diff --git a/cspell-words.txt b/cspell-words.txt index 73e992e4..758918af 100644 --- a/cspell-words.txt +++ b/cspell-words.txt @@ -884,3 +884,5 @@ LLM внутрипараграфный внутрипараграфные скилов +oxc +консты diff --git a/docs/Открытые_вопросы_v8_3.md b/docs/Открытые_вопросы_v8_3.md index 93539333..9ca86de7 100644 --- a/docs/Открытые_вопросы_v8_3.md +++ b/docs/Открытые_вопросы_v8_3.md @@ -2,7 +2,39 @@ **Назначение:** единый рабочий список вопросов, требующих решения заказчика для разблокировки разработки. Разбит по адресатам, внутри — по приоритету. -**Версия:** 1.76 от 09.05.2026 — **Post-MVP: AdminTenantDetailView epic закрыт** (2 этапа / 2 коммита `f9d8926..cab1f87`). Backend `GET /api/admin/tenants/{subdomain}` с 4 секциями (users/projects/balance_history/activity) + computed metrics; frontend AdminTenantDetailView переписан с mock на real API. **Pest 416/416 (1388 assertions) + Vitest 416/416 + Histoire 21/28 зелёные**. +**Версия:** 1.77 от 10.05.2026 — **Sprint 4 «Audit tail» закрыт** (5 коммитов `f77c91d..b912724`). Закрыты 3 audit O-* пункта: O-perf-04 (keyset pagination в `DealController::index` + 3 Pest-теста), O-refactor-04 хвост (8 Vue-компонентов >300 строк разделены на shell + sub-components; AppLayout R0.6 hard-стоп снят явным запросом заказчика), O-refactor-06 (rollup-plugin-visualizer + knip + cleanup ~165 строк dead-code в composables/). Регрессия зелёная: **Pest 421 / Vitest 416 / Larastan 0 / vue-tsc 0 / ESLint 0 / build OK 1.02 сек**. Также Sprint 0 push выполнен (21 коммит на origin/main). Roadmap до production написан: [docs/superpowers/specs/2026-05-10-roadmap-to-production-design.md](superpowers/specs/2026-05-10-roadmap-to-production-design.md) (3-track A/B/C, 9 sprint'ов: Sprint 0 push + Track A 4-6 не зависят от Б-1 + Track B 7-9 после Б-1 + Track C external). + +**Что изменилось в v1.77 относительно v1.76:** + +- **Sprint 4 «Audit tail»** (5 фаз / 5 коммитов, ~1 час wall-clock через mix inline + 3 subagent-делегации): + + - **Phase A (backend keyset)** `f77c91d` — `DealController::index` получил опциональный `cursor` query-параметр (base64-encoded JSON `{r:received_at, i:id}`). При cursor — keyset через PG row constructor `(received_at, id) < (?, ?)` с использованием существующего индекса `(received_at DESC, id DESC)`. O(1) на любой глубине, без COUNT(*). Без cursor — backward-compat OFFSET-путь (total + offset для существующего frontend). Оба режима возвращают `next_cursor` (NULL = последняя страница). 3 новых Pest-теста (keyset-навигация, 422 на невалидный cursor, next_cursor flow). Pest +3 от 418 → **421**. Frontend integration не делалась (OFFSET путь жив, не блокирует deploy). + + - **Phase B/1 (3 admin/layout views)** `30ef61d` — AdminTenantsView 377→155 (+TenantsStatsHeader 82 / TenantsFilters 93 / TenantsTable 116), AdminTenantDetailView 436→109 (+TenantDetailHeader 158 / TenantDetailTabs 176 + adminTenantDetailFormatters 43 composable), **AppLayout 466→78** (+AppSidebar 155 / AppTopbar 269; R0.6 layouts hard-стоп снят явным заказчиком в начале сессии). Паттерн: state в parent ради `defineExpose`-контракта Vitest, sub-components читают Pinia stores напрямую (auth/notifications/reminders) — без prop-drilling. + + - **Phase B/2 (3 user views)** `849bc73` — BillingView 416→114 (+BalanceCard 155 / TransactionsTable 113 / InvoicesTable 90 / billingFormatters 51), SecurityTab 354→39 (+ChangePasswordCard 17 / TwoFactorCard 218 / RecoveryCodesCard 104 / SessionsTable 66), RemindersView 345→183 (+RemindersFilters 51 / RemindersList 173). TopupDialog/ReminderForm не созданы — TopupDialog был заглушкой в исходнике (создание = new feature, не split), ReminderForm уже существовал как `ReminderDialog`. + + - **Phase B/3 (2 utility views)** `79ff60f` — ErrorView 320→178 (+ErrorBrand 54 / ErrorIllustration 31 / ErrorActions 55 / ErrorMeta 102), DashboardView 302→84 (+DashboardPageHead 65 / DashboardKpiRow 97 / DashboardBalance 124). DashboardRecentDeals не создан — секция отсутствует в текущем DashboardView (есть KPI-row + ActivityChart/FunnelChart). + + - **Phase C (dead-code)** `b912724` — установлены `rollup-plugin-visualizer ^7.0.1` + `cross-env ^10.1.0` + `knip ^6.12.2`. Vite-plugin visualizer условный (`BUILD_ANALYZE=1`), `npm run build:analyze` script. Knip упал на Windows quirk «oxc-parser ArrayBuffer fail» — конфиг оставлен для CI (Linux). Ручной grep по composables/ нашёл и удалил dead exports: `mockReports.ts:MOCK_JOBS` (62 стр) + `QuotaInfo`/`MOCK_QUOTA`, `reportsMapper.ts:reportTypes`, `mockTenantDetail.ts:expandTenantDetail` + 4 sample-консты, `useCsvDownload.ts:csvEscape` (export убран). ~165 строк dead-code вычищено. + +- **Acceptance Sprint 4:** + + - ✅ keyset pagination работает + Pest +3 теста + - ✅ Audit O-refactor-04 список 12 компонентов >300: 10/12 закрыты в Sprint 3+4 (Top-3 Sprint 3, 8 Sprint 4 B/1+B/2+B/3) + ImpersonationDialog уже <300 органически. **Остаются 2 исключения**: DealsView (560) + DealDetailDrawer (386) — Sprint 3 intentional (defineExpose-контракт Vitest, дальнейшее извлечение требует переписать тестовый контракт; зафиксировано как «правильное инженерное решение» в memory). + - ✅ Bundle analyzer + knip активны, dead-code удалён + - ✅ Регрессия зелёная: Pest 421 / Larastan 0 / Pint / ESLint 0 / vue-tsc 0 / Vitest 416/416 / build OK 1.02 сек / Histoire 21/43 + +- **Что НЕ сделано (вынесено в backlog):** + + - **O-perf-04 frontend-integration** — frontend `useDealsList`/`DealsView` пока использует OFFSET-путь (backward-compat). Включение `cursor` mode на UI = отдельный коммит (не блокирует backend). + - **DealsView/DealDetailDrawer split** — требует переписывания Vitest defineExpose-контракта. Не блокер. + - **Knip полный sweep по `api/`/`stores/`/`components/`** — ждёт Linux CI (Windows quirk). + - **Sprint 5 «Pre-prod tooling local»** — следующий по roadmap'у Track A (#25 Semgrep + #26 Trivy prep + #27 Dependabot). + +- **Sprint 0 push выполнен** — 21 коммит ушёл на origin/main `4f36bd3..8c6374d`. PAT permission «Workflows: Read and write» подтверждена через API-диагностику. Различие GitHub UI fine-grained PAT: «Workflows» (запись workflow-файлов) ≠ «Actions» (управление workflow runs). + +- **Сводка §0:** без изменений (70 ✅ / 5 🟦 / 4 ⏸ / 1 P0 + 3 P1 + 0 P2). Sprint 4 не был open-вопросом реестра — это закрытие audit O-* хвоста. **Что изменилось в v1.76 относительно v1.75:**