generated from wiz4apps/templates.OnlineShop
docs: complete source audit, add catalog inventory and redesign plan
- ANALYSIS.md: append the 2026-10-04 findings (94 SKUs, hidden categories, broken link, PDP gaps, shipping contradiction, guest checkout) - CATALOG.md: full de-duplicated inventory (11 categories, 94 products with prices/badges), 3 extra PDP samples, checkout/payment field map, store constants - PLAN.md: locked decisions, route map, data model + ERD, key flows, seed plan, layer acceptance checks and open questions
This commit is contained in:
parent
2db94ac43b
commit
262ae126fb
179
docs/ANALYSIS.md
Normal file
179
docs/ANALYSIS.md
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
# Анализ сайта-источника la-rose.by
|
||||
|
||||
**Дата аудита:** 2026-10-01 · **Метод:** обход живого сайта (HTML + headless-сессия для каталога и корзины).
|
||||
**Статус документа:** факты о текущем сайте как есть. Плановые решения — в `docs/PLAN.md`.
|
||||
|
||||
## 0. Кратко
|
||||
|
||||
LaRose — минская доставка цветов (с 2018), ~94 уникальных товара, 11 категорий верхнего уровня,
|
||||
8 информационных страниц, одностраничное оформление заказа, самовывоз + курьер по Минску.
|
||||
Сайт работает на **Webasyst Shop-Script** (тема `free1`), интерфейс полностью русский, валюта — **BYN**.
|
||||
|
||||
Ключевой вывод для переделки: сайт **функционально полный, но структурно бедный** —
|
||||
на карточке товара нет структурированных полей (состав, размеры, количество стеблей, наличие),
|
||||
нет фасетных фильтров (только диапазон цены), нет блога/FAQ, аккаунт не выведен в шапку.
|
||||
Это и есть главный фронт работ по «крутому» сайту.
|
||||
|
||||
## 1. Карта страниц (sitemap)
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
HOME["/ — Главная"] --> CAT["Каталог — 11 категорий"]
|
||||
CAT --> C1["/category/bukety-tsvetov/ (~92)"]
|
||||
CAT --> C2["/category/sbornye-bukety/ (~36)"]
|
||||
CAT --> C3["/category/bukety-iz-alstromerii/ (~15)"]
|
||||
CAT --> C4["/category/bukety-iz-gvozdiki/ (~16)"]
|
||||
CAT --> C5["/category/bukety-iz-kustovoy-rozy/ (~20)"]
|
||||
CAT --> C6["/category/bukety-iz-khrizantemy/ (~37)"]
|
||||
CAT --> C7["/category/svadebnye-bukety-nevesty/ (3)"]
|
||||
CAT --> C8["/category/monobuket/ (~23)"]
|
||||
CAT --> C9["/category/kompozitsii/ (~7)"]
|
||||
CAT --> C10["/category/tsvety-v-yashchike/ (1)"]
|
||||
CAT --> C11["/category/tsvety-v-korzine/ (~6)"]
|
||||
C1 --> PDP["/product/<slug|id> — ~94"]
|
||||
C6 --> PDP
|
||||
C8 --> PDP
|
||||
CAT -. вне меню .-> H1["/category/bukety-iz-roz/ (22)"]
|
||||
CAT -. вне меню .-> H2["/category/bukety-iz-gortenziy/ (0)"]
|
||||
CAT -. вне меню .-> H3["/category/bukety-s-tyulpanami/ (0)"]
|
||||
HOME --> TOP["Сервисное меню"]
|
||||
TOP --> A1["/company/ — О компании"]
|
||||
TOP --> A2["/dostavka/ — Доставка по Минску"]
|
||||
TOP --> A3["/vozvrat/ — Возврат"]
|
||||
TOP --> A4["/contacts/ — Контакты"]
|
||||
A1 --> A1a["/company/b2b/ — Корпоративным клиентам"]
|
||||
A1 --> A1b["/company/politika-konfidentsialnosti/"]
|
||||
A2 --> A2a["/dostavka/oplata/ — Варианты оплаты"]
|
||||
A2 --> A2b["/dostavka/zakaz/ — Как заказать"]
|
||||
A4 --> A4a["/contacts/vakansii/ — Вакансии"]
|
||||
HOME --> SYS["Транзакционные"]
|
||||
SYS --> S1["/order/ — корзина + оформление (1 страница)"]
|
||||
SYS --> S2["/cart/ — корзина (alt)"]
|
||||
SYS --> S3["/login/ · /signup/ · /my/"]
|
||||
SYS --> S4["/search/?query=…"]
|
||||
```
|
||||
|
||||
## 2. Каталог
|
||||
|
||||
- **Дерево:** 2 уровня — 11 категорий верхнего уровня → товары. Подкатегорий **нет**, фильтры не сгруппированы.
|
||||
- **Товар может лежать в нескольких категориях** (кросс-листинг), поэтому сумма по категориям > числа уникальных товаров (~94).
|
||||
- **Фильтры:** только диапазон цены (`price_min` / `price_max`, наблюдаемый диапазон 43–765 BYN) + «Показать» / «Очистить». Фасетов по поводу, цвету, цветку, размеру — нет.
|
||||
- **Сортировки (`?sort=`):** Название, Цена, Хиты продаж, Оценка покупателей, Дата добавления, В наличии.
|
||||
- **Пагинация:** номерная, ~28 товаров на страницу + селектор «Показывать по».
|
||||
- **Блоки листинга:** «Хиты продаж», бейджи `ХИТ! / NEW! / СКИДКА!`, быстрая кнопка «В корзину», SEO-текст под сеткой.
|
||||
- **Скрытые категории:** `bukety-iz-roz` (22 товара, есть только в SEO-тексте), `bukety-iz-gortenziy` и `bukety-s-tyulpanami` — отдают 200 и 0 товаров.
|
||||
|
||||
## 3. Карточка товара — реальный набор полей
|
||||
|
||||
Образец: `/product/buket-iz-15-roz-fridom/`
|
||||
|
||||
| # | Поле (как на сайте) | Примечание |
|
||||
|---|---|---|
|
||||
| 1 | Название (`<h1>`) | «Букет из 15 роз» |
|
||||
| 2 | Бейдж | Хит! / New! / Скидка! |
|
||||
| 3 | Текущая цена | `142 BYN` |
|
||||
| 4 | Старая (зачёркнутая) цена | только при скидке |
|
||||
| 5 | Валюта | BYN (`og:product:price:currency`) |
|
||||
| 6 | Степпер количества | `мин.` + `шт.`, `name=quantity` |
|
||||
| 7 | Кнопка «Купить» | добавление в корзину |
|
||||
| 8 | Галерея | 4 превью + основное изображение |
|
||||
| 9 | Хлебные крошки | Главная › Букеты цветов › Монобукеты |
|
||||
| 10 | «Поделиться» | ya-share2 |
|
||||
| 11 | Таб «Обзор» | единственный таб |
|
||||
| 12 | Описание | свободный текст (SEO-заготовка) |
|
||||
| 13 | «Просмотренные товары» | блок истории просмотра |
|
||||
|
||||
**Чего нет как структурированных данных (главный разрыв):** размеры/варианты, состав букета,
|
||||
количество стеблей, высота/габариты, уход, срок доставки, наличие/остаток, допы, отзывы и рейтинг.
|
||||
Состав и количество цветов спрятаны внутри названия («Белая ромашка, примерно 51 цветочек»).
|
||||
|
||||
## 4. Корзина и оформление
|
||||
|
||||
Оформление **одностраничное** — `/order/`, секции: `Корзина → Оформление → Покупатель → Доставка → Оплата`.
|
||||
|
||||
1. **Корзина:** строки, степпер `мин./шт.`, цена за единицу и за строку, «Удалить» / «Удалить все товары», промокод (`coupon_code` + «Активировать»), «Итого».
|
||||
2. **Покупатель:** `firstname`, `phone`, `email`, **`nomer_skidochnoy_karty`** (номер скидочной карты — лояльность), `data_i_vremya_dostavki` (дата и время доставки).
|
||||
3. **Доставка:** страна/регион/город предзаполнены и заблокированы (Беларусь / Минск). Типы: «Доставка курьером» (Бесплатно · Сегодня) и «Самовывоз из магазинов» (Бесплатно · Сегодня). Карточки вариантов доставки с выбором дня/интервала. Адрес: имя получателя, телефон получателя, улица, **`tekst-na-otkryt`** (текст для открытки), комментарий к заказу. Итоги: товары / доставка / итого.
|
||||
4. **Оплата:** «Наличные при получении» и «Оплата картой онлайн (РБ, РФ, Мир)» — Visa, MasterCard, МИР, Google Pay, Yandex Pay, Apple Pay, ЕРИП.
|
||||
|
||||
**Пробелы:** нет явной опции «анонимный подарок» (только текст открытки), логика бесплатной доставки в копирайте противоречива (50 / 80 / 100 BYN в разных местах).
|
||||
|
||||
## 5. Информационные страницы
|
||||
|
||||
| URL | О чём |
|
||||
|---|---|
|
||||
| `/company/` | О компании: с 2018, 5 точек самовывоза, импорт из 7 стран, бонусная система, B2B, заказ 24/7 |
|
||||
| `/company/b2b/` | Корпоративным: подарки сотрудникам/партнёрам, брендирование, оформление офиса, доставка за 1 час, безнал, счёт, скидка 10% |
|
||||
| `/dostavka/` | Доставка по Минску: бесплатно от 100 BYN, иначе 15 BYN; за МКАД +0.50 BYN/км; срок до 2 часов; самовывоз Притыцкого 10, 09:00–21:00 |
|
||||
| `/dostavka/oplata/` | Оплата: курьеру/в магазине, карта онлайн (WebPay, ЕРИП, Альфа-Банк), VISA/MasterCard/BELCART, Apple/Samsung Pay, безнал для юрлиц |
|
||||
| `/dostavka/zakaz/` | Как заказать: телефон/почта/корзина, круглосуточный приём, «Подтвердить заказ» → «Оплатить заказ» |
|
||||
| `/vozvrat/` | Возврат: живые цветы возврату не подлежат; претензии только в момент передачи; возврат на исходный способ оплаты, карта до 30 дней |
|
||||
| `/contacts/` | ООО «Диапазон Плюс», УНП 190438401, Притыцкого 10 пом. 1Н; 2 телефона; 09:00–21:00, праздники до 23:00 |
|
||||
| `/contacts/vakansii/` | Вакансии: менеджер по работе с клиентами, флорист; 2/2, метро Пушкинская |
|
||||
| `/company/politika-konfidentsialnosti/` | Политика обработки персональных данных |
|
||||
|
||||
FAQ, блог, новостей и отдельной страницы «доставка за МКАД» — нет.
|
||||
|
||||
## 6. Коммерческие факты (для констант сайта)
|
||||
|
||||
- **Телефоны:** +375 (29) 657-30-00, +375 (33) 657-30-00 · **E-mail:** info@La-rose.by
|
||||
- **Часы:** ежедневно 09:00–21:00, праздники до 23:00; приём заказов онлайн — 24/7
|
||||
- **Адрес:** г. Минск, ул. Притыцкого, 10, пом. 1Н (самовывоз, метро Пушкинская)
|
||||
- **География:** Минск и Минская область; за МКАД +0.50 BYN/км
|
||||
- **Срок доставки:** до 2 часов (B2B — приоритет 1 час)
|
||||
- **Валюта:** BYN · **Доставка:** бесплатно от 100 BYN, иначе 15 BYN
|
||||
- **Оплата:** наличные курьеру/в магазине, карта онлайн (Visa, MasterCard, БЕЛКАРТ, МИР; Google/Yandex/Apple/Samsung Pay; ЕРИП), безнал для юрлиц
|
||||
- **Гарантии:** импорт 2 раза в неделю, свой курьер, претензии по качеству — при передаче
|
||||
|
||||
## 7. Дополнительные возможности и интеграции
|
||||
|
||||
- Поиск по каталогу (`/search/?query=`), аккаунт Webasyst (`/login/`, `/signup/`, `/my/`) — **не выведен в шапку/футер**.
|
||||
- Избранное и сравнение: компоненты темы есть, отдельной страницы в sitemap нет.
|
||||
- Лояльность: скидочная карта, промокоды, «Общая скидка», бонусная система, 10% корпоративным.
|
||||
- Отзывы/рейтинг: сортировка «Оценка покупателей» есть, сами отзывы на PDP не рендерятся.
|
||||
- Каналы: WhatsApp `wa.me/375296573000`, Telegram-бот `t.me/bot_a_nik_vsop`, VK `vk.com/La_Rose_by`, Instagram `instagram.com/larose_by`, онлайн-чат **Bitrix24**.
|
||||
- Аналитика: Yandex Metrika (72956191, webvisor + ecommerce), GA4/GTM (G-GNXX0B3PD5, G-4SN20SG8SP, AW-837118909, GTM-W8NK6WWQ), Meta Pixel 128304465805329, Mail.ru top.
|
||||
|
||||
## 8. Технические факты
|
||||
|
||||
- Платформа: **Webasyst Shop-Script** (`/wa-data/public/shop/…`, `/webasyst/` отвечает 200, `sitemap-shop.xml` сгенерирован Webasyst).
|
||||
- Тема: `free1`. `<meta name="generator">` отсутствует.
|
||||
- `robots.txt`: 38 запретов, включая `/my/`, `/checkout/`, `/search/`, `/order/`, `/login/`, `/cart/`, все query-string (`/*?*`), `/webasyst/`.
|
||||
- `sitemap-shop.xml` не перечисляет все товары: страницы `/product/<id>/` всплывают только из листингов.
|
||||
|
||||
## 9. Что это значит для переделки
|
||||
|
||||
| Разрыв | Решение (в `docs/PLAN.md`) |
|
||||
|---|---|
|
||||
| Поля товара не структурированы | Ввести контракт PDP: состав, количество стеблей, высота, размер/вариант, уход, наличие, срок доставки |
|
||||
| Нет фасетных фильтров | Фасеты: повод, цвет, тип цветка, размер, цена + сортировки как сейчас |
|
||||
| Аккаунт спрятан | Вывести вход/кабинет в шапку, добавить историю заказов и повтор заказа |
|
||||
| Противоречивые условия доставки | Один источник констант: порог бесплатной доставки, за МКАД, срок, часы |
|
||||
| Нет FAQ/блога | Добавить FAQ на страницы доставки/оплаты (низкая стоимость, высокий SEO-эффект) |
|
||||
| SEO-слаги и числовые ID | Сохранить существующие слаги 1:1, для `/product/<id>/` подготовить 301-карту |
|
||||
| Аналитика и чат | Решить судьбу Bitrix24, сохранить паритет по Метрике/GA4/Pixel |
|
||||
|
||||
## 10. Дополнение от 2026-10-04 — полный инвентарь каталога и чек-аут
|
||||
|
||||
Аудит дособран: полный дедуплицированный инвентарь (94 товара, 11 категорий, цены, старые цены,
|
||||
бейджи, кросс-листинг), 3 дополнительных образца PDP, точные поля и способы оформления/оплаты,
|
||||
константы. Полные таблицы и оговорки — в приложении [`docs/CATALOG.md`](CATALOG.md).
|
||||
|
||||
Новые/уточнённые факты:
|
||||
|
||||
- **Каталог:** 256 слотов в листингах → **94 уникальных товара**; размер страницы фиксирован (28),
|
||||
селектор «Показывать по» не активен; бейджи ХИТ! × 24, NEW! × 13, СКИДКА! × 5.
|
||||
- **Скрытые категории:** `/category/bukety-iz-roz/` (22 товара, только прямой URL и крошки);
|
||||
«Гортензии» и «Тюльпаны» — HTTP 200, но 0 товаров. Дополнительно видны `/category/rozy-po-tsvetu/`
|
||||
и `/category/krasnye-rozy/` (крошки PDP).
|
||||
- **Битая ссылка:** карточка `/product/1997/` в листинге ведёт на **HTTP 404**.
|
||||
- **PDP:** структурированных полей нет ни у одного образца; у части товаров есть варианты
|
||||
(«15/19/25 роз» → 198/240/325 BYN) с одной характеристикой «Кому дарим цветы».
|
||||
- **Бесплатная доставка:** копирайт противоречив (50 / 80 / 100 BYN), а фактически в корзине
|
||||
настроен **один бесплатный вариант** доставки по Минску без порога; тариф 15 BYN и «+0.50 BYN/км»
|
||||
в корзине недостижимы (город заблокирован как Минск).
|
||||
- **Оформление:** гостевой чекаут возможен; промокод `coupon_code` с ошибкой «Купон недействителен»;
|
||||
поля получателя включают `tekst-na-otkryt` (текст открытки) и `nomer_skidochnoy_karty`.
|
||||
- **Оплата:** «Наличные» и «Оплата картой онлайн» (плагин `begateway`; Visa/MasterCard/МИР,
|
||||
Google/Yandex/Apple Pay, ЕРИП).
|
||||
- **Не проверено:** отправка заказа и редирект оплаты, валидный промокод, тариф за МКАД.
|
||||
265
docs/CATALOG.md
Normal file
265
docs/CATALOG.md
Normal file
|
|
@ -0,0 +1,265 @@
|
|||
# Каталог la-rose.by — полный инвентарь (приложение к аудиту)
|
||||
|
||||
**Источник:** https://la-rose.by/ · **Дата сбора:** 2026-10-04 · **Метод:** обход живого сайта
|
||||
(HTML + headless-браузер, карточки `div.Product-grid`, пагинация `?page=`).
|
||||
**Статус документа:** факты «как есть». Сводный анализ — [`docs/ANALYSIS.md`](ANALYSIS.md),
|
||||
плановые решения — [`docs/PLAN.md`](PLAN.md).
|
||||
|
||||
> Примечание: у части карточек название в листинге может быть сокращено или отличаться от `<h1>`
|
||||
> на странице товара — сверить при наполнении. Данные волатильны (цены/акции на дату сбора).
|
||||
|
||||
## 1. Категории — коды и объёмы
|
||||
|
||||
| Код | Категория | URL | Страниц | Товаров в листинге | Уникальных |
|
||||
|---|---|---|---|---|---|
|
||||
| BC | Букеты цветов | `/category/bukety-tsvetov/` | 4 (28+28+28+8) | 92 | 92 |
|
||||
| SB | Букеты сборные | `/category/sbornye-bukety/` | 2 (28+8) | 36 | 36 |
|
||||
| AL | Букеты с альстромерией | `/category/bukety-iz-alstromerii/` | 1 | 15 | 15 |
|
||||
| GV | Букеты с гвоздикой | `/category/bukety-iz-gvozdiki/` | 1 | 16 | 16 |
|
||||
| KR | Букеты с кустовой розой | `/category/bukety-iz-kustovoy-rozy/` | 1 | 20 | 20 |
|
||||
| HZ | Букеты с хризантемами | `/category/bukety-iz-khrizantemy/` | 2 (28+9) | 37 | 37 |
|
||||
| SV | Свадебные букеты невесты | `/category/svadebnye-bukety-nevesty/` | 1 | 3 | 3 |
|
||||
| MB | Монобукеты | `/category/monobuket/` | 1 | 23 | 23 |
|
||||
| KZ | Цветочные композиции | `/category/kompozitsii/` | 1 | 7 | 7 |
|
||||
| YS | Цветы в ящике | `/category/tsvety-v-yashchike/` | 1 | 1 | 1 |
|
||||
| YK | Цветы в корзине | `/category/tsvety-v-korzine/` | 1 | 6 | 6 |
|
||||
| | **Итого слотов / уникальных** | | | **256** | **94** |
|
||||
|
||||
- Размер страницы фиксирован — 28; селектор «Показывать по» есть в разметке
|
||||
(`select.cat-onpage_select`), но **не активен**.
|
||||
- **Кросс-листинг массовый** (256 слотов → 94 товара): товар попадает до 6 категорий
|
||||
(например, «Грезы»).
|
||||
- Бейджи: `ХИТ!` × 24, `NEW!` × 13, `СКИДКА!` × 5.
|
||||
|
||||
## 2. Скрытые и пустые категории
|
||||
|
||||
| Категория | HTTP | Товаров | Доступность |
|
||||
|---|---|---|---|
|
||||
| `/category/bukety-iz-roz/` (Розы) | 200 | 22 (все — дубли видимых категорий) | по прямому URL и из хлебных крошек розовых PDP; **нет в меню** |
|
||||
| `/category/bukety-iz-gortenziy/` (Гортензии) | 200 | 0 | только по SEO-ссылке в тексте; пустая выдача |
|
||||
| `/category/bukety-s-tyulpanami/` (Тюльпаны) | 200 | 0 | только по SEO-ссылке в тексте; пустая выдача |
|
||||
|
||||
Дополнительная скрытая таксономия (видна в хлебных крошках PDP, нет в меню):
|
||||
`/category/rozy-po-tsvetu/` (Розы по цвету), `/category/krasnye-rozy/` (Красные розы).
|
||||
|
||||
## 3. Полная таблица товаров (94, дедуплицировано)
|
||||
|
||||
| # | Название | Slug / URL | Цена BYN | Старая BYN | Бейдж | Категории |
|
||||
|---|---|---|---|---|---|---|
|
||||
| 1 | «Летний» | `/product/buket-nostalgiya/` | 71 | 161 | ХИТ! | BC, HZ, MB |
|
||||
| 2 | Корзина с кустовой розой «Золушка» | `/product/korzina-tsvetov-zolushka/` | 257 | 351 | ХИТ! | BC, KR, YK |
|
||||
| 3 | Корзина с розой и гвоздикой «Диадема» | `/product/korzina-tsvetov-diadema/` | 174 | 197 | NEW! | BC, SB, KZ, YK |
|
||||
| 4 | Композиция «Совершенство» | `/product/sovershenstvo/` | 125 | 140 | — | BC, SB, HZ, KZ |
|
||||
| 5 | Корзина цветов «Розовая пантера» | `/product/275/` | 135 | 150 | — | BC, KR, YK |
|
||||
| 6 | Сухоцветы гипсофила и лаванда | `/product/buket-iz-gipsofily-i-lavandy/` | 105 | 127 | — | BC, SV |
|
||||
| 7 | Букет из пёстрой ромашки | `/product/buket-iz-pyostroy-romashki/` | 85 | 136 | — | BC, HZ |
|
||||
| 8 | Корзина «Нежность» | `/product/korzina-nezhnost/` | 320 | 370 | — | BC, GV, HZ, YK |
|
||||
| 9 | Свадебный букет из красной розы на роспись | `/product/svadebnyy-buket-na-rospis/` | 215 | — | — | BC, SV |
|
||||
| 10 | Свадебный букет на роспись «Люблю» | `/product/svadebnyy-buket-na-rospis-lyublyu/` | 210 | — | — | BC, SV |
|
||||
| 11 | Букет из 15 гвоздик и эвкалипта | `/product/buket-iz-15-gvozdik-i-evkalipta/` | 135 | 150 | ХИТ! | BC, GV, MB |
|
||||
| 12 | Композиция из чёрных роз (Эквадор) | `/product/buket-iz-chernykh-roz-ekvador/` | 765 | — | NEW! | BC |
|
||||
| 13 | Букет из синих роз | `/product/nezabyvaemyy-buket-iz-sinikh-roz/` | 150 | 165 | NEW! | BC, MB |
|
||||
| 14 | Нежный букет с розой и альстромерией | `/product/nezhnyy-buket-iz-rozy-s-alstromeriey/` | 183 | 197 | — | BC, SB, AL |
|
||||
| 15 | Букет из красных роз с эвкалиптом | `/product/buket-iz-krasnykh-roz-s-evkaliptom/` | 198 | 295 | ХИТ! | BC, MB |
|
||||
| 16 | Букет красных роз Кения | `/product/1553/` | 165 | 187 | — | BC |
|
||||
| 17 | Букет из французской розы | `/product/1565/` | 150 | 250 | СКИДКА! | BC, MB |
|
||||
| 18 | Безмятежное счастье | `/product/buket-bezmyatezhnoe-schaste/` | 125 | 130 | ХИТ! | BC, SB, AL, GV |
|
||||
| 19 | Нежный букет с хризантемой и диантусом | `/product/nezhnyy-buket-s-khrizantemoy-i-diantusom/` | 162 | 177 | ХИТ! | BC, SB, AL, GV, HZ |
|
||||
| 20 | Букет 15 белых роз | `/product/buket-15-belykh-roz-1/` | 196 | — | ХИТ! | BC, MB |
|
||||
| 21 | «Элегантность в простоте» | `/product/buket-elegantnost-v-prostote/` | 104 | 189 | ХИТ! | BC, SB, KR, HZ |
|
||||
| 22 | Букет «Нежность» | `/product/buket-nezhnost-v-lepestkakh/` | 157 | 164 | NEW! | BC, SB, GV, KR, HZ |
|
||||
| 23 | Букет «Сахарная вата» | `/product/buket-sakharnaya-vata/` | 73 | 99 | — | BC, GV |
|
||||
| 24 | Сборный букет «Вспышка» | `/product/sbornyy-buket-vspyshka/` | 183 | 212 | — | BC, SB, GV, KR |
|
||||
| 25 | Букет «Небесная симфония» | `/product/1814/` | 117 | 138 | — | BC, HZ, MB |
|
||||
| 26 | Букет «Зефирная нежность» | `/product/buket-zefirnaya-nezhnost/` | 98 | 156 | — | BC, KR, MB |
|
||||
| 27 | Композиция в корзине | `/product/kompozitsiya-v-korzine/` | 154 | 186 | — | BC, KR, MB, KZ, YK |
|
||||
| 28 | Разрешите подарить вам радугу | `/product/razreshite-podarit-vam-radugu/` | 154 | 237 | ХИТ! | BC, HZ, MB |
|
||||
| 29 | Романтика в воздухе | `/product/romantika-v-vozdukhe/` | 190 | 203 | — | BC, SB, KR, HZ |
|
||||
| 30 | Весеннее настроение | `/product/vesennee-nastroenie/` | 148 | 187 | — | BC, SB, GV, KR, HZ |
|
||||
| 31 | Роза кустовая Рефлекс | `/product/roza-kustovaya-pionovidnaya/` | 292 | 315 | — | BC, MB |
|
||||
| 32 | Летний ветер | `/product/letniy-veter/` | 65 | 115 | — | BC, HZ, MB |
|
||||
| 33 | Букет из 15 роз | `/product/buket-iz-15-roz-fridom/` | 142 | 175 | — | BC, MB |
|
||||
| 34 | Обнимая ароматом | `/product/obnimaya-aromatom/` | 163 | 178 | — | BC, SB |
|
||||
| 35 | Грезы | `/product/grezy/` | 141 | 168 | — | BC, SB, AL, GV, KR, HZ |
|
||||
| 36 | Для Самой Любимой | `/product/dlya-samoy-lyubimoy/` | 207 | 298 | СКИДКА! | BC, SB, KR, HZ |
|
||||
| 37 | Хризантема с ромашкой | `/product/khrizantema-s-romashkoy/` | 115 | 145 | NEW! | BC, HZ |
|
||||
| 38 | Для тебя | `/product/dlya-tebya/` | 125 | 137 | — | BC, MB |
|
||||
| 39 | Букет из нежной хризантемы и гипсофилы | `/product/buket-iz-nezhnoy-khrizantemy-i-gipsofily/` | 117 | 230 | ХИТ! | BC, SB, HZ, MB |
|
||||
| 40 | Очарование | `/product/ocharovanie-1/` | 187 | 193 | — | BC, SB, AL, GV |
|
||||
| 41 | Композиция в рамке | `/product/kompozitsiya-v-ramke/` | 91 | 104 | — | BC, KZ |
|
||||
| 42 | Солнечный ангел | `/product/solnechnyy-angel/` | 153 | 193 | — | BC, SB, AL, GV |
|
||||
| 43 | Цветы в шляпной коробке | `/product/tsvety-v-shlyapnoy-korobke-2/` | 117 | 125 | — | KZ |
|
||||
| 44 | Тёплые объятия | `/product/teplye/` | 372 | 374 | — | BC, SB, AL |
|
||||
| 45 | Букет «Для Самой Любимой» из хризантем | `/product/mamina-nezhnot/` | 143 | 210 | ХИТ! | BC, SB, HZ |
|
||||
| 46 | Розовая хризантема Ромашка | `/product/rozovaya-khrizantema-romashka/` | 65 | 115 | ХИТ! | BC, HZ, MB |
|
||||
| 47 | Белая ромашка, примерно 51 цветочек | `/product/belaya-romashka-primerno-51-tsvetochek/` | 55 | 137 | — | BC, HZ, MB |
|
||||
| 48 | Голубая ромашка с гипсофилой | `/product/golubaya-romashka-s-gipsofiloy/` | 98 | 167 | ХИТ! | BC, HZ, MB |
|
||||
| 49 | Кустовая роза Рефлекс с альстромерией | `/product/kustovaya-roza-refleks-s-alstromeriey/` | 134 | 187 | — | BC, AL, KR |
|
||||
| 50 | Нежный поцелуй | `/product/nezhnyy-potseluy-1/` | 98 | 167 | — | BC, AL |
|
||||
| 51 | Вдохновение природы | `/product/vdokhnovenie-prirody/` | 169 | 245 | — | BC, HZ, MB |
|
||||
| 52 | Букет из кустовой розы и кустовой хризантемы | `/product/1982/` | 153 | 197 | — | BC, SB, HZ |
|
||||
| 53 | Нежно-розовый букет из дуэта хризантем | `/product/nezhno-rozovyy-buket-iz-dueta-khrizantem/` | 155 | 245 | — | BC, SB, HZ |
|
||||
| 54 | Зефирное облако нежных хризантем | `/product/zefirnoe-oblako-nezhnykh-khrizantem/` | 169 | 244 | NEW! | BC, HZ |
|
||||
| 55 | Нежный букет для самой любимой | `/product/nezhnyy-buket-dlya-samoy-lyubimoy/` | 179 | 218 | NEW! | BC, SB, AL, KR, HZ |
|
||||
| 56 | Букет в сиренево-розовых тонах | `/product/buket-v-sirenevo-rozovykh-tonakh-iz-khrizantemy-rozy-i-diantusa/` | 115 | 167 | — | BC |
|
||||
| 57 | Нежный букет из кустовой и французской розы | `/product/1993/` | 113 | 137 | NEW! | BC, KR |
|
||||
| 58 | ~51 небесно-голубая ромашка | `/product/51-nebesno-golubaya-romashka/` | 59 | 115 | — | BC, HZ |
|
||||
| 59 | Букет «Небесная симфония» из пушистой хризантемы | `/product/1997/` ⚠️ **404** | 82 | 115 | — | BC, HZ, MB |
|
||||
| 60 | Ящик деревянный с хризантемой «Радужный» | `/product/yashchik-derevyannyy-s-khrizantemoy-raduzhnyy/` | 124 | 139 | — | BC, HZ, KZ, YS |
|
||||
| 61 | Композиция в ящике «Мечтаю о тебе» | `/product/kompozitsiya-v-yashchike-mechtayu-o-tebe/` | 89 | 127 | ХИТ! | BC |
|
||||
| 62 | Нежно-бирюзовая ромашка | `/product/nezhno-biryuzovaya-romashka/` | 65 | 115 | ХИТ! | BC, HZ, MB |
|
||||
| 63 | Букет из диантусов | `/product/2003/` | 117 | 157 | — | BC, SB, GV |
|
||||
| 64 | Букет «Приятные моменты» | `/product/buket-priyatnye-momenty-iz-kustovoy-rozy-khrizantemy-i-alstromerii/` | 135 | 149 | — | BC, SB, AL, KR, HZ |
|
||||
| 65 | Букет из хризантемы и кустовой розы Рефлекс | `/product/2008/` | 107 | 193 | СКИДКА! | BC, SB, KR, HZ |
|
||||
| 66 | Букет из кустовой и французской розы с альстромерией | `/product/2009/` | 117 | 183 | СКИДКА! | BC, SB, AL, KR |
|
||||
| 67 | Букет из голубой хризантемы и розы «Рефлекс» | `/product/buket-iz-goluboy-khrizantemy-i-rozy-refleks/` | 98 | — | — | BC |
|
||||
| 68 | Нежный букет из французской розы и эвкалипта | `/product/nezhnyy-buket-iz-frantsuzskoy-rozy-i-evkalipta/` | 63 | 98 | ХИТ! | BC, SB, MB |
|
||||
| 69 | Букет «Алые паруса» из 11 красных роз | `/product/buket-alye-parusa-iz-11-krasnykh-roz-s-limoniumom-i-evkaliptom/` | 146 | 193 | ХИТ! | BC, SB, MB |
|
||||
| 70 | Букет из альстромерии, роз, хризантемы и эустомы | `/product/2028/` | 167 | 189 | NEW! | BC, SB |
|
||||
| 71 | 3 веточки розовой хризантемы | `/product/2033/` | 43 | 65 | ХИТ! | BC, HZ |
|
||||
| 72 | Букетик сухоцвет лаванды | `/product/buketik-sukhotsvet-lavandy/` | 43 | 57 | — | BC |
|
||||
| 73 | Воздушный объёмный букет с розами | `/product/vozdushnyy-obyomnyy-buket-s-frantsuzskoy-i-kustovoy-rozami/` | 179 | — | — | BC, SB, KR, HZ |
|
||||
| 74 | Сборный ароматный букет с лилией и розой | `/product/sbornyy-aromatnyy-buket-s-liliey-i-rozoy/` | 194 | — | — | BC, SB, KR |
|
||||
| 75 | Букет из французских и кустовых роз | `/product/2048/` | 119 | 137 | — | BC, SB |
|
||||
| 76 | Букет с зеркалом «Ты — Моё Всё» | `/product/2050/` | 154 | 186 | NEW! | BC, SB, GV, KZ |
|
||||
| 77 | Букет из диантусов с лизиантусами | `/product/2051/` | 183 | 275 | NEW! | BC, SB, GV |
|
||||
| 78 | Букет из альстромерии и диантусов | `/product/2052/` | 117 | 143 | NEW! | BC, SB, AL, GV |
|
||||
| 79 | Букет из альстромерии и диантусов с лагурусом | `/product/2053/` | 129 | 161 | NEW! | BC, SB, AL, GV |
|
||||
| 80 | Букет «Для моей Принцессы» | `/product/2054/` | 157 | 198 | — | BC, SB, HZ |
|
||||
| 81 | Букет из французской и кустовой розы, эустомы | `/product/buket-iz-frantsuzskoy-rozy-kustovoy-rozy-eustomy/` | 125 | 153 | — | BC |
|
||||
| 82 | Букет из розовых хризантем микс | `/product/buket-iz-rozovykh-khrizantem-miks/` | 51 | 63 | — | BC |
|
||||
| 83 | Букет из кустовой розы, альстромерии и гипсофилы | `/product/buket-iz-kustovoy-rozy-alstromerii-i-gipsofila/` | 126 | 158 | — | BC |
|
||||
| 84 | Букет из малиновой розы | `/product/buket-iz-malinovoy-rozy/` | 107 | 137 | — | BC |
|
||||
| 85 | Корзина «Мамино Сердце» | `/product/2068/` | 537 | — | — | YK |
|
||||
| 86 | Сиренево-белый букет из хризантемы Алтай | `/product/2069/` | 83 | 105 | — | BC, HZ |
|
||||
| 87 | Сборный микс альстромерий | `/product/2070/` | 81 | 127 | — | BC, AL |
|
||||
| 88 | Букет из хризантемы Алтай и лимониума | `/product/2071/` | 98 | 168 | — | BC, HZ |
|
||||
| 89 | Букет нежный из кустовой хризантемы и лимониума | `/product/2072/` | 119 | 184 | — | BC, HZ |
|
||||
| 90 | Букет из красной французской розы с эвкалиптом | `/product/2073/` | 93 | 173 | — | BC |
|
||||
| 91 | Букет из красных роз и эустомы | `/product/2074/` | 157 | 210 | — | BC |
|
||||
| 92 | Букет из французской розы, эустомы и кустовой розы | `/product/2075/` | 123 | 169 | — | BC |
|
||||
| 93 | Нежный светлый букет с розой и хризантемой | `/product/2076/` | 144 | 193 | — | BC, KR |
|
||||
| 94 | Букет из французской розовой розы и эвкалипта | `/product/2077/` | 98 | 132 | — | BC |
|
||||
|
||||
⚠️ Строка 59 (`/product/1997/`) — **битая ссылка в листинге**: href ведёт на HTTP 404
|
||||
(у темы нет слага, fallback на числовой ID не резолвится). Остальные числовые ID — HTTP 200.
|
||||
|
||||
## 4. Карточка товара (PDP) — реальный набор полей, 3 дополнительных образца
|
||||
|
||||
Базовый образец (`/product/buket-iz-15-roz-fridom/`, id 1860, «Букет из 15 роз», 142/175 BYN, без бейджа, BC+MB).
|
||||
|
||||
| Поле | A. Роза `/product/buket-iz-krasnykh-roz-s-evkaliptom/` | B. Хризантема `/product/buket-iz-nezhnoy-khrizantemy-i-gipsofily/` | C. Композиция/коробка `/product/tsvety-v-shlyapnoy-korobke-2/` |
|
||||
|---|---|---|---|
|
||||
| h1 | Букет из красных роз с эвкалиптом | Букет из нежной хризантемы и гипсофилы | Цветы в шляпной коробке |
|
||||
| Бейдж | ХИТ! | ХИТ! | нет |
|
||||
| Цена | 198 BYN | 117 BYN | 117 BYN |
|
||||
| Старая цена | 295 BYN | 230 BYN | 125 BYN |
|
||||
| Валюта | BYN | BYN | BYN |
|
||||
| Степпер `input[name=quantity]` | value 1; **нет `min`/`max`/`step`** | value 1; нет min/max/step | value 1; нет min/max/step |
|
||||
| Изображений в галерее | 1 | 4 | 3 |
|
||||
| Хлебные крошки | Букеты цветов › Розы › Розы по цвету › Красные розы | Букеты цветов | Цветочные композиции |
|
||||
| Описание | свободный SEO-блок, 614 симв., без короткого текста | короткий текст 191 симв. + «Подробное описание» + SEO 613 симв. | свободный SEO-блок, 582 симв. |
|
||||
| Структурированные поля | нет | нет | нет |
|
||||
| Табы | «Обзор» / «Характеристики»: **одна** характеристика «Кому дарим цветы» + варианты **15/19/25 роз → 198/240/325 BYN** | только «Кому дарим цветы»; вариантов нет | нет |
|
||||
| Состав | нет | нет | нет |
|
||||
| Количество стеблей | нет (только в метках вариантов «N роз») | нет | нет |
|
||||
| Высота / размеры | нет | нет | нет |
|
||||
| Уход | нет | нет | нет |
|
||||
| Наличие / остаток | не показывается | не показывается | не показывается |
|
||||
| Срок доставки | не показывается (только текст «от 80 руб») | не показывается | не показывается |
|
||||
| «Просмотренные товары» | нет (первый в сессии) | да | да |
|
||||
|
||||
**Пробелы:** состав, количество стеблей, высота/габариты, уход, наличие/остаток и срок доставки
|
||||
не выводятся как структурированные данные; состав и число цветов спрятаны в названии
|
||||
(«Белая ромашка, примерно 51 цветочек»). Варианты («N роз») есть только у части товаров и меняют цену.
|
||||
|
||||
## 5. Корзина / оформление / оплата
|
||||
|
||||
Оформление одностраничное — `/order/` (секции «Корзина → Оформление → Покупатель → Доставка → Оплата»).
|
||||
Добавление в корзину: `POST /cart/add/` (JSON: `product_id`, `quantity`).
|
||||
|
||||
**Промокод:** поле `input[name=coupon_code]` + кнопка «Активировать» (AJAX). Неверный код → ошибка
|
||||
«Купон недействителен»; при успехе появляется «Отменить». Валидный код и размер скидки получить не удалось.
|
||||
|
||||
**Порог бесплатной доставки — противоречие подтверждено:**
|
||||
|
||||
| Источник | Утверждение |
|
||||
|---|---|
|
||||
| `/dostavka/` | бесплатно от 100 BYN, иначе 15 BYN; за МКАД 15 BYN + 0.50 BYN/км; срок до 2 ч |
|
||||
| meta `/dostavka/` | бесплатная доставка при заказе от 100 BYN |
|
||||
| копирайт `/category/bukety-tsvetov/` | бесплатно от 50 руб |
|
||||
| meta `/category/bukety-tsvetov/` | бесплатно от 100 BYN |
|
||||
| копирайт `/category/monobuket/` | бесплатно от 80 руб |
|
||||
| meta `/category/monobuket/` | бесплатно от 100 BYN |
|
||||
| текст PDP | бесплатно от 80 руб |
|
||||
| **фактическая конфигурация (проверено)** | курьер «Бесплатно» при корзине 43 BYN и 117 BYN — минимума нет; доступен **один** вариант доставки `8.delivery` «Доставка цветов по Минску», Бесплатно; тариф 15 BYN в корзине недостижим |
|
||||
|
||||
**Типы доставки:**
|
||||
|
||||
| Тип | id | Цена | Дата | Варианты |
|
||||
|---|---|---|---|---|
|
||||
| Доставка курьером | `todoor` | Бесплатно | Сегодня | `8.delivery` «Доставка цветов по Минску», Бесплатно (`variants_count: 1`) |
|
||||
| Самовывоз из магазинов | `pickup` | Бесплатно | Завтра | — |
|
||||
|
||||
Слота времени нет: дата/время — свободное текстовое поле `auth[data][data_i_vremya_dostavki]` +
|
||||
вычисляемая строка «Срок доставки». Адрес — через адаптер Yandex Maps (`possible_addresses: []`).
|
||||
|
||||
**Поля формы (точные `name`):**
|
||||
|
||||
| Секция | Поле | name | Обяз. |
|
||||
|---|---|---|---|
|
||||
| Покупатель | Имя | `auth[data][firstname]` | да |
|
||||
| Покупатель | Телефон | `auth[data][phone]` | да |
|
||||
| Покупатель | Email | `auth[data][email]` | нет |
|
||||
| Покупатель | Номер скидочной карты | `auth[data][nomer_skidochnoy_karty]` | нет |
|
||||
| Доставка | Дата и время доставки | `auth[data][data_i_vremya_dostavki]` | нет |
|
||||
| Доставка | Страна / регион / город (заблокированы) | `region[country]=blr`, `region[region]=07`, `region[city]=Минск` | — |
|
||||
| Доставка | Тип | `shipping[type_id]` (`todoor`/`pickup`) | — |
|
||||
| Доставка | Вариант | `shipping[variant_id]` (`8.delivery`) | — |
|
||||
| Получатель | Имя получателя | `details[shipping_address][imya-poluchatel]` | нет |
|
||||
| Получатель | Телефон получателя | `details[shipping_address][telefon-polucha]` | нет |
|
||||
| Получатель | Адрес доставки | `details[shipping_address][street]` | да |
|
||||
| Получатель | Текст на открытке | `details[shipping_address][tekst-na-otkryt]` | нет |
|
||||
| Комментарий | Комментарий к заказу | `confirm[comment]` | нет |
|
||||
| Hidden | Пользователь / локация | `auth[user_id]`, `region[location_id]` | — |
|
||||
|
||||
**Оплата (точный список):**
|
||||
|
||||
| value | Способ | Описание | Плагин |
|
||||
|---|---|---|---|
|
||||
| `1` | Наличные | «Оплата наличными при получении» | `cash` |
|
||||
| `29` | Оплата картой онлайн (РБ, РФ, Мир) | Visa, MasterCard, МИР, Google Pay, Yandex Pay, Apple Pay, ЕРИП | `begateway` |
|
||||
|
||||
**Гостевой чекаут:** да — форма `/order/` открывается для анонимной сессии без логина (только
|
||||
скрытый `auth[user_id]`; имя + телефон обязательны). Реальную отправку заказа выполнить не удалось.
|
||||
|
||||
## 6. Контакты и константы (проверено)
|
||||
|
||||
| Параметр | Значение |
|
||||
|---|---|
|
||||
| Телефон 1 | +375 (29) 657-30-00 (`tel:+375296573000`) |
|
||||
| Телефон 2 | +375 (33) 657-30-00 (`tel:+375336573000`) |
|
||||
| E-mail | info@La-rose.by (встречается info@la-rose.by) |
|
||||
| WhatsApp | https://wa.me/375296573000 |
|
||||
| Telegram | https://t.me/bot_a_nik_vsop |
|
||||
| VK | https://vk.com/La_Rose_by |
|
||||
| Instagram | https://www.instagram.com/larose_by/ |
|
||||
| Часы | ежедневно 09:00–21:00; праздники/предпраздничные до 23:00; онлайн-заказы 24/7 |
|
||||
| Салон (самовывоз) | г. Минск, ул. Притыцкого, 10, пом. 1Н (53.911005, 27.501101) |
|
||||
| Юрлицо | ООО «Диапазон Плюс», УНП 190438401; 220073, Минск, ул. Притыцкого, 10, пом. 1Н |
|
||||
| Торговый реестр | № 556600; свид. 19043840 от 18.02.2019 |
|
||||
| География | Минск (Беларусь); «за МКАД» упоминается в текстах, но в корзине не настраивается |
|
||||
| Аналитика | GA4 `G-GNXX0B3PD5`, `G-4SN20SG8SP`, `GTM-W8NK6WWQ`, `AW-837118909`; FB Pixel `128304465805329`; Яндекс.Метрика `72956191`; Mail.ru `3238855`; чат Bitrix24 |
|
||||
|
||||
## 7. Что не проверено / оговорки
|
||||
|
||||
- Отправка заказа и редиректы оплаты не выполнялись (нет реальных контактов/платежа) — проверена
|
||||
только структура и валидация формы.
|
||||
- Валидный промокод и размер скидки не получены.
|
||||
- Тариф за МКАД / вне Минска не воспроизводится: город заблокирован как Минск, доступен один
|
||||
бесплатный вариант доставки.
|
||||
- `/product/1997/` возвращает 404, хотя это href карточки в листинге.
|
||||
- Скрытые категории «Гортензии» и «Тюльпаны» отдают HTTP 200, но 0 товаров.
|
||||
- Извлечение опирается на разметку `div.Product-grid`: товар, доступный только по прямому URL
|
||||
и скрытый из всех листингов, в инвентарь не попал бы. Дедуплицированный итог — 94, совпадает с ожиданием.
|
||||
- Цены и акции волатильны (дата сбора — 2026-10-04).
|
||||
378
docs/PLAN.md
Normal file
378
docs/PLAN.md
Normal file
|
|
@ -0,0 +1,378 @@
|
|||
# La Rose — план переделки сайта (`docs/PLAN.md`)
|
||||
|
||||
**Проект:** `SemianiakaVY/la-rose` · **Шаблон:** `online-shop` · **Стек:** Next.js
|
||||
**Источники:** [`SPEC.md`](../SPEC.md) (контракт), [`docs/ANALYSIS.md`](ANALYSIS.md) (факты об
|
||||
источнике), [`docs/CATALOG.md`](CATALOG.md) (полный инвентарь каталога).
|
||||
**Дата:** 2026-10-04.
|
||||
|
||||
## 0. Этап и рамки
|
||||
|
||||
Текущий этап — **исследование, структура, схемы и карточки задач**. На этом этапе:
|
||||
|
||||
- **Нового дизайна НЕ делаем** (решение зафиксировано в `.w4c/project.json`) — отдельная
|
||||
дизайн-спецификация не выпускается; UI следует структуре источника и токенам, выбранным на
|
||||
слое фронтенда.
|
||||
- **Реальные платежи не подключаем** — провайдер за интерфейсом, реализация `mock`.
|
||||
- Код приложения на этом этапе не пишется: результатом этапа являются этот план, mermaid-схемы
|
||||
и карточки задач на доске.
|
||||
|
||||
## 1. Цель продукта
|
||||
|
||||
Интернет-магазин доставки цветов и подарков по Минску (переделка `la-rose.by`): каталог с
|
||||
категориями и фасетными фильтрами, карточка товара со структурированными полями, корзина и
|
||||
одностраничное оформление, личный кабинет с историей заказов и закрытая админ-панель.
|
||||
Продукт должен **работать end-to-end на сид-данных** (SPEC.md §1), UI — русский.
|
||||
|
||||
## 2. Зафиксированные решения
|
||||
|
||||
| # | Решение | Значение |
|
||||
|---|---|---|
|
||||
| R1 | Стек | **Next.js** (App Router, TypeScript) — из диалога создания проекта |
|
||||
| R2 | Деньги | Только целые минорные единицы (`priceMinor`, копейки); никаких float |
|
||||
| R3 | Форматирование чисел | `Intl.NumberFormat` / `toLocaleString('en-US')` с кодом валюты (SPEC.md §4) |
|
||||
| R4 | Валюта | Целевая валюта магазина — **BYN**; в настройках шаблона доступны только USD/EUR/RUB, поэтому работаем через одну константу `STORE_CURRENCY` (интерим `RUB`). Переключение на BYN — правка одной константы; курсовой пересчёт в рамки не входит, цены сидов берём из аудита как есть |
|
||||
| R5 | Платежи | Провайдер за одним интерфейсом `PaymentProvider`; при `None (mock)` — мок-адаптер, flow работает без ключей (SPEC.md §6) |
|
||||
| R6 | Оформление | Оформление — **одностраничное** `/checkout`, как у источника (`/order/`): корзина → покупатель → доставка → оплата. Аккаунт: по SPEC.md §2 чекаут требует аккаунта, у источника гостевой чекаут возможен — берём SPEC как контракт (чекаут после входа), гостю показываем логин с сохранением корзины |
|
||||
| R7 | Доставка | **Один источник констант** (`lib/delivery/constants.ts`): порог бесплатной доставки, тариф, за МКАД, срок, часы. Противоречие источника (50/80/100 BYN, см. ANALYSIS.md §4) снимается на одном значении |
|
||||
| R8 | Фильтры | Фасеты: **повод, цвет, тип цветка, размер/диапазон цены** + сортировки как у источника (название, цена, хиты, оценка, дата, наличие) |
|
||||
| R9 | PDP-контракт | Обязательные структурированные поля: состав, количество стеблей, высота/габариты, вариант/размер, уход, наличие, срок доставки (сейчас отсутствуют — ANALYSIS.md §3, CATALOG.md §4) |
|
||||
| R10 | URL | Существующие человекочитаемые слаги категорий и товаров сохраняем 1:1; для товаров с числовыми `/product/<id>/` готовим **301-карту** на новые слаги (CATALOG.md §3) |
|
||||
| R11 | Контент | Информационные страницы источника переносим: О компании, B2B, Доставка, Оплата, Как заказать, Возврат, Контакты, Вакансии, Политика; добавляем **FAQ** (нет у источника) |
|
||||
| R12 | Аналитика и чат | Паритет по Яндекс.Метрике/GA4/FB Pixel закладываем; судьба чата Bitrix24 — открытый вопрос (см. §9) |
|
||||
|
||||
## 3. Информационная архитектура (маршруты)
|
||||
|
||||
### Витрина
|
||||
|
||||
| Маршрут | Экран | Источник |
|
||||
|---|---|---|
|
||||
| `/` | Главная: hero, категории, хиты | SPEC.md §3 |
|
||||
| `/catalog` | Все товары, фильтры, сортировка, пагинация | SPEC.md §3, R8 |
|
||||
| `/catalog/[categorySlug]` | Товары категории (11 категорий источника + скрытые, CATALOG.md §1–2) | SPEC.md §3 |
|
||||
| `/product/[slug]` | Карточка: галерея, цена/старая цена, бейдж, варианты, PDP-контракт R9, в корзину | SPEC.md §3, R9 |
|
||||
| `/cart` | Строки, количество, промокод, итоги | SPEC.md §3, ANALYSIS.md §4 |
|
||||
| `/checkout` | Оформление (одна страница): покупатель → доставка → оплата | SPEC.md §5.2, R6 |
|
||||
| `/checkout/success/[orderId]` | Подтверждение с номером заказа | SPEC.md §3 |
|
||||
| `/account/orders`, `/account/orders/[orderId]` | История и детали заказа | SPEC.md §3 |
|
||||
| `/login`, `/register`, `/logout` | Аутентификация | SPEC.md §3 |
|
||||
| `/search?query=` | Поиск по названию/описанию | SPEC.md §6 |
|
||||
| `/pages/[slug]` | Информационные страницы (R11) | ANALYSIS.md §5 |
|
||||
|
||||
### Админ (за ролью `admin`)
|
||||
|
||||
| Маршрут | Экран |
|
||||
|---|---|
|
||||
| `/admin` | Дашборд: последние заказы, низкий остаток, выручка за период |
|
||||
| `/admin/products` | Список/создание/правка/архив, изображения, цена и остаток |
|
||||
| `/admin/categories` | Список/создание/правка/порядок |
|
||||
| `/admin/orders`, `/admin/orders/[orderId]` | Список со статусами, детали и смена статуса |
|
||||
|
||||
### Карта страниц
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
HOME["/ — Главная"] --> CAT["/catalog — все товары (фасеты, сортировки)"]
|
||||
CAT --> C1["/catalog/bukety-tsvetov (92)"]
|
||||
CAT --> C2["/catalog/sbornye-bukety (36)"]
|
||||
CAT --> C3["/catalog/bukety-iz-alstromerii (15)"]
|
||||
CAT --> C4["/catalog/bukety-iz-gvozdiki (16)"]
|
||||
CAT --> C5["/catalog/bukety-iz-kustovoy-rozy (20)"]
|
||||
CAT --> C6["/catalog/bukety-iz-khrizantemy (37)"]
|
||||
CAT --> C7["/catalog/svadebnye-bukety-nevesty (3)"]
|
||||
CAT --> C8["/catalog/monobuket (23)"]
|
||||
CAT --> C9["/catalog/kompozitsii (7)"]
|
||||
CAT --> C10["/catalog/tsvety-v-yashchike (1)"]
|
||||
CAT --> C11["/catalog/tsvety-v-korzine (6)"]
|
||||
C1 --> PDP["/product/[slug] — 94 товара"]
|
||||
PDP --> CART["/cart — корзина + промокод"]
|
||||
CART --> CHECKOUT["/checkout — одна страница"]
|
||||
CHECKOUT --> OK["/checkout/success/[orderId]"]
|
||||
HOME --> AUTH["/login · /register"]
|
||||
AUTH --> ACC["/account/orders"]
|
||||
ACC --> ORD["/account/orders/[orderId]"]
|
||||
HOME --> SRC["/search?query="]
|
||||
HOME --> PAGES["/pages/[slug] — о компании, доставка, оплата, как заказать, возврат, контакты, b2b, вакансии, политика, FAQ"]
|
||||
HOME --> ADMIN["/admin — дашборд (роль admin)"]
|
||||
ADMIN --> AP["/admin/products"]
|
||||
ADMIN --> AC["/admin/categories"]
|
||||
ADMIN --> AO["/admin/orders"]
|
||||
```
|
||||
|
||||
## 4. Модель данных
|
||||
|
||||
Расширяем модель SPEC.md §4 полями, которые требует источник (кросс-листинг, бейджи, старая цена,
|
||||
варианты, промокоды, контент). Ключевые дополнения выделены.
|
||||
|
||||
- **Category** — id, slug, name, description, position, parentId?, `visible` (скрытые категории
|
||||
источника: розы/гортензии/тюльпаны — CATALOG.md §2).
|
||||
- **Product** — id, slug, name, description, `priceMinor` (**R2**), `oldPriceMinor?` (старая цена),
|
||||
`currency`, `badge` (`hit`|`new`|`sale`|null), `stock`, status (`draft`|`active`|`archived`),
|
||||
createdAt, **`composition`**, **`stems?`**, **`heightCm?`**, **`care`**, **`deliveryTime`** (**R9/R11**).
|
||||
- **ProductCategory** — productId, categoryId (кросс-листинг: 256 слотов → 94 товара).
|
||||
- **ProductImage** — productId, url, position.
|
||||
- **ProductVariant** — productId, label («15 роз»), priceMinor, stock (у источника: 15/19/25 роз → 198/240/325 BYN).
|
||||
- **ProductFeature** — productId, key («Кому дарим цветы»), value[] (характеристики/фасеты, R8).
|
||||
- **Cart** / **CartItem** — productId, quantity, цена всегда из продукта.
|
||||
- **Customer** / **Address** — email, passwordHash, name, addresses[].
|
||||
- **Order** — number, customerId, status (`pending`|`paid`|`fulfilled`|`cancelled`),
|
||||
subtotalMinor, shippingMinor, `discountMinor`, totalMinor, currency, shippingAddress (получатель,
|
||||
телефон, `giftNote` = текст открытки, deliveryDate/Time), promoCodeId?, createdAt.
|
||||
- **OrderItem** — orderId, productId, name, unitPriceMinor, quantity (**иммутабельный снимок**).
|
||||
- **Payment** — orderId, provider, providerRef, status, amountMinor.
|
||||
- **PromoCode** — code, type, value, activeFrom/To (`coupon_code` источника).
|
||||
- **ContentPage** — slug, title, body (R11; FAQ — блоком или страницей).
|
||||
- **DeliveryOption** — id, name (`todoor`/`pickup`), priceMinor, freeOverMinor (`R7`).
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
CATEGORY {
|
||||
int id PK
|
||||
string slug
|
||||
string name
|
||||
int parentId FK
|
||||
bool visible
|
||||
}
|
||||
PRODUCT {
|
||||
int id PK
|
||||
string slug
|
||||
string name
|
||||
int priceMinor
|
||||
int oldPriceMinor
|
||||
string currency
|
||||
string badge
|
||||
int stock
|
||||
string status
|
||||
string composition
|
||||
int stems
|
||||
int heightCm
|
||||
}
|
||||
PRODUCT_CATEGORY {
|
||||
int productId FK
|
||||
int categoryId FK
|
||||
}
|
||||
PRODUCT_IMAGE {
|
||||
int id PK
|
||||
int productId FK
|
||||
string url
|
||||
int position
|
||||
}
|
||||
PRODUCT_VARIANT {
|
||||
int id PK
|
||||
int productId FK
|
||||
string label
|
||||
int priceMinor
|
||||
int stock
|
||||
}
|
||||
PRODUCT_FEATURE {
|
||||
int id PK
|
||||
int productId FK
|
||||
string key
|
||||
string value
|
||||
}
|
||||
CART {
|
||||
int id PK
|
||||
int customerId FK
|
||||
}
|
||||
CART_ITEM {
|
||||
int id PK
|
||||
int cartId FK
|
||||
int productId FK
|
||||
int quantity
|
||||
}
|
||||
CUSTOMER {
|
||||
int id PK
|
||||
string email
|
||||
string passwordHash
|
||||
string name
|
||||
}
|
||||
ADDRESS {
|
||||
int id PK
|
||||
int customerId FK
|
||||
string street
|
||||
}
|
||||
ORDER {
|
||||
int id PK
|
||||
string number
|
||||
int customerId FK
|
||||
string status
|
||||
int subtotalMinor
|
||||
int shippingMinor
|
||||
int discountMinor
|
||||
int totalMinor
|
||||
string currency
|
||||
string giftNote
|
||||
int promoCodeId FK
|
||||
datetime createdAt
|
||||
}
|
||||
ORDER_ITEM {
|
||||
int id PK
|
||||
int orderId FK
|
||||
int productId FK
|
||||
string name
|
||||
int unitPriceMinor
|
||||
int quantity
|
||||
}
|
||||
PAYMENT {
|
||||
int id PK
|
||||
int orderId FK
|
||||
string provider
|
||||
string providerRef
|
||||
string status
|
||||
int amountMinor
|
||||
}
|
||||
PROMO_CODE {
|
||||
int id PK
|
||||
string code
|
||||
string type
|
||||
int value
|
||||
}
|
||||
CONTENT_PAGE {
|
||||
int id PK
|
||||
string slug
|
||||
string title
|
||||
string body
|
||||
}
|
||||
DELIVERY_OPTION {
|
||||
string id PK
|
||||
string name
|
||||
int priceMinor
|
||||
int freeOverMinor
|
||||
}
|
||||
CATEGORY ||--o{ CATEGORY : "parent of"
|
||||
CATEGORY ||--o{ PRODUCT_CATEGORY : lists
|
||||
PRODUCT ||--o{ PRODUCT_CATEGORY : "listed in"
|
||||
PRODUCT ||--o{ PRODUCT_IMAGE : has
|
||||
PRODUCT ||--o{ PRODUCT_VARIANT : has
|
||||
PRODUCT ||--o{ PRODUCT_FEATURE : has
|
||||
PRODUCT ||--o{ CART_ITEM : "added as"
|
||||
PRODUCT ||--o{ ORDER_ITEM : "snapshot in"
|
||||
CUSTOMER ||--o| CART : owns
|
||||
CART ||--o{ CART_ITEM : contains
|
||||
CUSTOMER ||--o{ ADDRESS : has
|
||||
CUSTOMER ||--o{ ORDER : places
|
||||
PROMO_CODE ||--o{ ORDER : discounts
|
||||
ORDER ||--|{ ORDER_ITEM : contains
|
||||
ORDER ||--o{ PAYMENT : "paid by"
|
||||
```
|
||||
|
||||
## 5. Ключевые потоки
|
||||
|
||||
### 5.1 Витрина: каталог → корзина
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["Каталог / фасеты"] --> B["Карточка товара"]
|
||||
B --> C{"В наличии?"}
|
||||
C -- нет --> D["Кнопка disabled + причина"]
|
||||
C -- да --> E["POST /api/cart — добавить"]
|
||||
E --> F["Бейдж корзины обновлён"]
|
||||
F --> B
|
||||
```
|
||||
|
||||
### 5.2 Чекаут и оплата
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
actor C as Покупатель (вошёл)
|
||||
participant UI as /checkout
|
||||
participant API as API
|
||||
participant PAY as PaymentProvider (mock)
|
||||
participant DB as БД
|
||||
C->>UI: Заполняет получателя, доставку, промокод
|
||||
UI->>API: POST /api/checkout (idempotency-key)
|
||||
API->>DB: Ревалидация цен и остатков серверно
|
||||
alt Товар распродан
|
||||
API-->>UI: 409 + какой товар недоступен
|
||||
else Всё доступно
|
||||
API->>DB: Создать Order (status=pending) + OrderItem (снимок)
|
||||
API->>PAY: charge(amountMinor)
|
||||
alt Оплата успешна
|
||||
PAY-->>API: succeeded, providerRef
|
||||
API->>DB: Order=paid, Payment=succeeded
|
||||
API-->>UI: 201 {orderNumber}
|
||||
UI-->>C: /checkout/success/[orderId]
|
||||
else Оплата не прошла
|
||||
PAY-->>API: failed
|
||||
API->>DB: Order остаётся pending
|
||||
API-->>UI: 402 + путь повтора
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
### 5.3 Админ: жизненный цикл товара и заказа
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> draft: создать товар
|
||||
draft --> active: опубликовать
|
||||
active --> archived: архивировать
|
||||
archived --> active: вернуть
|
||||
note right of archived
|
||||
Архивный товар исчезает из витрины,
|
||||
но остаётся в прошлых заказах.
|
||||
end note
|
||||
```
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> pending: заказ создан
|
||||
pending --> paid: оплата подтверждена
|
||||
pending --> cancelled: отклонён
|
||||
paid --> fulfilled: выдан/доставлен
|
||||
paid --> cancelled: возврат
|
||||
```
|
||||
|
||||
## 6. Данные для наполнения (сиды из аудита)
|
||||
|
||||
- **Категории:** 11 видимых (+ 3 скрытых: розы/гортензии/тюльпаны, CATALOG.md §2).
|
||||
- **Товары:** 94 уникальных с ценами, старыми ценами и бейджами (CATALOG.md §3); кросс-листинг
|
||||
через `ProductCategory`.
|
||||
- **Варианты:** у части товаров («N роз» → цена) — `ProductVariant`.
|
||||
- **Константы магазина:** телефоны, e-mail, часы, адрес самовывоза, юрлицо, мессенджеры
|
||||
(CATALOG.md §6) → `lib/store/constants.ts`.
|
||||
- **PDP-контракт R9** заполняется вручную/скриптом при переносе: состав, стебли, высота, уход,
|
||||
наличие, срок доставки (в источнике отсутствуют).
|
||||
|
||||
## 7. Слои сборки и приёмка (definition of done)
|
||||
|
||||
| # | Слой | Владелец | Проверка (команда / runtime) |
|
||||
|---|---|---|---|
|
||||
| 1 | План и рамки | Startup Creator | `docs/PLAN.md` + `docs/CATALOG.md` в репозитории; каждая карточка слоя содержит проверку |
|
||||
| 2 | Диаграмма архитектуры | Diagram Expert | ERD/архитектура на `/diagrams` открываются без потерь; сущности = §4 |
|
||||
| 3 | БД и формы | DataTables Expert | миграции + сид на чистом клоне; агрегатный запрос = пересчитанному вручную итогу |
|
||||
| 4 | Бэкенд и API | Code Expert | `npm run lint`/`typecheck` + неавторизованный запрос к админ-маршруту → 401/403 |
|
||||
| 5 | Фронтенд | Code Expert | `npm run build` + browse → cart → checkout → confirmation проходится на мок-провайдере |
|
||||
| 6 | Админ-панель | Code Expert | нон-админ на `/admin/*` получает отказ серверно; смена статуса логируется |
|
||||
| 7 | Control Panel | Control Panel Builder | виджеты показывают данные или пустое состояние; нет спиннера вечно; нет гориз. скролла 390×844 |
|
||||
| 8 | Workflows | Elsa Workflows Manager | тестовый вебхук создаёт задачу и запись письма; неоплаченная ветка пропускает письмо |
|
||||
| 9 | Качество и поставка | Code Expert | `npm run ci` (install + lint + typecheck + test + build) зелёный; README quickstart на чистом клоне |
|
||||
| 10 | Деплой | Server Ops | публичный URL отдаёт приложение; рестарт контейнера восстанавливает сервис |
|
||||
|
||||
Полные критерии приёмки — `SPEC.md` §8.
|
||||
|
||||
## 8. Поэтапный порядок сборки
|
||||
|
||||
1. Каркас Next.js: install → dev-server → пустая оболочка → коммит.
|
||||
2. Схема и миграции по §4, сид из §6.
|
||||
3. Каталог и карточка (витрина становится демонстрируемой).
|
||||
4. Корзина + чекаут + оплата (сначала мок).
|
||||
5. Аккаунт + история заказов.
|
||||
6. Админ-панель.
|
||||
7. Качество: тесты, CI, README, `.env.example`, доступность.
|
||||
|
||||
## 9. Открытые вопросы (нужно решение пользователя)
|
||||
|
||||
| # | Вопрос | Варианты |
|
||||
|---|---|---|
|
||||
| Q1 | Валюта витрины на этом этапе | интерим `RUB` с константой (рекомендую) ↔ сразу включить `BYN`, если платформа позволит |
|
||||
| Q2 | Скрытые категории источника | перенести как невидимые (рекомендую) ↔ удалить ↔ сделать видимыми |
|
||||
| Q3 | SEO-слаги | сохранить 1:1 (рекомендую) ↔ новая схема + 301 |
|
||||
| Q4 | Чат Bitrix24 | сохранить ↔ заменить на WhatsApp/Telegram ↔ убрать |
|
||||
| Q5 | FAQ/блог | FAQ-страница на этом этапе (рекомендую) ↔ отложить блог |
|
||||
| Q6 | Числовой ID `/product/1997/` (404) | выяснить живой URL у владельца ↔ исключить товар |
|
||||
|
||||
## 10. Вне рамок
|
||||
|
||||
Мультивендор-маркетплейс, подписки, склад/инвентарные интеграции, налоговые движки,
|
||||
мультиязычная витрина (SPEC.md §1); реальные платёжные шлюзы; новый визуальный дизайн на этом
|
||||
этапе; перенос аналитики и чата — только решение и закладки (R12).
|
||||
Loading…
Reference in a new issue