ci / build-test (push) Canceled after 0s
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 зелёные.
242 lines
28 KiB
Markdown
242 lines
28 KiB
Markdown
# Дейл (Deal) — Статус разработки и прогресс
|
||
|
||
> Обновляется в конце каждого захода. Проект в git (ветка `main`, коммиты на русском) — борд состояния + git-история.
|
||
> Дата последнего обновления: 2026-09-11.
|
||
>
|
||
> **2026-09-11 — единый контракт источника (generic source).** Ядро (домен Cards, Storage-сервис,
|
||
> персистентность, конвейер, wire, фронт) переведено с Telegram-полей карточки на generic-тип
|
||
> `SourceItem` (`SourceRef` + `SourceContent`, вложения — `DataRef` → общий Storage). Дашборды/канбан/конвейер
|
||
> больше не знают о Telegram; Telegram-специфика — только в тонком адаптере приёма. Tenant-миграции
|
||
> пересозданы с нуля (init). Добавлены extension-point `ISourceContentProvider`/`SourceContentResolver` и
|
||
> `GET /api/cards/{id}/source`. Входящий поток источников — generic (`sources.proto`/`PushSource`,
|
||
> `SourceIngressGrpcService`), `PushMessage` из telegram.proto удалён. Сухой прогон текста по конвейеру
|
||
> (стоп-правила → ML → ИИ) без записи: `POST /api/admin/check-message` + UI настроек. Remote-просмотр
|
||
> исходника: `TelegramService.ReadSource` + `TelegramSourceContentProvider` + UI «Обновить из источника».
|
||
> Метрика алертинга `deal.ai.budget.used.ratio{tenant}`; actor/tenant в access-логе; прогресс переклассификации
|
||
> через SSE. Hardening контейнеров (non-root/read-only/limits), шардированная пакетная миграция схем,
|
||
> единый CI (`scripts/ci.sh`). Ядро: build 5 sln 0/0, `Deal.Tests.Unit` **1326/1326 PASS**,
|
||
> telegram **130/130**, ai **52/52**, ml **38/38**, storage **9/9**, фронт `build` + `lint:i18n` зелёные.
|
||
> Детали — `docs/superpowers/specs/2026-09-11-source-contract-design.md`.
|
||
>
|
||
> **2026-09-11 (вечер) — закрыты остатки код-стайла (TD-COMMENTS-IFACE, TD-STYLE-ANALYZERS).** Дедупликация
|
||
> `<summary>`: дублей нет (сканы по тексту и по имени члена — 39 интерфейсов/229 членов). `var`: гейт
|
||
> `csharp_style_var_for_built_in_types = false:warning` (ломает сборку), остаток выправлен `dotnet format`
|
||
> по 5 sln (51 файл), «очевидный/прочий тип» — silent осознанно. Переводы строк: решено LF — `.gitattributes`
|
||
> (`* text=auto eol=lf`), `.editorconfig` → lf, нормализовано 1029 файлов; попутно починены 42 CRLF-.sh
|
||
> (первый прогон удалённого CI падал бы). Понижено 12 новых private XML-доков; добавлены 4 `<summary>`
|
||
> членам интерфейсов; переведены 3 англоязычных комментария; из индекса убраны 2 `__pycache__/*.pyc`;
|
||
> STATUS.md — удалён устаревший блок «Осталось (в backlog)» в шапке. Дочистка по контрольному скану
|
||
> краткости: удалены 73 очевидных `<param name="ct">` (пересказ сигнатуры) в 17 файлах, ужаты 3 summary
|
||
> (многосентенционные/длинные); контроль: `<remarks>` 0, inline-`<summary>` 0, многосентенционных 0, TODO 0. Явные реализации интерфейсов (§11) —
|
||
> остались точечным ревью владельца (43 интерфейса с реализациями, массовая правка не автоматизируется).
|
||
> Сборка 5 sln 0/0; тесты: core **1340/1340**, telegram **130/130**, ai **52/52**, ml **38/38**, storage **9/9** — зелёные.
|
||
> Детали — `docs/spec/Код-стайл-аудит-2026-09-11.md`, §2.
|
||
>
|
||
> **2026-09-11 (ночь) — Gitea-контур.** Репозиторий запушен (`gitea.khomegeneric.keenetic.pro/rust/Deal`),
|
||
> ~4000 спам-пользователей вычищено, регистрация закрыта владельцем. CI перенесён в
|
||
> `.gitea/workflows/ci.yml`; первый прогон поймал и закрыл кроссплатформенный баг
|
||
> (`ModelPool` валидировал tenant-id через `GetInvalidFileNameChars` — на Linux пропускал `\`);
|
||
> валидация заменена на явный белый список. **`scripts/` исключён из репозитория** (правило владельца:
|
||
> в репе только код) — скрипты сборки/тестов/бэкапов/кодмоды живут только локально; CI-workflow
|
||
> переписан inline. Раннер для CI — на сервере рядом с Gitea (пакет `deploy/gitea-runner/`).
|
||
>
|
||
> **2026-09-11 (поздний вечер) — явные реализации интерфейсов (вариант A, решение владельца).** Правило
|
||
> владельца: классы напрямую не вызываем (исключения — DTO, хелперы, экстеншены), тесты — через
|
||
> интерфейсы, моки — NSubstitute, маркерные классы не используем. Сделано: 161 член в 30 прод-файлах
|
||
> переведён на явные реализации codemod'ом `scripts/make_explicit.py`; потребители конкретных типов
|
||
> перетипизированы на интерфейсы (8 мест в проде, 17 тест-файлов; самовызовы — `((ISessionClient)this)`);
|
||
> 10 маркерных классов заменены маркерными интерфейсами (`IKanbanModule`…`ISharedKernel`); NSubstitute 6.1.0
|
||
> подключён к 5 тест-проектам, эталон миграции — `FakePasswordHasher` → `TestHashers.New()` (фейк удалён);
|
||
> правила зафиксированы в §11 код-стайла. Card/`I*Card` — implicit (DTO). Оставшиеся 30 фейков —
|
||
> поэтапная миграция (`backlog.md`, TD-TESTS-NSUBSTITUTE). Build 5 sln 0/0, тесты зелёные.
|
||
|
||
**Все этапы 0–12 выполнены (100%)** — см. roadmap
|
||
> `docs/superpowers/plans/2026-09-05-deal-roadmap.md`, план этапа 10
|
||
> `docs/superpowers/plans/2026-09-10-deal-stage10-operator-analytics.md` и ledgers в `.superpowers/sdd/`.
|
||
> Live-приёмки на Docker Desktop выполнены: dev-smoke 14/14, SaaS-контур 15/15, prod-контур+mTLS+
|
||
> observability PASS, backup/restore на копии PASS, runtime-приёмка этапа 10 (оператор-консоль,
|
||
> аналитика, аудит) PASS (см. чек-лист ниже). Осталось Manual: реальные Telegram/LLM-креды (п.5).
|
||
|
||
## Общий прогресс по этапам
|
||
|
||
| Этап | Статус | Задач | Тесты (unit, накопительно) | Приёмка |
|
||
|---|---|---|---|---|
|
||
| 0. Каркас | ✅ готов | 9/9 | 6 | health 200 |
|
||
| 1. Доступ и мультитенантность | ✅ готов | 6/6 | 25 | auth 1:1 |
|
||
| 2. Settings (настройки) | ✅ готов | 11/11 | 175 | 60/60 |
|
||
| 3. Kanban (дашборд) | ✅ готов | 15/15 | 410 | 94/94 |
|
||
| 4. Pipeline/«Обработка» | ✅ готов | 13/13 | 535 | 74/74 |
|
||
| 5. Projects («Выбранные») | ✅ готов | 13/13 | 620 | 75/75 |
|
||
| 6. Сервисы telegram/ml/ai + Discovery | ✅ готов | 20/20 | 830 | 20/20 + 37/37 |
|
||
| 7. SaaS-контур (оператор/инвайты/лимиты/аудит/безопасность/prod-деплой/бэкапы/доки) | ✅ готов | 16/16 | 1123 | ✅ live SaaS 15/15 (остальное — ⚠ Manual) |
|
||
| 8. Code-quality rework (ревью 5 зон) | ✅ готов | 5/5 фаз | 1139 | build 4 sln 0/0; фронт build OK |
|
||
| 9. Единая карточка (слияние Kanban/Projects, `/api/cards`+`/api/containers`) | ✅ готов | 11/11 | 1138 | ✅ live dev-smoke PASS=14 FAIL=0 |
|
||
| 10. Оператор-консоль, аналитика, аудит действий, Grafana/Loki-дашборды | ✅ готов | 7/7 | 1173 | ✅ live runtime (Docker dev) |
|
||
| 11. Локализация UI (вынос строк в ресурсы) | ✅ готов | 7/7 | 1173 | build + `lint:i18n` зелёные |
|
||
| 12. Наблюдаемость/устойчивость/перф + добивка ТЗ | ✅ готов | 4/4 пакетов + добивка | 1275 | build 4 sln 0/0; telegram 125/125 |
|
||
| **Итого** | **этапы 0–12 = 100%** | **137/137** | **1275 (core)** + 125/52/38 (сервисы) | — |
|
||
|
||
Финальный прогон этапа 12 (2026-09-10, автономный заход A–D): build `Deal.sln` 0/0; core **1275/1275 PASS**;
|
||
telegram **125/125**; фронт `npm run build` зелёный (main-чанк 309 kB, словарь в отдельном чанке i18n),
|
||
`npm run lint:i18n` зелёный; метрики: `/metrics` (OTel→Prometheus) во всех 4 процессах, Prometheus targets 5/5 UP;
|
||
пакеты B (rate-limit/LoginAttemptGuard на Postgres, разлогин suspended, purge) и D (reclassify + токены ML)
|
||
с зелёными тестами. Всё остановлено (правило «без хвостов»). LEDGER: `.superpowers/sdd/deal-stage12-observability-hardening/`.
|
||
|
||
Финальный прогон этапа 10 (2026-09-10): build `Deal.sln` 0/0; core **1173/1173 PASS**; фронт
|
||
`npm run build` зелёный; `GET /api/operator/analytics/{overview,tokens,activity}` и
|
||
`GET /api/operator/audit` живьём на dev-Postgres (`:5433`, миграция `AddTokenUsageEvents` применена),
|
||
`deal-core` healthy; страницы `#/operator` и `#/join` отдаются dev-сервером. Детали — ledger
|
||
`.superpowers/sdd/deal-stage10-operator-analytics/progress.md`.
|
||
|
||
Финальный прогон (Task 16, 2026-09-08, docker выключен): build 0 warnings / 0 errors всех четырёх sln
|
||
(core/telegram/ai/ml); core 1123/1123 PASS, telegram 114/114, ai 50/50, ml 36/36 PASS;
|
||
`docker compose -f deploy/compose.prod.yml config` rc=0 (+ профиль observability);
|
||
`sh -n` scripts/dev-smoke.sh/backup.sh/restore.sh/mtls-certs.sh rc=0.
|
||
> Накопительный счётчик core в таблице — по состоянию на конец этапа: этап 8 — 1139, этап 9 — 1138
|
||
> (часть тестов удалена вместе с доменом Projects), этап 10 — 1173.
|
||
|
||
## Что система умеет СЕЙЧАС (проверяемо)
|
||
|
||
- **Ядро (этапы 0–6)**: вход admin/admin (dev-seed, dev-only), сессии, схемы на тенанта (Postgres :5433);
|
||
дашборд (колонки/карточки/drag&drop/архив/корзина/FTS-поиск), «Обработка»
|
||
(очередь→стоп-лист→дедуп→ML/ИИ→карточка), «Выбранные» (стадии/напоминания SSE/файлы Local/MinIO),
|
||
Настройки (ключи AI enc:, промпты, валюты; Telegram-ключи — глобально у оператора), Каналы/Discovery; полный dev-стек этапа 6 —
|
||
`deploy/compose.dev.yml` (`Services__*__UseLocal=false`, gRPC-режим telegram/ai/ml + ингресс core).
|
||
- **SaaS-контур (этап 7)**: оператор (`public.operators/operator_sessions`, кука `deal_operator_session`,
|
||
bootstrap env `DEAL_OPERATOR_*`; dev-дефолт operator/operator) и ручки `/api/operator/*`
|
||
(auth/tenants/invites/limits/audit/health — с этапа 10 у них есть UI, см. ниже); инвайты (код 16 симв., 72 ч) и активация
|
||
`POST /api/join` (пользователь + провижининг тенанта); лимиты ИИ-бюджета (`tenant_limits`,
|
||
`TokenUsageRecorder`, гейт-декораторы → Local-фолбэк, SSE-тосты 80/100%); append-only аудит;
|
||
rate limiting (auth 10/мин·IP, api 600/мин·тенант, gRPC-ингресс 600/мин·тенант, `LoginAttemptGuard`
|
||
5/15 мин); Origin-проверка мутаций + security-заголовки + ForwardedHeaders за Caddy;
|
||
mTLS за флагом `DEAL_MTLS_*` (`scripts/mtls-certs.sh` → `deploy/certs/`); Serilog JSON во всех
|
||
4 процессах (+ access-логи HTTP/gRPC); prod-деплой `deploy/compose.prod.yml` (caddy 80/443,
|
||
postgres/minio без host-портов, профиль observability: promtail/loki/grafana, `.env.prod.example`);
|
||
бэкапы `scripts/backup.sh`/`restore.sh`/`deal-backup-lib.sh` (pg_dump -Fc + MinIO + tar; retention 14).
|
||
- **Оператор-консоль и аналитика (этап 10)**: hash-роутер фронта (`#/` приложение, `#/operator` консоль,
|
||
`#/join?code=…` активация инвайта); разделы консоли (вход, тенанты+suspend/resume/impersonate,
|
||
инвайты, лимиты, аудит с фильтрами/пагинацией, аналитика, health); impersonation ставит httpOnly-куку
|
||
`deal_session` тем же ответом (оператор сразу в тенанте). Сквозной аудит действий (`public.audit_log`):
|
||
выходы, `invite_joined`, действия карточек/комментариев, CRUD контейнеров, настройки, каналы, Telegram.
|
||
История расхода токенов `public.token_usage_events` + операторская аналитика
|
||
(`/api/operator/analytics/{overview,tokens,activity}`, `groupBy=day|tenant|provider|model`).
|
||
Grafana provisioning (datasource Loki + дашборды `Deal-Auth/Errors/Rps/Logs`) и promtail-лейблы.
|
||
- **Что увидеть глазами**: полный dev-стек — `docker compose -f deploy/compose.dev.yml up -d --build`
|
||
→ фронт `cd src/frontend && npm run dev` → логин `admin/admin` (dev-seed);
|
||
либо сквозной smoke одной командой: `sh scripts/dev-smoke.sh`. Prod-контур — §13.8 техдока
|
||
(оператор → тенант → инвайт → `/api/join`). Host-режим (Local-заглушки): postgres/minio +
|
||
`dotnet run --project src/core/Deal.Api --urls http://localhost:5080`.
|
||
- Полная карта «что/где» — техдок `docs/technical/Техническая-документация-Дейл.md` (§5, §7–§11,
|
||
§13.1–§13.10), api-map `docs/api/api-map.md` (раздел «Реализовано в Deal»), инструкция пользователя
|
||
`docs/user-guide/Инструкция-пользователя-Дейл.md`.
|
||
|
||
## Manual-чек-лист (остаток после live-приёмок)
|
||
|
||
Выполнено живьём на Docker (автономно от авто-прогонов Task 16, build/test/config/syntax — там же):
|
||
|
||
1. ✅ **SaaS-сквозная приёмка (live, 15/15 PASS)** — `run-live-saas.sh` + `live-saas-check.sh` на поднятом
|
||
dev-Postgres (:5433, миграции SystemSaaS + SessionsImpersonationMark применены): оператор login →
|
||
создать тенанта → инвайт → `POST /api/join` → вход пользователя → settings/cards (на тот момент —
|
||
`boards`/демо-карточка) →
|
||
IDOR-негатив 401 (пользователь к операторским ручкам) → suspend (вход 403) → resume (вход 200) →
|
||
лимиты (tenant_limits) → аудит-лента. Core погашен, :5080 свободен.
|
||
2. ✅ **dev-smoke 14/14 PASS** — полный gRPC-стек (`scripts/dev-smoke.sh`): подъём, health, login
|
||
admin/admin, `/api/tg/status` idle, `POST /api/cards` (карточка `planned`) → trash → обучающий сигнал spam,
|
||
ML-флашер выгрузил outbox. Стек погашен скриптом (trap).
|
||
3. ✅ **Prod-контур + mTLS + observability (live)** — сертификаты перегенерированы (`scripts/mtls-certs.sh -f`,)
|
||
полный набор в deploy/certs; подъём `compose.prod.yml` + `--profile observability` с фиктивными
|
||
env-секретами (`DEAL_MTLS_ENABLED=1`, endpoint'ы https://): core/telegram/ai/ml **healthy** под mTLS;
|
||
исходящее mTLS подтверждено живьём — `/api/tg/status` (idle) и `/api/ml/status` (reachable:true) через
|
||
Caddy; фронт и `/api/health` через Caddy 200; promtail→loki (логи пишутся), Grafana 200. Исправлен
|
||
дефект `deploy/observability/loki.yml` (Loki 3.x: `delete_request_store`). `.env.prod` тестовый удалён.
|
||
4. ✅ **backup/restore (live, на копии)** — `backup.sh`: pg (-Fc) + minio (docker-mc) + data (tar docker-томов)
|
||
+ retention; `restore.sh pg` в копию-БД — 43 таблицы/3 схемы идентичны, данные сошлись (users=2,
|
||
tenants=2, sessions=30); `restore.sh minio` с реальным объектом (залит→бэкап→удалён→восстановлен);
|
||
`restore.sh data`. Исправлены дефекты скриптов, проявившиеся живьём: двойная схема в MC_HOST_deal
|
||
(`deal-backup-lib.sh`), пустой бакет → mv (`backup.sh`), Windows/MSYS docker-пути (`host_docker_path`).
|
||
5. ❌ Реальный Telegram-вход (api_id/api_hash/QR) и LLM-вызовы — **нужны живые креды**.
|
||
6. ✅ Прогон `scripts/backup.sh` и restore-тест — см. п.4 (полный цикл на dev-хранилищах и копии-БД).
|
||
7. ✅ **Этап 10 — runtime-приёмка (Docker dev-стек)** — миграция `AddTokenUsageEvents` применена к
|
||
dev-Postgres (`:5433`), `deal-core` пересобран/healthy; операторский вход `operator`/`operator` → 200;
|
||
`GET /api/operator/tenants`, `/audit`, `/analytics/overview`, `/analytics/tokens?groupBy=day|provider`,
|
||
`/analytics/activity?limit=3` → 200 (реальные лента/агрегаты); фронт `npm run build` зелёный, dev-сервер
|
||
отдаёт `#/operator` и `#/join`; core-тесты 1173/1173. Детали — ledger этапа 10.
|
||
|
||
## Заделы (этап 13+; подробно — техдок §11 и roadmap)
|
||
|
||
> **Единый источник отложенного и техдолга — `docs/superpowers/backlog.md`.** Ниже — краткая выжимка.
|
||
|
||
- **Этап 11 — Локализация интерфейса (i18n)** — **выполнен** (2026-09-10, урезанный объём): все
|
||
пользовательские строки фронта в ресурсах (`src/frontend/src/i18n/`, 1039 ключей в 13 областях),
|
||
линтер `npm run lint:i18n`. Переключатель языка и второй язык — **в бэклоге**: делаем, когда появится
|
||
потребность (ядро i18n/`registerLocale` к этому готово).
|
||
- **Этап 12 — Наблюдаемость/устойчивость/перф** — **выполнен** (2026-09-10, автономно, пакеты A–D):
|
||
метрики Prometheus+Grafana (`/metrics` :9464 во всех процессах); распределённый rate-limit и
|
||
`LoginAttemptGuard` на Postgres; мгновенный разлогин suspended-сессий; авто-purge `audit_log`/`tenant_limits`;
|
||
разбиение бандла фронта + прогрессивный рендер колонок; LRU-кэши WTelegram; пакетная миграция схем тенантов;
|
||
реальный `reclassify` с Local-фолбэком. LEDGER: `.superpowers/sdd/deal-stage12-observability-hardening/`.
|
||
- **Остатки этапа 12 (закрыто 2026-09-10):** доки под этап 12 (real-reclassify, maintenance-migrate, без
|
||
демо), Prometheus alert rules (`deploy/observability/prometheus-rules.yml` + провижининг), устранена гонка
|
||
`FreeTcpPort()` в тест-харнессе (единый `TestPort`), SSE `cards_reclassified` (бэк+фронт), нагрузочные
|
||
скрипты `scripts/loadtest/`, скан уязвимостей — **чисто** (core: 0 уязвимых пакетов; frontend `npm audit`: 0).
|
||
- Прочее (требует владельца/кредов): биллинг/провайдер планов и саморегистрация; мультиаккаунтность Telegram;
|
||
k8s/Cloudflare; Kafka; экспорт/импорт ML; переключатель языка/второй язык (в бэклоге — по потребности);
|
||
реальный Telegram-вход и живые LLM-вызовы;
|
||
legacy-прототип `docker-compose.yml` перенесён в `archive/leadradar-legacy/` (2026-09-10).
|
||
- **Добивка по ТЗ (2026-09-10, автономно)** — закрыты найденные аудитом частично/незакрытые пункты:
|
||
ML-проверка на канале/сообщении (`/api/ml/candidates`+`/apply` — реальные, не заглушки); глобальные
|
||
исключения до ML/ИИ (§5.14); новые группы фильтров колонки `levels/locations/types/prices` (§6.3);
|
||
«открыть исходник» как быстрое действие на карточке (§6.6); глубины очередей/сессии в `/api/operator/health` (§10.2);
|
||
детектор подозрительной активности `/api/operator/analytics/suspicious` (§10.5); раздел настроек и
|
||
поддержка тем «Внешний вид» — тёмная (дефолт) / светлая / системная (§8.12). Отчёт аудита:
|
||
`docs/superpowers/reviews/2026-09-10-tz-compliance-audit.md`. Core-тесты **1275/1275**; фронт build+`lint:i18n` зелёные.
|
||
- **Telegram-ключи — вариант A (2026-09-10, по решению владельца):** `api_id`/`api_hash` задаёт
|
||
**оператор глобально** (таблица `public.global_settings`, ручки `GET/PUT /api/operator/settings/telegram-keys`,
|
||
hash шифруется; раздел «Telegram» в оператор-консоли). У тенанта ключи убраны — только подключение
|
||
аккаунта; без ключей подключение недоступно (`/api/tg/status → keysSet:false`). Миграция `GlobalSettings`
|
||
**применена**; `PUT` поддерживает частичное обновление (можно сменить одно поле). Core-тесты **1275/1275**.
|
||
|
||
## Code-quality rework (2026-09-08, после ревью 5 зон ~1100 файлов)
|
||
|
||
Проведено многоосевое ревью (безопасность/корректность/архитектура/перф) бэкенда и фронта; findings —
|
||
`docs/superpowers/reviews/2026-09-08-code-quality-review.md`. Все исправления закрыты и проверены:
|
||
**core 1135/1135, telegram 118/118, ai 52/52, ml 38/38**, фронт build OK, 4 sln 0/0. Главное:
|
||
|
||
- **Безопасность**: SSRF-гейт (baseUrl каталоговых провайдеров фиксирован + private-IP-блок в проверке),
|
||
fail-closed Production (rate limit/CORS/conn-string обязательны), код инвайта в аудите — SHA-256, пароль ≥8,
|
||
маска ключа не перезаписывает ключ и короткие секреты скрыты, TenantId = 32-hex, mTLS fail-closed,
|
||
gRPC-лимиты входных данных, join проверяет целевого тенанта, атомарный инкремент токенов (Npgsql).
|
||
- **Корректность**: атомарные append комментариев/ссылок/файлов (1 SQL), уникальный objectKey, атомарный
|
||
дедуп-pump, запрет move из trash/archive/taken, логирование «немых» catch, очистка сессий вне hot-path;
|
||
фронт: смена пароля с текущим паролем, boot не падает от одного 500, автосейв не затирает промпты,
|
||
гонки поиска закрыты seq-токенами.
|
||
- **Архитектура**: `Deal.Grpc.Hosting` (общая обвязка 3 сервисов), `TenantSettingsSnapshot` (9 копий чтения
|
||
настроек → одна), декомпозиция 7 крупных файлов на partial (<350 строк), фронт store.js → слайсы `store/`,
|
||
вынесены компоненты Settings/Discovery; мёртвый код удалён.
|
||
- **Реестры констант (C35, 2026-09-09)**: общие `Deal.Contracts.Integrations.MlLearningLabels`
|
||
(spam/t:hire/t:order) и `SourceDefaults` (DefaultHue) вместо дублей в 5 модулях; единый предикат «активные
|
||
правила» (Kanban `ColumnRules.HasActiveRules`); реестр id-стадий `ProjectStages` (с этапа 9 — `CardsDefaultContainers`); общий
|
||
`CardsService.JustNowLabel`; TTL-эвикция в DiscoverySearchErrorCounter (+4 теста, core 1139).
|
||
- **Заделы** (не рисковали без e2e/не успели): вынос оставшихся вкладок SettingsView, Optional-пункты
|
||
(пагинация колонок, виртуализация, LRU-кэши WTelegram и др.). Подробности — в отчёте ревью и
|
||
`.superpowers/sdd/deal-stage8-quality-rework/`.
|
||
|
||
## Процесс (обязательства, чтобы не жрать память/хосты)
|
||
|
||
- Acceptance-серверы — только через враппер с гарантированным kill (taskkill //T //F по PID-файлу) +
|
||
проверка освобождения порта; в конце каждой приёмки — шаг очистки.
|
||
- Контейнеры — по требованию (`docker compose ... up|down`); между заходами ничего не держать;
|
||
`scripts/cleanup-dev.sh` (kill висящих Deal.*/тест-хостов, `dotnet build-server shutdown`,
|
||
остановка deal-контейнеров) — в конце захода.
|
||
- **Хвостов не оставлять (правило владельца, 2026-09-10):** по завершении работы все сервисы и процессы
|
||
должны быть остановлены — включая Docker-контейнеры и dev-серверы (frontend/Vite, dotnet) — если
|
||
владелец явно не попросил оставить их запущенными. Проверка в конце: `docker ps` без `deal-*`,
|
||
свободные порты (5173/5080/5082/5101/5102/5103/5433/9000/9001/9464), `dotnet build-server shutdown`.
|
||
- **Разовые решения — одним списком в начале (правило владельца, 2026-09-10):** все вопросы, требующие
|
||
выбора владельца, собираются и задаются **сразу, до начала работы**, а не по ходу/в конце. **Не
|
||
спрашивать о том, что уже определено ТЗ/принятыми решениями** — это делать без вопросов; вопрос —
|
||
только при реальном противоречии в требованиях. При неоднозначности без противоречий — выбирать
|
||
безопасный обратимый дефолт и делать (напр. перенос, а не удаление).
|
||
- **Легаси-прототип LeadRadar** перенесён из корня в `archive/leadradar-legacy/` (2026-09-10; обратимо,
|
||
на сборку/запуск не влияет).
|