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 зелёные.
18 KiB
18 KiB
Бэклог (техдолг и отложенные задачи) — «Дейл»
Назначение: единый источник отложенного/запланированного. Роудмап черпается отсюда. Статусы: BACKLOG (сделаем при потребности), DEFERRED (отложено осознанно, вне текущих рамок), MANUAL (нужны внешние условия: креды, хост, прод), TECHDEBT (качество/архитектура). Приоритет: P1 (важно), P2 (полезно), P3 (когда-нибудь). Обновлять при каждом заходе; выполненные пункты переносить в
docs/superpowers/STATUS.mdи вычёркивать здесь.
1. Продуктовые фичи (по потребности)
| ID | Пункт | Источник | Приоритет | Статус |
|---|---|---|---|---|
| BL-I18N | Переключатель языка в UI + второй язык (en) + locale-aware форматирование (Intl), плюрализация. Основа (вынос строк в ресурсы, registerLocale) готова |
ТЗ §11, этап 11 | P3 | BACKLOG |
| BL-TG-MULTI | Мультиаккаунтность Telegram (сейчас 1 аккаунт на тенант) | ТЗ §12 | P2 | DEFERRED |
| BL-ML-EXP | Экспорт/импорт ML-моделей (перенос «мозгов» между инстансами) | обсуждение этапа 12 | P3 | DEFERRED (решено не делать; вернуться при SaaS-масштабе) |
| BL-RECLASS-SSE | Сделано (2026-09-11): пакетная переклассификация отдаёт промежуточный прогресс через SSE cards_reclassified ({progress:true,done,total,moved,kept,trashed,skipped}) и финальное событие ({progress:false,reclassified,moved}); CardReclassifier.ReclassifyInboxAsync принимает IProgress<ReclassifyProgressDto>; в UI — индикатор done/total в шапке «Неразобранного» |
этап 12, D | P3 | DONE |
| TD-CARD-MERGE | Полное слияние внутренних DTO карточки в единый CardDto. Решение (2026-09-11): DEFERRED. Наружный контракт единый; внутренние DTO (read/write/DB/patch) намеренно разделены по слоям, слияние — риск без пользы |
этап 9/11 | P3 | DEFERRED |
| TD-PROTO-COMMENTS | Сделано (2026-09-11): из комментариев убраны ссылки на процесс/прототип (Task/Ruling/этап/python L…/main.py/прототип/LEADRADAR_*), удалены блоки <remarks>, <summary> сжаты до короткой фразы; //-комментарии со ссылками удалены, в .proto — тоже. Строк комментариев 27 210 → ~19 100 |
запрос владельца 2026-09-11 | P2 | DONE |
| TD-COMMENTS-IFACE | Привести код к правилам код-стайла (docs/spec/Код-стайл-Дейл.md). Сделано (2026-09-11): (1) <summary> только блочно — 5286 шт.; (2) приватные XML-доки понижены — 2028+12; (3) дедупликация <summary>→<inheritdoc/> — дублей нет (сканы); (4) явные реализации интерфейсов — сделано (2026-09-11, вечер, вариант A): 161 член в 30 прод-файлах конвертирован codemod'ом scripts/make_explicit.py, потребители перетипизированы на интерфейсы (8 мест в проде, 17 тест-файлов), Card/ICard-семейство оставлено implicit как DTO; попутно маркерные классы заменены маркерными интерфейсами. Детали — docs/spec/Код-стайл-аудит-2026-09-11.md |
запрос владельца 2026-09-11 | P2 | DONE |
| TD-TESTS-NSUBSTITUTE | Миграция тестовых фейков на NSubstitute (решение владельца 2026-09-11: моки — через NSubstitute, новых фейк-классов не заводить). Сделано (2026-09-11): NSubstitute 6.1.0 подключён к 5 тест-проектам; эталон миграции — FakePasswordHasher → хелпер TestHashers.New() (NSubstitute, детерминированная семантика сохранена), фейк удалён. Осталось (по размеру): FakeDiscoveryPacer (1 файл), FakeRatesListener (2), FakeTenantProvisioner (5), FakeSecretCipher (8), FakeAiTools (4), FakeRatesSource (1), FakeGlobalSettingsStore (4), FakeTenantRegistry/FakeTenantRepository (3+7), FakeAiClassifier (5), FakeSettingsStore (42), FakeRateLimitCounterStore (5), FakeAuditLogStore (13), FakeTenantStore (10), FakeMlLearningStore (5), FakeMlClient (17), FakeOperatorAuthStore (14), FakeInviteStore (7), FakeFileStorage (9), FakeTokenUsageEventStore (10), FakeAuthStore (15), Recording*/Harness* (gRPC-харнессы — оставить как хелперы), крупные stateful: FakeTelegramGateway (5), FakeDiscoveryGateway (2), FakeTelegramStore (7), FakeTenantLimitStore (15), FakePipelineStore (12), FakeDiscoveryStore (7), FakeKanjStore (21). Для каждого: заменить подставку на Substitute.For<>() + Returns, семантику состояния воспроизвести в конфигурации, тесты перетипизировать на интерфейс |
решение владельца 2026-09-11 | P2 | BACKLOG |
| TD-STYLE-ANALYZERS | Остаток мягких правил код-стайла. Закрыто (2026-09-11): (1) var — включён ломающий сборку гейт только для встроенных типов (csharp_style_var_for_built_in_types = false:warning), остаток выправлен dotnet format style --diagnostics IDE0008 по 5 sln; режимы «очевидный/прочий тип» — silent осознанно (~1600 субъективных замен); (2) дедупликация <summary> — дублей нет (см. TD-COMMENTS-IFACE); (3) переводы строк — решено: LF (.gitattributes * text=auto eol=lf, .editorconfig → lf, 1029 файлов нормализовано, git add --renormalize; попутно починены 42 CRLF-.sh — до этого первый прогон удалённого CI падал бы). this. и именование приватных полей уже закрыты в .editorconfig |
аудит 2026-09-11 | P3 | DONE |
2. Инфраструктура и эксплуатация
| ID | Пункт | Источник | Приоритет | Статус |
|---|---|---|---|---|
| BL-K8S | Kubernetes-манифесты (сейчас docker-compose; k8s — при масштабировании) | ТЗ §11/§12, R6 | P3 | DEFERRED |
| BL-KAFKA | Kafka как шина данных между сервисами (сейчас gRPC + БД-outbox) | ТЗ §12, обсуждение | P3 | DEFERRED |
| BL-CF | Cloudflare / внешний периметр (сейчас Caddy, mTLS; конфиг вне кода) | ТЗ §11, техдок §10 | P2 | MANUAL |
| BL-CI | Сделано (2026-09-11): scripts/ci.sh — сборка всех 5 решений, тесты всех сервисов, скан уязвимых NuGet-зависимостей (dotnet list package --vulnerable --include-transitive), сборка+линтер фронта; build.sh/test.sh расширены на все решения/сервисы; .github/workflows/ci.yml. Первый прогон в удалённом CI — при публикации репозитория |
техдок §8 | P2 | DONE (remote — MANUAL) |
| BL-IMG-HARDEN | Сделано (2026-09-11): non-root USER (deal, UID 10001, HOME=/tmp) во всех прикладных образах; в compose — read_only root FS + tmpfs /tmp, no-new-privileges, cap_drop ALL, mem_limit/cpus; логи stateless-сервисов в /tmp/logs. Проверено compose config (dev/prod/observability); живой прогон — MANUAL |
техдок §10 | P2 | DONE (live — MANUAL) |
| BL-BACKUP-CRON | Автоматизация бэкапов (cron/systemd-примеры есть, реальный прогон — MANUAL) | техдок §9 | P2 | MANUAL |
3. SaaS / мультитенантность
| ID | Пункт | Источник | Приоритет | Статус |
|---|---|---|---|---|
| BL-BILLING | Биллинг и тарифные планы, провайдер платежей | ТЗ §12 | P3 | DEFERRED |
| BL-SIGNUP | Саморегистрация тенантов (сейчас инвайты/оператор) | ТЗ §12 | P3 | DEFERRED |
| BL-SCALE-1000 | Механизм миграций/провижининга на 1000+ схем. Сделано (2026-09-11): пакетная миграция шардирована — ITenantRepository.ListPageAsync + обход страницами в TenantSchemaMigrationService (параллелизм внутри страницы, DefaultPageSize=200, границы 1..32 / 1..5000), сбои изолированы. Осталось при росте: вынести параллелизм/размер в конфиг и кэш прогресса (при необходимости) |
roadmap этап 0, этап 12 | P2 | DONE |
4. Безопасность и наблюдаемость (доработки)
| ID | Пункт | Источник | Приоритет | Статус |
|---|---|---|---|---|
| BL-ALERT-BUDGET | Сделано (2026-09-11): метрика deal.ai.budget.used.ratio{tenant} (доля израсходованного ИИ-бюджета периода, 0..1) в DealMetrics + сбор в RuntimeDepthsCollector/DealMetricsCollector; на её основе оператор настраивает алерт в Prometheus/Grafana |
этап 12, A | P2 | DONE |
| BL-LOG-ACTOR | Сделано (2026-09-11): access-лог HTTP core (HttpAccessLogMiddleware) включает actor (login пользователя тенанта либо оператора) и tenant (id тенанта) — их берут из HttpContext.Items (Session/OperatorSession middleware) |
этап 12, T6 | P3 | DONE |
| BL-GRACEFUL | Дополнительные проверки устойчивости/ретраев (по результатам нагрузочного прогона) | этап 12, C | P2 | BACKLOG |
| BL-SUSPICIOUS | Сделано (2026-09-11): детектор SuspiciousActivityService расширен правилом distinct_logins_per_ip (перебор разных логинов с одного IP, порог DistinctLoginsPerIpThreshold); плюс real-time SuspiciousActivityReporter — метрика deal.security.suspicious{kind} + warn-лог на 429 rate limiter (rate_limit) и блокировке входа (login_blocked) |
ТЗ §10.5, этап 12 | P3 | DONE |
5. Технический долг (качество/архитектура)
| ID | Пункт | Источник | Приоритет | Статус |
|---|---|---|---|---|
| TD-SETTINGS-UI | Вынос вкладок SettingsView в компоненты. Сделано (2026-09-11): SettingsView.vue — только набор вкладок/QR-опрос, все 10 вкладок — отдельные компоненты (components/settings/*) |
ревью 2026-09-08 | P3 | DONE |
| TD-VIRT | Полная виртуализация длинных колонок. Решение (2026-09-11): DEFERRED — прогрессивный рендер «Показать ещё» покрывает текущие объёмы; виртуализация — при росте списков | ревью, этап 12 | P3 | DEFERRED |
| TD-SSE-DEAD | Сделано (2026-09-11): мёртвые SSE-ветки фронта boards_changed/pipeline_stats удалены из store/lifecycle.js (core их не публикует) |
этап 12, E | P3 | DONE |
| TD-DBL-CLICK | Сделано (2026-09-11): перезагрузка доски при batch-переклассификации коалесцируется scheduleBoardReload() (ответ + SSE → один запрос) |
этап 12, E | P3 | DONE |
| TD-TEST-HARNESS | Историческая гонка FreeTcpPort — устранена; следить за новыми хост-хелперами |
этап 12, E | P3 | TECHDEBT |
| TD-OLD-DOCS | Исторические доки несут старые термины под пометками. Проверено (2026-09-11): docs/superpowers/plans/* и старые docs/architecture/2026-09-0* имеют шапку «Исторический документ»; переписывать не нужно |
docs sweep | P3 | DONE |
| TD-SOURCE-PROVIDER | Провайдеры содержимого источников. Сделано (2026-09-11): TelegramSourceContentProvider + ReadSource RPC + GET /api/cards/{id}/source + UI «Обновить из источника». Осталось: провайдеры прочих источников по мере появления |
generic source 2026-09-11 | P2 | TECHDEBT |
| TD-STORE-ATTACH | Выгрузка вложений источника в Storage-сервис адаптером. Решение (2026-09-11): медиа-посты Telegram пропускаем — извлечение/выгрузка не делаются; вложений у прочих источников пока нет — DEFERRED (контракт DataRef готов, включается при появлении такого источника) |
generic source 2026-09-11 | P3 | DEFERRED |
| TD-TG-CORE-SPLIT | Перенос оставшейся Telegram-специфики ядра в telegram-сервис. Закрыто (2026-09-11): не требуется. Задача «дашборды/карточки не знают о Telegram» решена generic-контрактом источника; оставшиеся TelegramStore/Dialogs/TgMessages/Discovery — это состояние тенанта (ядро — владелец данных, telegram-service — stateless-шлюз), перенос отдал бы шлюзу доступ к схеме тенанта |
generic source 2026-09-11 | — | CLOSED |
| TD-SOURCE-CONTACTS | Квалификатор контактов знает форматы профилей (t.me/@handle). Решение (2026-09-11): DEFERRED — форматы стабильны, расширяемость под источник добавляется при конкретной потребности |
generic source 2026-09-11 | P3 | DEFERRED |
| TD-APIMAP-COUNT | Ручной подсчёт числа ручек в api-map. Сделано (2026-09-11): сверил счётчики §3.1–§3.8 с фактическими строками (рассинхрон §3.5 — 14→15 из-за GET /cards/{id}/source); в §3 добавлено правило обновлять счётчики |
docs sweep | P3 | DONE |
6. Manual-проверки (нужны внешние условия)
| ID | Пункт | Источник | Приоритет | Статус |
|---|---|---|---|---|
| MN-E2E-TG | Реальный Telegram-вход (QR) + приём сообщений, backfill, «Перечитать каналы» | ТЗ §4, STATUS | P1 | MANUAL (креды/аккаунт) |
| MN-E2E-LLM | Живые LLM-вызовы (классификация/фильтр/reclassify/расход токенов) | ТЗ §8–9 | P1 | MANUAL (LLM-ключ) |
| MN-PROD | Прод-развёртывание (хост/домен, Caddy+mTLS, observability-профиль) | техдок §13.8 | P2 | MANUAL (данные хоста) |
| MN-GRAFANA | Живая проверка Grafana-дашбордов метрик/алертов и логов | этап 12, A/T6 | P2 | MANUAL |
| MN-LOADTEST | Живой нагрузочный прогон (scripts/loadtest/) и baseline |
этап 12, C | P2 | MANUAL |
| MN-BACKUP | Живой прогон backup.sh/restore на реальных данных |
техдок §9 | P2 | MANUAL |
| MN-THEME | Визуальная приёмка светлой темы в браузере | этап 12, «Внешний вид» | P3 | MANUAL |
7. Отложено/решено «не делать» (для истории)
| ID | Пункт | Решение |
|---|---|---|
| DEC-DEMO | Демо-эндпоинты (DEAL_DEMO, simulate-lead) |
Удалены (этап 9/12) |
| DEC-LEGACY | Легаси-прототип LeadRadar (backend/, mlservice/, корневой compose) |
Перенесён в archive/leadradar-legacy/ (2026-09-10); 2026-09-11 убран и из репозитория — лежит только локально |
| DEC-ML-EXP | Экспорт/импорт ML | Отложено владельцем (перенесено в BL-ML-EXP) |
Как пользоваться
- Для нового захода: выбрать пункты по приоритету/теме, оформить SDD-план в
docs/superpowers/plans/и ledger.superpowers/sdd/<этап>/, после приёмки — перенести факт вdocs/superpowers/STATUS.md, а пункт здесь пометить выполненным/удалить. - Открытые пункты (BACKLOG/MANUAL) зеркалятся задачами в Gitea (
rust/Deal, метки P1/P2/P3/manual/techdebt); при закрытии пункта закрывать задачу и наоборот. - Пункты
MANUALне блокируют разработку; выполняются, когда владелец даёт креды/хост.