Files
Deal/docs/superpowers/plans/2026-09-05-deal-roadmap.md
T
Rustam Khalimov 27c7831910
ci / build-test (push) Canceled after 0s
Deal — единая кодовая база
SaaS-мониторинг Telegram: ядро (модули Cards/Kanban/Pipeline/Tenants/Settings/
Discovery, Api, Infrastructure), сервисы telegram/ai/ml/storage, фронт Vue,
контракты и grpc-hosting, деплой-конфиги (dev/prod/observability/CI-раннер),
Gitea Actions CI, документация (ТЗ, техдок, api-map, код-стайл, планы, бэклог).

Текущее состояние: все этапы роадмапа 0–12 закрыты, сборка 5 sln 0/0,
тесты 1340/130/52/38/9 зелёные.
2026-09-11 23:56:47 +03:00

20 KiB
Raw Blame History

Дейл (Deal) — Roadmap этапов (все этапы 0–7 выполнены; 2026-09-08)

Исторический документ (roadmap этапов 07, 2026-09-08). Актуальное состояние — docs/superpowers/STATUS.md и docs/technical/Техническая-документация-Дейл.md.

Назначение: зафиксировать план продолжения разработки «Дейл» по этапам. Каждый этап исполняется как отдельный SDD-план (файл в docs/superpowers/plans/, ledger в .superpowers/sdd/<plan>/), задача-за-задачей с ревью. Проект НЕ git — фиксация в отчётах и ledgers.

Выполнено

  • Этап 0 — Каркас (2026-09-05-deal-scaffold.md): структура src/, фронт переехал в src/frontend/, .editorconfig+Directory.Build.props, Deal.sln (11 проектов), тесты, dev-Postgres (:5433), tenant-контекст (TenantId/ITenantContext/TenantContext AsyncLocal/ConnectionStringProvider search_path), EF (public), TenantSchemaMigrator, CI-скрипты.

  • Этап 1 — Доступ и мультитенантность (2026-09-05-deal-stage1-tenancy.md): карта /api (docs/api/api-map.md, 101 эндпоинт, 87 использует фронт), два DbContext (системный public + бессхемный tenant: таблица settings), миграции InitialSystem/InitialTenant, модуль Tenants (порты+адаптеры, Argon2id, сессии 30 дней), auth-эндпоинты 1:1 (login/logout/me/change-password), SessionMiddleware + ITenantContext.Reset, TenantProvisioningService (схема tenant_<32hex> + Migrate c MigrationsHistoryTable("__TenantMigrationsHistory", schema)), TenantBootstrapService (seed: тенант id 000…001 + admin/admin из env; идемпотентно). 25 тестов PASS.

  • Этап 2 — Settings (настройки тенанта) (2026-09-05-deal-stage2-settings.md): модуль Deal.Modules.Settings (каталог ключей/дефолты 1:1 с прототипом, ISettingsStore, SettingsService снимок+PATCH 1:1, IncomingRules, PromptFiller, RatesService) + адаптеры (SettingsStore на settings, AesGcmSecretCipher), эндпоинты GET/PATCH /api/settings, POST /api/ai/check, GET /api/rates, POST /api/rates/refresh, /api/ml/* (заглушка LocalMlClient), POST /api/admin/check-message (тестер фильтров). Секреты AI/Telegram — AES-GCM (enc: в БД, ключ env DEAL_ENCRYPTION_KEY/файл). Задачи 1–11 приняты: 175 unit-тестов PASS, build 0/0, сквозная curl-приёмка :5080 PASS=60 FAIL=0 + psql (шифрование, внутренние ключи не публикуются). Ограничение: Settings-экран обслуживается бэкендом, но Vue-фронт полностью оживает только с этапом 3 (его boot() требует /api/boards, /api/leads, /api/projects, /api/tg/status, /api/columns/state; Telegram-вкладка, кнопки «Проверить правила сейчас»/«Пересобрать индекс», «Предложить ключи» и канбан-фронт — этапы 3–6).

  • Этап 3 — Kanban (дашборд): колонки, карточки, архив/корзина (2026-09-05-deal-stage3-kanban.md): миграция TenantKanban (Boards/Cards/LeadComments/CardMoves/MlOutbox в схеме тенанта), модуль Deal.Modules.Kanban (доски/карточки/правила ColumnRules с matchHits, StorageTickService + фоновый StorageTickScheduler 30 с, ConversionRecomputer, демо-фабрика, эвристика ИИ-предложений), эндпоинты boards/columns/leads/search/events(SSE)/admin/demo/ai-suggest, boot-заглушки /projects и /tg/status, LocalMlClient+PushAsync. Задачи 115 приняты: 410 unit-тестов PASS, build 0/0, сквозная curl-приёмка :5080 PASS=94 FAIL=0 + psql. Ограничения: pipeline/очередь/отсев/FTS — этап 4; projects/файлы/reminder_due — этап 5; реальные ai/telegram/ml и discovery — этап 6; reclassify и /admin/fts/rebuild — контракт-заглушки. Фронт теперь boot'ится полностью и канбан-дашборд работает на демо-данных (реальные данные появятся с pipeline этапа 4).

  • Этап 4 — Pipeline + вкладка «Обработка» (2026-09-05-deal-stage4-pipeline.md): миграция TenantPipeline (QueueItems/RejectedItems/DedupEntries + FTS-колонки SearchTsv на Cards/RejectedItems), модуль Deal.Modules.Pipeline (ядро разбора 1:1, Ingest/ProcessingService/PipelineWorkerService pump 1:1, CardComposer через IKanjStore.AddCardAsync, dedup-связь), порт IAiClassifier + детерминированный LocalAiClassifier, эндпоинты /api/pipeline/* + демо-ingest, реальные admin/tick и admin/fts/rebuild (+SSE new_lead/тост очистки отсева), фоновые PipelineWorkerScheduler (2 с) и purge-отсева 3 дня в StorageTickScheduler, FTS-поиск /api/search. Задачи 1–13 приняты: 535 unit-тестов PASS, build 0/0, сквозная curl-приёмка :5080 (Task 13 — финал) PASS=74 FAIL=0

    • psql. Ограничения: projects/reminder_due/файлы — этап 5; реальные ai/telegram/ml-сервисы и их gRPC-ингресс, discovery, ИИ-предложения колонок на реальных данных — этап 6; оператор/лимиты/ аудит — этап 7. Вкладка «Обработка» и канбан-дашборд работают на реальном конвейере (демо-ingest до telegram-этапа 6).
  • Этап 5 — Projects («Выбранные»): стадии, напоминания, файлы/ссылки, история (2026-09-05-deal-stage5-projects.md): миграция TenantProjects (ProjectCards с partial UNIQUE LeadId), модуль Deal.Modules.Projects (стадии ProjectStages 1:1, ProjectsService: take из дашборда с уходом лида в col='taken'/ручное создание/patch presence-aware/move+история/clear-rejected/ комментарии/ссылки; ProjectReminderService; ProjectFilesService), порт IFileStorage + адаптеры LocalFileStorage/MinioFileStorage (deal-minio в compose.dev.yml), эндпоинты /api/projects* (16 шт., файлы и напоминания включены), boot-заглушка /projects снята, напоминания в admin/tick + фоновый 30-с цикл StorageTickScheduler + SSE reminder_due. Задачи 1–13 приняты: 620 unit-тестов PASS, build 0/0, сквозная curl-приёмка :5080 (Task 13 — финал) PASS=75 FAIL=0 + psql (take- семантика, история, clear-rejected, UNIQUE LeadId, файлы на диске, reminder_due фоновым циклом). Ограничения: реальные ai/telegram/ml-сервисы и их gRPC-ингресс, discovery, telegram-вкладка и /tg/status — этап 6; оператор/лимиты/админка, мульти-аренда MinIO-бакетов — этап 7.

  • Этап 6 — Сервисы telegram/ai/ml (отдельные процессы) + Discovery (2026-09-05-deal-stage6-services.md): gRPC-контракты в src/contracts/*.proto (общий Deal.Proto); три автономных процесса — telegram-service (:5101: ферма сессий 1 акк/тенант, QR-вход, AES-GCM-сессии /data/sessions, диалоги/мониторинг/backfill с анти-бан-паузами), ai-service (:5102: LLM-фасад OpenAI-совместимых+Anthropic, Filter/Classify/ GenerateKeywords/EvaluateFit, usage), ml-service (:5103: инкрементальный наивный Байес 1:1 с python mlservice/model.py, SQLite на тенанта); core — gRPC-ингресс telegram :5082 (PushMessage→очередь, SyncDialogs, ReportStatus→SSE), модуль Telegram (Dialogs/TgMessages) + эндпоинты /api/tg (14 шт., реальный статус, QR-SVG) вместо boot-заглушки, ai/ml-gRPC-адаптеры за флагами Services:*:UseLocal (код-дефолт Local, compose.dev.yml — false), MlOutboxFlushScheduler (10 с), модуль Discovery (воркер 5 с: поиск/ каскад оценки/авто-join с квотами и бан-гардом; /api/discovery 13 шт.); полный dev-стек — deploy/compose.dev.yml (postgres/minio/3 сервиса/core, secrets, healthcheck), smoke-скрипт scripts/dev-smoke.sh (отложенный живой прогон — Docker Desktop был выключен). Задачи 1–20 приняты: 830 unit-тестов PASS, build 0 warnings / 0 errors всех четырёх sln, curl-приёмки Task 14 (/api/tg PASS=20 FAIL=0) и Task 19 (/api/discovery PASS=37 FAIL=0), in-proc gRPC-приёмки. Ledger: .superpowers/sdd/deal-stage6-services/. Ручные проверки (с кредами): Telegram-вход (api_id/api_hash/QR) и реальные LLM-вызовы; живой smoke scripts/dev-smoke.sh — после поднятия Docker. Ограничения этапа 6 (переходят в этап 7): mTLS-сертификаты и prod-compose; лимиты/бюджеты токенов (учёт aiTokenUsage уже есть); оператор/админка/аудит-поток; rate limiting gRPC; экспорт/импорт ML-моделей; ротация/бэкап ключей сессий; reclassify на реальном ИИ (контракт-заглушка остаётся).

  • Этап 7 — SaaS-контур (Tasks 116, 2026-09-08) (2026-09-05-deal-stage7-saas.md): оператор (public-таблицы, кука deal_operator_session, bootstrap env, ручки /api/operator/* — API-only), инвайты + активация POST /api/join, лимиты ИИ-бюджета с fallback-декораторами и SSE-тостами, append-only аудит-поток, rate limiting (приложение + gRPC-ингресс + защита входа), Origin-проверка/ security-заголовки/ForwardedHeaders, mTLS за флагом DEAL_MTLS_* + scripts/mtls-certs.sh, Serilog JSON во всех 4 процессах, prod-деплой deploy/compose.prod.yml (caddy 80/443, mTLS-env, healthcheck'и grpc_health_probe, профиль observability: promtail/loki/grafana) + deploy/.env.prod.example, бэкапы scripts/backup.sh/restore.sh (+ deal-backup-lib.sh). Task 16 (финал): актуализированы техдок §5/§7–§11/§13 (фактический стек, Manual-пометки), api-map (раздел «Реализовано в Deal»), user-guide, STATUS.md (этапы 07 = 100%). Финальный прогон: core 1123/1123 PASS, telegram 114/114, ai 50/50, ml 36/36 PASS, build 0/0 всех четырёх sln, compose.prod.yml config rc=0, sh -n скриптов rc=0. Ledger: .superpowers/sdd/deal-stage7-saas/. Manual (нужен docker/живые креды): применение system-миграции + сквозная SaaS-curl-приёмка, подъём compose.prod и dev-smoke scripts/dev-smoke.sh, mTLS-рукопожатие контейнеров, реальные Telegram/LLM-вызовы, прогон scripts/backup.sh и restore-тест — чек-лист в task-16-report.md.

Эталонные конвенции (уже в коде — их придерживаться дальше)

  • Модуль = чистый проект (SharedKernel/Contracts): порты (интерфейсы) + record-DTO, без EF. Регистрация: AddTenantsModule() (модуль), адаптеры EF — в Deal.Infrastructure через AddDealPersistence() (scoped). HTTP-эндпоинты — в Deal.Api/Endpoints/* (MapXxxEndpoints).
  • Два EF-контекста: системный (public, явная схема) и tenant (бессхемный; новые таблицы модулей — DbSet в TenantDbContext + dotnet ef migrations add X --context TenantDbContext; применяются провижинером ко всем схемам). Ошибки API — {detail}; JSON camelCase; кука deal_session.
  • Константы/настройки: IOptions<T>; без магических чисел; 1 тип=1 файл; XML-doc на public.

Следующие этапы (после этапов 0–7; порядок из архитектуры §12.5)

Актуальный источник отложенного и техдолга — backlog.md в корне (роудмап черпается оттуда). Ниже — историческая секция роудмапа.

Этапы 0–7 выполнены (см. «Выполнено»). Ниже — следующие инкременты: заделы этапа 7 (сознательно вынесены, подробно — техдок §11) и пункты архитектуры, не входившие в этапы.

Этап 8+ — следующие инкременты (заделы этапа 7, подробно — техдок §11):

  • Этапы 8–10 выполнены (2026-09-10): ревью/качество; единая карточка (unified card); оператор-консоль + активация инвайта (UI) + аудит действий и аналитика расхода токенов + ELK/Loki-дашборды.
  • Остаются заделы: OTel-метрики/Prometheus и дашборды метрик (сейчас Serilog-логи → Loki); multi-instance rate-limit и бэкенд попыток входа; экспорт/импорт ML-моделей; reclassify на реальном ИИ; мультиаккаунтность Telegram; биллинг/планы; k8s/Cloudflare-конфигурация; purge-автоматика audit_log.

Этап 11 — Локализация интерфейса (i18n)

Требование владельца (2026-09-10). Весь интерфейс — на русском; все тексты вынесены в ресурсы, чтобы можно было добавлять новые языки и менять язык на лету.

  • Русский — язык по умолчанию. Все пользовательские строки UI (экраны, кнопки, подписи, пустые состояния, подсказки, подтверждения, уведомления/тосты, страницы оператора и активации) — на русском.
  • Никакого хардкода строк в компонентах. Все тексты — в словарях ресурсов (ключ → значение), включая сообщения об ошибках, которые сейчас формируются на бэке ({detail}), — они должны быть локализуемы (ключ + параметры) или переводимы по коду.
  • Переключение языка на лету, без перезагрузки страницы; выбранный язык сохраняется (localStorage/настройки).
  • Расширяемость: добавление нового языка = новый файл словаря, без правок компонентов.
  • Форматирование дат/времени/чисел/валют — через i18n-форматтеры (не вручную), плюрализация — через правила языка.
  • Ключи — стабильные, сгруппированные по областям (nav/cards/settings/operator/…); отсутствующий ключ в языке → фолбэк на русский.
  • Бэк: ответы API остаются с {detail}/кодами; фронт отображает локализованный текст по коду/ключу (при необходимости — расширяемый словарь ошибок).

UI-область, к которой это применяется: основное приложение (дашборд, «Выбранные», настройки, каналы, обработка) и оператор-консоль (этап 10).

Открытые точки согласования (накопились к концу этапа 1)

Решения владельца (2026-09-06): 1 — бренд меняем (сделано точечно: index.html, LoginView, Sidebar, DiscoveryView, SettingsView); 2 — инвайты/оператор остаются на SaaS-этап, dev-seed admin/admin; 3 — PascalCase — конвенция БД; 4 — кука deal_session остаётся; 5 — заглушки сервисов допустимы (порты с детерминированными локальными реализациями до этапов 6+); 6 — идём по roadmap все этапы.

  1. Бренд во фронте: Vue-фронт всё ещё показывает «LeadRadar» (LoginView, заголовки). Фронт «не трогаем» — но бренд теперь «Дейл». Менять ли строки бренда во фронте (точечно) или позже?
  2. Инвайты/оператор: ТЗ требует invite-only + отдельный вход оператора; во фронте такого UI нет. Оставляем dev-seed (admin/admin + дефолтный тенант) до этапа 7? Тогда auth остаётся «как прототип».
  3. Имена колонок БД: EF генерирует PascalCase (UpdatedAt), ТЗ/доки местами в SQL-нотации (snake_case). Оставляем PascalCase (конвенция кода) — подтвердить.
  4. Имя куки deal_session (прототип: leadradar_session) — фронту всё равно; ок?
  5. Сервисы ml/ai/telegram: полный ребилд — это самые крупные этапы. Подтвердить, что локально между этапами допустимы порты с детерминированными заглушками (пока сервисы не написаны), чтобы pipeline/kanban разрабатывать и показывать на синтетических входах.
  6. Приоритет и темп: продолжать строго по roadmap (Settings → Kanban → Pipeline → Projects → сервисы+Discovery → SaaS-контур) и в каком темпе/объёме на сессию.

Статус на 2026-09-08 (этапы 0–7 завершены): п.2 закрыт — инвайты/оператор реализованы в этапе 7 (API-only: /api/operator/* + /api/join), dev-seed admin/admin остаётся dev-only (Ruling 1); UI операторской админки и страницы активации — задел этапа 8+. п.1 — бренд во фронте меняется точечно (как решено); п.3–5 — зафиксированы решениями (PascalCase, deal_session, локальные реализации портов) и не пересматривались; п.6 — roadmap исполнен: этапы 0–7 пройдены (STATUS.md — 100%, Manual-чек-лист вынесен отдельно).