Этап 0: документация и макеты
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
commit
3400f58a5a
75 files changed
+14283
No files matched your search
@@ -0,0 +1,19 @@
|
||||
# Этап 0. Документация
|
||||
|
||||
Статус: готово 20.10.2026.
|
||||
|
||||
## 1. Цель
|
||||
|
||||
Зафиксировать продукт, архитектуру, модель данных и план этапов так, чтобы каждый этап можно было запускать в отдельной сессии.
|
||||
|
||||
## 2. Сделано
|
||||
|
||||
1. Обсуждение исходной задачи ([history/HUMAN_IDEA.md](../history/HUMAN_IDEA.md)) и макетов, решения [D-001…D-021](../decisions/README.md).
|
||||
2. Документы `docs/01…10`, файлы этапов, [CLAUDE.md](../../CLAUDE.md).
|
||||
3. Макеты скопированы в `design/handoff/`.
|
||||
4. Репозиторий инициализирован локально, без коммитов.
|
||||
|
||||
## 3. Осталось
|
||||
|
||||
1. Переезд разработки под пользователя vx_dev (R-00), репозиторий в Gitea и SSH-доступ для vx_dev (R-01), затем первый коммит и push по просьбе пользователя.
|
||||
2. Вопросы к следующим этапам — в [00-index.md](../00-index.md), раздел 4.2. Этап 1a они не блокируют.
|
||||
@@ -0,0 +1,39 @@
|
||||
# Этап 1a. Фундамент
|
||||
|
||||
Статус: не начат.
|
||||
|
||||
## 1. Цель
|
||||
|
||||
Рабочий каркас: одно приложение отвечает на все dev-домены, определяет сайт, язык и валюту, показывает оболочку обоих брендов в своих цветах; админка с базовыми справочниками.
|
||||
|
||||
## 2. Входит
|
||||
|
||||
1. Проект: Next.js 16.4, Payload 3.x (или 4, если вышел стабильный), TypeScript strict, pnpm, ESLint, Prettier. Структура папок — [02-architecture.md](../02-architecture.md), раздел 3.
|
||||
2. PostgreSQL: адаптер с `idType: 'uuid'`, push в dev, настроенные миграции для prod.
|
||||
3. Payload: админка только на хосте админки; `admins` с ролями; плагин multi-tenant (поле `site`); локализация `en, ru, de, fr, es` с откатом на `en`; интерфейс админки `ru` и `en`; `filterAvailableLocales`.
|
||||
4. Коллекции: `sites`, `domains`, `currencies`, `countries`, `locations`, `tags`, `tariffs`, `payment-systems` (пока только адаптер `manual`), `media` — по [03-data-model.md](../03-data-model.md).
|
||||
5. Proxy: Host → домен → сайт и тип фронтенда; префиксы языков (next-intl, английский без префикса); определение языка по [06-i18n.md](../06-i18n.md), раздел 4; cookie валюты; внутренние маршруты; закрыть `/admin` и REST Payload на доменах брендов.
|
||||
6. Темы: токены брендов ([07-frontend.md](../07-frontend.md), раздел 4), Tailwind v4, `data-site`, `data-theme`, три режима темы без мигания; шрифты через `next/font`.
|
||||
7. Оболочки: шапка и подвал маркетинговых сайтов обоих брендов с переключателями языка, валюты и темы; оболочка кабинета (боковая панель и мобильные вкладки) с заглушками страниц.
|
||||
8. Начальные данные (seed): 2 сайта, dev-домены, валюты, 30 стран и RU, 30 локаций на каждом сайте, тарифы dedicated (3 уровня) и mass (месяц, год) с ценами в RUB и USD, платёжная система `manual`.
|
||||
9. `/svc/health`.
|
||||
10. systemd user-юнит `veilix-dev.service`; текст конфигурации nginx для dev-хостов на согласование.
|
||||
11. Раздел «Команды» в [CLAUDE.md](../../CLAUDE.md).
|
||||
|
||||
## 3. Не входит
|
||||
|
||||
Страницы по макетам (1b), вход (1c), биллинг (1d).
|
||||
|
||||
## 4. Перед стартом
|
||||
|
||||
Root: R-00…R-06 ([09-infrastructure.md](../09-infrastructure.md), раздел 8). Открытых решений к этапу нет.
|
||||
|
||||
## 5. Готово, когда
|
||||
|
||||
1. `dev.veilix.app` и `dev.veilixvpn.com` открываются по HTTPS: шапка и подвал в цветах бренда, три режима темы.
|
||||
2. Работают `/ru`, `/de`, `/fr`, `/es`; первый заход без префикса перенаправляет по правилам определения языка; поисковые боты не перенаправляются.
|
||||
3. Переключатель валюты запоминает выбор.
|
||||
4. `dev.plc.veilix.cc/admin`: переключение сайтов, справочники редактируются, локализованные поля переключаются по языкам, у сайта видны только его языки.
|
||||
5. В URL админки — UUID.
|
||||
6. `dev.my.*` показывает оболочку кабинета; `/admin` на доменах брендов — 404.
|
||||
7. `pnpm build`, линтер и проверка типов проходят.
|
||||
@@ -0,0 +1,34 @@
|
||||
# Этап 1b. Маркетинговые страницы
|
||||
|
||||
Статус: не начат.
|
||||
|
||||
## 1. Цель
|
||||
|
||||
Сайты обоих брендов по макетам, с контентом из Payload, формами и SEO.
|
||||
|
||||
## 2. Входит
|
||||
|
||||
1. Страницы по макетам для обоих брендов: главная, цены, локации (карта, отрисованная на сервере), поддержка ([07-frontend.md](../07-frontend.md), раздел 2). Юридические страницы `/legal/*`, 404 и 500.
|
||||
2. Коллекции `pages`, `faq` (с местами показа), `leads`; поля контактов в `sites`.
|
||||
3. Контент из макетов на RU и EN: тексты, FAQ, локации, тарифы.
|
||||
4. Черновики юридических текстов на RU и EN с заглушками вместо данных юрлица: условия, конфиденциальность, возвраты, cookies.
|
||||
5. ALTCHA ([08-integrations.md](../08-integrations.md), раздел 2). Формы «Индивидуальные условия» и обратной связи с ALTCHA пишут в `leads`. Письмо администратору появится в 1c.
|
||||
6. SEO: `<title>` и описания на каждом языке, `hreflang`, `canonical`, `sitemap.xml` и `robots.txt` на каждый домен, картинки для соцсетей.
|
||||
7. Статическая сборка «язык × валюта» и пересборка по событию из Payload ([D-017](../decisions/D-017-static-pages.md)).
|
||||
8. Решить, показывать ли количество свободных серверов.
|
||||
|
||||
## 3. Не входит
|
||||
|
||||
Оформление заказа (1d), кабинет (1f), переводы на de, fr, es (1h; до этого — английский запасной).
|
||||
|
||||
## 4. Перед стартом
|
||||
|
||||
Q-02 (цены mass в USD), Q-08 (email поддержки), Q-09 (часовой пояс), Q-16 (ящик поддержки).
|
||||
|
||||
## 5. Готово, когда
|
||||
|
||||
1. Страницы обоих брендов совпадают с макетами: светлая и тёмная тема, десктоп и мобильный, RU и EN.
|
||||
2. Правка цены, статуса локации или FAQ в админке видна на сайте в течение нескольких секунд.
|
||||
3. Lighthouse mobile ≥ 90 на главной и странице цен обоих брендов.
|
||||
4. Формы создают заявки, ALTCHA работает.
|
||||
5. `sitemap.xml` и `hreflang` проходят проверку.
|
||||
@@ -0,0 +1,32 @@
|
||||
# Этап 1c. Вход по коду и почта
|
||||
|
||||
Статус: не начат.
|
||||
|
||||
## 1. Цель
|
||||
|
||||
Регистрация и вход по коду из письма в кабинетах обоих брендов; почтовая подсистема с журналом.
|
||||
|
||||
## 2. Входит
|
||||
|
||||
1. Почта ([08-integrations.md](../08-integrations.md), раздел 1): глобал «Почта» (транспорты `smtp`, `sendmail`, `log_only`), email-адаптер, `email-templates` с шапкой и подвалом бренда, `email-log`, задача `send-email`, тестовое письмо, флаг «Записывать коды входа в журнал».
|
||||
2. Шаблоны на RU и EN: `login_code`, `admin_new_lead` (и подключить его к формам из 1b).
|
||||
3. `customers` со своей стратегией, `customer-sessions`, `auth-codes`; запрос и проверка кода, лимиты, ALTCHA ([05-auth.md](../05-auth.md), разделы 2–4).
|
||||
4. Страница `/login` по макету с состояниями: код отправлен, ошибка, истёк, повторная отправка через 60 секунд.
|
||||
5. Выход, выход на всех устройствах.
|
||||
6. Язык и валюта аккаунта при регистрации ([04-billing.md](../04-billing.md), раздел 2).
|
||||
7. Задача `cleanup` для кодов, сессий и журнала.
|
||||
|
||||
## 3. Не входит
|
||||
|
||||
Telegram (этап 3), реферальная привязка при регистрации (1g).
|
||||
|
||||
## 4. Перед стартом
|
||||
|
||||
Root: R-07 (Postfix, OpenDKIM, DNS) или данные SMTP-провайдера. Без них этап делается на транспорте `log_only`.
|
||||
|
||||
## 5. Готово, когда
|
||||
|
||||
1. Регистрация и вход работают на `dev.my.veilix.app` и `dev.my.veilixvpn.com`; аккаунты сайтов независимы.
|
||||
2. С флагом коды видны в журнале; на `log_only` письма не уходят.
|
||||
3. Через `sendmail` или `smtp` письмо доходит до Gmail не в спам; оценка mail-tester ≥ 9/10.
|
||||
4. Лимиты и счётчик попыток работают; сессии отзываются.
|
||||
@@ -0,0 +1,36 @@
|
||||
# Этап 1d. Биллинг без эквайринга
|
||||
|
||||
Статус: не начат.
|
||||
|
||||
## 1. Цель
|
||||
|
||||
Деньги и заказы работают целиком: оформление заказа, оплата с баланса, ручные платежи, продления, льготный период — без внешних платёжных систем.
|
||||
|
||||
## 2. Входит
|
||||
|
||||
1. Коллекции `orders`, `payments`, `ledger-entries`, `payment-methods` (структура), `keys` (поля и статусы), `audit-log`.
|
||||
2. `core/billing`: `processPayment`, оплата с баланса, задачи `renewals`, `expiry`, `reminders`, `reconcile`; блокировки и уникальные ограничения ([04-billing.md](../04-billing.md)).
|
||||
3. `/order` по макетам обоих брендов: шаг «Почта» из 1c, шаг «Оплата» (с баланса; «Заказ создан, ожидает оплаты», когда платёжных систем нет), согласие с условиями, сводка из тарифа, локации и валюты.
|
||||
4. `/buy` в кабинете: dedicated — сетка локаций с ценами, mass — «Месяц» и «Год».
|
||||
5. Админка: ручной платёж, корректировка баланса, возврат на баланс, продление вручную, блокировка, «Очередь выдачи»; всё — в журнал действий.
|
||||
6. Шаблоны писем на RU и EN: `order_paid`, `key_provisioning`, `renewal_reminder`, `expiry_reminder`, `renewal_succeeded`, `renewal_failed`, `grace_started`, `key_expired`, `topup_succeeded`, `refund_issued`, `admin_new_order`, `admin_provisioning_needed`.
|
||||
|
||||
## 3. Не входит
|
||||
|
||||
Подключения и выдача ключа (1e), реальные платёжные системы (этап 4). Для проверок ключ переводится в `active` вручную в админке.
|
||||
|
||||
## 4. Перед стартом
|
||||
|
||||
Этап 1c готов.
|
||||
|
||||
## 5. Готово, когда
|
||||
|
||||
Автотесты `core/billing` проходят сценарии:
|
||||
|
||||
1. Ручное пополнение → оплата заказа с баланса → заказ оплачен → ключ `provisioning`.
|
||||
2. Частичный баланс + ручной платёж на разницу → заказ оплачен.
|
||||
3. Продление с баланса за 24 часа; денег нет → заказ ждёт → пополнение само оплачивает продление.
|
||||
4. Переходы в льготный период и «истёк» с письмами.
|
||||
5. Частичный и полный возврат на баланс, с отменой ключа и без.
|
||||
6. Повторный `processPayment` и параллельные запуски задач не списывают дважды.
|
||||
7. `reconcile` не находит расхождений.
|
||||
@@ -0,0 +1,26 @@
|
||||
# Этап 1e. Ключи и подключения
|
||||
|
||||
Статус: не начат.
|
||||
|
||||
## 1. Цель
|
||||
|
||||
Администратор выдаёт ключи вручную; пользователь получает конфиги и ссылки на странице ключа.
|
||||
|
||||
## 2. Входит
|
||||
|
||||
1. Коллекция `connections` с шифрованием содержимого ([03-data-model.md](../03-data-model.md), 5.2).
|
||||
2. Админка: на странице ключа — добавление подключений (WG/AWG — файлом или текстом, ссылка Happ, ссылка Xray, RU-адрес, номер устройства, страна), действие «Выдать ключ», список «К отключению».
|
||||
3. Страница ключа в кабинете: срок, галочка автопродления, «Продлить сейчас», WG-конфиги (скачать, QR), Happ/Xray (копировать, QR); для mass — WG по странам: конфиги, которые добавил администратор; нужна другая страна — ссылка на поддержку.
|
||||
4. Состояния: готовится, льготный период, истёк, нет подключений.
|
||||
5. Содержимое конфигов отдаётся отдельным запросом только владельцу, в HTML страницы не попадает. QR строится в браузере из полученного содержимого.
|
||||
6. Шаблон `key_ready` на RU и EN.
|
||||
|
||||
## 3. Перед стартом
|
||||
|
||||
Этап 1d готов.
|
||||
|
||||
## 4. Готово, когда
|
||||
|
||||
1. Администратор выдал ключ — пользователь видит его активным, срок пошёл с момента выдачи.
|
||||
2. Скачанный `.conf` импортируется в WireGuard; QR сканируется в WireGuard и Happ.
|
||||
3. Чужой пользователь получает 404 на конфиг (тест).
|
||||
@@ -0,0 +1,24 @@
|
||||
# Этап 1f. Веб-кабинеты
|
||||
|
||||
Статус: не начат.
|
||||
|
||||
## 1. Цель
|
||||
|
||||
Кабинеты обоих брендов по макетам `App` и `MassApp`.
|
||||
|
||||
## 2. Входит
|
||||
|
||||
1. Главная: ключи, «Купить ключ», FAQ.
|
||||
2. Список ключей; бейдж «Истекает» по правилу [04-billing.md](../04-billing.md), раздел 15.
|
||||
3. «Счёт и платежи»: баланс, пополнение (пресеты и своя сумма; пока платёжных систем нет — понятное сообщение), сохранённая карта и «Отвязать карту» (видно с этапа 4), ближайшие списания, история.
|
||||
4. Настройки: язык, валюта (правило — [04-billing.md](../04-billing.md), раздел 2), тема; выход.
|
||||
5. Мобильная навигация: вкладки «Главная, Ключи, Купить, Ещё».
|
||||
6. Различия брендов: у mass «Список ключей» без «текущей/запасной локации».
|
||||
|
||||
## 3. Не входит
|
||||
|
||||
Реферальная страница (1g), MiniApp (этап 3).
|
||||
|
||||
## 4. Готово, когда
|
||||
|
||||
Кабинеты обоих брендов совпадают с макетами: светлая и тёмная тема, десктоп и мобильный, RU и EN. Все данные — реальные, из базы.
|
||||
@@ -0,0 +1,23 @@
|
||||
# Этап 1g. Реферальная программа
|
||||
|
||||
Статус: не начат.
|
||||
|
||||
## 1. Цель
|
||||
|
||||
«Приведите друга — вы оба получите по месяцу в подарок» по правилам [04-billing.md](../04-billing.md), раздел 11.
|
||||
|
||||
## 2. Входит
|
||||
|
||||
1. Реферальные коды пользователей.
|
||||
2. Маршрут `my.<домен>/r/<код>`: cookie `vx_ref` на 60 дней и переход на сайт бренда.
|
||||
3. Привязка при регистрации; коллекция `referrals`.
|
||||
4. Бонус обоим после первой оплаты заказа `new_key` приглашённого; статус `review` при совпадении хэша IP.
|
||||
5. Суммы бонуса по валютам в `sites`.
|
||||
6. Страница `/referral` по макету: приглашено, начислено, ожидает; ссылка с копированием; приглашённые с замаскированной почтой.
|
||||
7. Шаблон `referral_reward` на RU и EN; список приглашений в админке.
|
||||
|
||||
## 3. Готово, когда
|
||||
|
||||
1. A делится ссылкой → B регистрируется → B оплачивает первый заказ → обоим начислен бонус.
|
||||
2. Самоприглашение с того же IP попадает в `review`.
|
||||
3. Ссылка другого бренда не засчитывается.
|
||||
@@ -0,0 +1,26 @@
|
||||
# Этап 1h. Переводы, аналитика, запуск prod
|
||||
|
||||
Статус: не начат.
|
||||
|
||||
## 1. Цель
|
||||
|
||||
Сайты и кабинеты на 5 языках работают на основных доменах.
|
||||
|
||||
## 2. Входит
|
||||
|
||||
1. Переводы de, fr, es: интерфейс и контент Payload, машинный перевод LLM с глоссарием ([06-i18n.md](../06-i18n.md), раздел 7); проверка непереведённых ключей.
|
||||
2. Umami на этом сервере ([D-018](../decisions/D-018-analytics.md)) с проксированием через домены брендов; баннер cookies ([08-integrations.md](../08-integrations.md), раздел 8).
|
||||
3. Проверка производительности (Lighthouse mobile ≥ 90) и доступности.
|
||||
4. Prod под пользователем vx_prod: `.env`, команда выкладки с папками релизов и откатом ([02-architecture.md](../02-architecture.md), раздел 5), первая выкладка, начальные данные prod, первый администратор, smoke-тесты.
|
||||
5. Бэкапы базы и media с проверкой восстановления.
|
||||
6. Юридические черновики на сайтах (Q-13 — пока с заглушками).
|
||||
|
||||
## 3. Перед стартом
|
||||
|
||||
Root: R-08…R-11, по желанию R-15. Решения: Q-14 (куда бэкапы), Q-18 (кто запускает выкладку).
|
||||
|
||||
## 4. Готово, когда
|
||||
|
||||
1. Основные домены работают по HTTPS, dev и prod разделены.
|
||||
2. Выкладка и откат отрепетированы.
|
||||
3. Восстановление из бэкапа проверено.
|
||||
@@ -0,0 +1,19 @@
|
||||
# Этап 2. Chatwoot и Twenty CRM
|
||||
|
||||
Статус: не начат.
|
||||
|
||||
## 1. Входит
|
||||
|
||||
1. Chatwoot ([08-integrations.md](../08-integrations.md), раздел 4): виджет на сайтах и в кабинетах, отдельные входящие каналы для каждого бренда; идентификация вошедших пользователей с HMAC; категория в баннере cookies.
|
||||
2. Боты поддержки обоих брендов подключены к Chatwoot как Telegram-каналы.
|
||||
3. Почта поддержки (Q-16) — по решению, например email-канал Chatwoot.
|
||||
4. Twenty ([08-integrations.md](../08-integrations.md), раздел 5): заявки уходят через API фоновой задачей с повторами, `leads.crmId`.
|
||||
|
||||
## 2. Перед стартом
|
||||
|
||||
Root: R-12 — VPS, Chatwoot, Twenty, ключи API, боты поддержки в BotFather.
|
||||
|
||||
## 3. Готово, когда
|
||||
|
||||
1. Сообщения из виджетов и ботов поддержки приходят в Chatwoot с указанием бренда; вошедший пользователь опознан.
|
||||
2. Заявки появляются в Twenty.
|
||||
@@ -0,0 +1,23 @@
|
||||
# Этап 3. Telegram
|
||||
|
||||
Статус: не начат.
|
||||
|
||||
## 1. Входит
|
||||
|
||||
1. Основные боты обоих брендов на grammY: вебхук, команды, меню, тексты в Payload на всех языках ([08-integrations.md](../08-integrations.md), раздел 6).
|
||||
2. MiniApp по макетам `AppTG` и `MassAppTG` с Telegram SDK: BackButton, MainButton, тема Telegram, отклик вибрацией; вход по `initData`.
|
||||
3. Привязка почты из Telegram, «Подключить Telegram» в кабинете, «Войти через Telegram» на сайте, объединение аккаунтов ([05-auth.md](../05-auth.md), раздел 6).
|
||||
4. Уведомления в бот; реферальный код через `/start`.
|
||||
5. Тестовые боты для dev с доступом по списку Telegram-аккаунтов.
|
||||
6. Оплата в Telegram — по решению Q-11.
|
||||
|
||||
## 2. Перед стартом
|
||||
|
||||
1. Root: R-13 — основные и тестовые боты, домен для Telegram Login, адреса MiniApp.
|
||||
2. Решения: Q-10 (имена ботов), Q-11 (оплата в Telegram).
|
||||
|
||||
## 3. Готово, когда
|
||||
|
||||
1. Из Telegram можно зарегистрироваться, купить ключ (по Q-11), получить конфиги, пополнить баланс, пригласить друга.
|
||||
2. Уведомления приходят в бот.
|
||||
3. Сценарии привязки и объединения аккаунтов проходят.
|
||||
@@ -0,0 +1,26 @@
|
||||
# Этап 4. Платёжные системы
|
||||
|
||||
Статус: не начат.
|
||||
|
||||
## 1. Входит
|
||||
|
||||
1. Адаптеры ([08-integrations.md](../08-integrations.md), раздел 7):
|
||||
a. Stripe: Payment Element, сохранение карты, автосписания на переменную сумму, возвраты, отвязка карты, вебхуки;
|
||||
b. RUB: процессинги для карт РФ — пополнения (провайдеров выбираем на старте, Q-12);
|
||||
c. криптовалюта — пополнения, экран счёта с адресом, суммой и таймером курса;
|
||||
d. ЮKassa — опционально, пополнения.
|
||||
2. Состояния оформления и пополнения: 3-D Secure, отказ, ожидание подтверждения сети.
|
||||
3. Повторы автосписаний ([04-billing.md](../04-billing.md), 6.1); возврат на карту (`refund` + `payout`).
|
||||
4. Тексты согласия на автосписания в оформлении заказа и в юридических документах.
|
||||
5. Настройка платёжных систем в админке: валюты, назначения, лимиты, тестовый или боевой режим. Если бренды получат разные аккаунты одного провайдера — Q-17.
|
||||
|
||||
## 2. Перед стартом
|
||||
|
||||
1. Root: R-14 — аккаунты провайдеров (сначала тестовые).
|
||||
2. Решения: Q-12; для боевого Stripe нужны данные юрлица (Q-13).
|
||||
|
||||
## 3. Готово, когда
|
||||
|
||||
1. Каждый адаптер в тестовом режиме проходит путь от оплаты до зачисления, включая повторную доставку вебхуков.
|
||||
2. Автопродление через Stripe работает на тестовых картах. Если карта требует 3-D Secure, пользователь получает письмо оплатить вручную.
|
||||
3. Возвраты на карту работают.
|
||||
@@ -0,0 +1,13 @@
|
||||
# Этап 5. Автоматизация выдачи ключей
|
||||
|
||||
Статус: обсуждение при старте этапа.
|
||||
|
||||
## 1. Что известно
|
||||
|
||||
1. По тарифу (страны, теги) подбирается свободный сервер, бэкенд возвращает подключения для ключа.
|
||||
2. Автоматика создаёт те же подключения, что на этапе 1 добавляет администратор ([D-020](../decisions/D-020-key-models.md)), и отключает их, когда ключ истекает.
|
||||
3. Наличие в локациях обновляется автоматически, сайты пересобираются по событию.
|
||||
|
||||
## 2. Обсудить при старте
|
||||
|
||||
Источник серверов и подключений, способ интеграции, как получать WG-конфиги mass по странам, обработка ошибок выдачи.
|
||||
Reference in new issue
Block a user