Тестове завдання на вакансію Junior AI Web Developer
План сайту
Сайт послуг з калькулятором вартості, адмінкою і заявками в Telegram. Зроблено з Claude Desktop; тексти, рішення і журнал роботи з AI лежать у репозиторії.
Мета
Приводити заявки на збірку і легкий ремонт меблів напряму майстрові, без посередників і дзвінків «а скільки коштує». Клієнт бачить ціни одразу, рахує орієнтовну вартість у калькуляторі й залишає заявку, яка за секунду приходить майстрові в Telegram.
Аудиторія
- Люди, які купили меблі в інтернеті чи в магазині без збірки (Rozetka, Epicentr, IKEA, Jysk).
- Орендарі та ті, хто переїжджає: розібрати, перевезти, зібрати.
- Власники старих меблів: розхитані стільці, двері шафи, що не зачиняються, зламані напрямні.
- Географія: Хмельницький та район. Більшість заходить з телефона, тому сайт «спочатку для телефона»: липка кнопка «Подзвонити», великі кнопки, форма на три поля.
Сторінки і структура
| Адреса | Що там | Для кого |
|---|---|---|
| / | Односторінковий лендінг (структура нижче) | клієнти |
| /plan | Ця сторінка: план сайту | рекрутер |
| /admin | Адмінка: прайс, фото, зміна пароля (логін + пароль) | майстер |
| /api/content | Прайс і фото для сторінки (JSON) | сайт |
| /api/lead | Приймає заявку з форми і надсилає в Telegram | сайт |
Головна сторінка зверху вниз (структура «Ціни-перший»):
- Шапка (липка): назва, меню розділів на комп'ютері, телефон та ім'я майстра.
- Перший екран: слоган, заголовок, кнопки «Подзвонити» і «Порахувати вартість».
- Ціни і калькулятор: усі групи прайсу розгорнуті картками. Біля кожної позиції кнопки «−/+»; липка панель показує «Обрано N позицій, від X грн» і кнопкою «Додати в заявку» вписує розрахунок у форму.
- Що робимо: 4 картки (збірка, легкий ремонт, кухні під ключ, розбирання і переїзд).
- Наші роботи: галерея фото з адмінки; порожні місця показуються заглушками.
- Залишити заявку: телефон, кнопка «Написати у Telegram», форма (ім'я*, телефон*, що зробити*, фото).
- Підвал: контакти, посилання на план і непомітна шестерня для входу в адмінку.
- На телефоні: закріплена панель «Подзвонити» + «Telegram».
Як це працює
Клієнт ──► сайт (Cloudflare Pages, папка site/)
│ прайс і фото ◄── /api/content ◄── сховище KV
│ калькулятор рахує з того ж прайсу
│ форма заявки ──► /api/lead ──► Telegram-бот ──► телефон майстра
Майстер ──► /admin (логін + пароль) ──► змінює прайс і фото ──► KV
Технічні рішення і чому
| Рішення | Чому |
|---|---|
| Чистий HTML/CSS/JS, без фреймворків і збирача | Сторінка одна, важить ~30 КБ, відкривається миттєво з телефона; правити може будь-хто. |
| Cloudflare Pages + Pages Functions + KV | 0 грн/рік, SSL і CDN у комплекті, серверна частина в тому ж проєкті, платіжна картка не потрібна. |
| Заявки в Telegram замість CRM | Майстер і так у Telegram; жодних акаунтів і пошти; заявка приходить за секунду. |
| Калькулятор рахує з прайсу адмінки | Одне джерело правди: змінив ціну в адмінці — змінився і калькулятор. |
| Власна адмінка з логіном і паролем | Для людини без технічних навичок: прайс і фото правляться з телефона. |
| Безпека адмінки | Хеш пароля PBKDF2, сесія в cookie HttpOnly, блокування після 5 невдалих входів, авто-вихід через 5 хвилин. |
Як працював з AI (Claude Desktop)
- Правила в CLAUDE.md: мова, заборона реальних даних клієнта, секрети лише в Cloudflare, кожне рішення з датою в журналі рішень.
- Порядок: мета → варіанти (три кольорові гами, три структури сторінки, зверстані й порівняні поруч) → вибір → код → перевірка в браузері на телефоні і комп'ютері → документація.
- Документація замість історії чату: README, TODO, папка docs. Нова сесія Claude починає з них і продовжує роботу без втрат.
- Перевірка, а не довіра: кожен крок адмінки і форми перевірено запитами до локального сервера (401/400/429, завантаження фото, зміна пароля).
- Безпека на кожному кроці: токени й паролі вводить людина в терміналі, AI їх не бачить і в файли не кладе.
Що далі
- Блок «Відгуки» та його редагування в адмінці.
- Редагування текстів і контактів через адмінку.
- Telegram-бот з діалогом (тип меблів → фото → адреса → час).
- Cloudflare Turnstile проти спаму, якщо з'явиться.