Этап 0: документация и макеты

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
andreypr207andClaude Opus 5.5 committed 2026-10-21 03:30:38 +02:00
commit 3400f58a5a
75 files changed
+14283

No files matched your search

+19
View File
@@ -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 они не блокируют.
+39
View File
@@ -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`, линтер и проверка типов проходят.
+34
View File
@@ -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` проходят проверку.
+32
View File
@@ -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. Лимиты и счётчик попыток работают; сессии отзываются.
+36
View File
@@ -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` не находит расхождений.
+26
View File
@@ -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 на конфиг (тест).
+24
View File
@@ -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. Все данные — реальные, из базы.
+23
View File
@@ -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. Ссылка другого бренда не засчитывается.
+26
View File
@@ -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. Восстановление из бэкапа проверено.
+19
View File
@@ -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.
+23
View File
@@ -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. Сценарии привязки и объединения аккаунтов проходят.
+26
View File
@@ -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. Возвраты на карту работают.
+13
View File
@@ -0,0 +1,13 @@
# Этап 5. Автоматизация выдачи ключей
Статус: обсуждение при старте этапа.
## 1. Что известно
1. По тарифу (страны, теги) подбирается свободный сервер, бэкенд возвращает подключения для ключа.
2. Автоматика создаёт те же подключения, что на этапе 1 добавляет администратор ([D-020](../decisions/D-020-key-models.md)), и отключает их, когда ключ истекает.
3. Наличие в локациях обновляется автоматически, сайты пересобираются по событию.
## 2. Обсудить при старте
Источник серверов и подключений, способ интеграции, как получать WG-конфиги mass по странам, обработка ошибок выдачи.