docs(spec): portal-wide audit & proposals — 70 items, 6-sprint schedule
Comprehensive audit of Лидерра portal from user's perspective: - 4 parallel Explore-agents (auth/app-user/admin/shared) → 100+ raw findings - Router (26 SPA) vs AppSidebar (7 items) vs AdminLayout (5/7 admin routes) coverage - ТЗ v8.5 §6 CSV-import gap analysis: schema partially ready, code 0% implemented - Cross-ref with Открытые_вопросы v1.83 (87/71 ✅/11 ⏸) - Playwright MCP browser smoke (login flow + console + network) Output: 70 atomic IDs in 11 categories (A-K), groupable to ~30-35 epics, scheduled across 6 sprints by priority P0 → P1 → P2 → P3 → 🆕 NEW → 🧹 CLEAN. Sprint 1 (P0, ~2 days): C2 FilterChip popovers + C4 Kanban DnD persist + C5 BulkActionsBar window.alert→snackbar + G1+G2 admin error handling. Sprint 4 (🆕 H1-H9, ~5 days): CSV-import module per ТЗ §6 (исторические лиды + проекты from crm.bp-gr.ru → tenant в Лидерре, idempotent через webhook_dedup_keys advisory-lock, transaction type historical_import). Approval: Дмитрий 2026-05-15 night «всё в работу, спринты по приоритету» через superpowers:brainstorming flow. Next: writing-plans for Sprint 1. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,321 @@
|
||||
# Portal-wide Audit & Proposals — Лидерра
|
||||
|
||||
**Дата:** 2026-05-15
|
||||
**Автор:** Claude (через `superpowers:brainstorming` → собственная синтез)
|
||||
**Заказчик:** Дмитрий (kpd9363@gmail.com)
|
||||
**Статус:** approved для составления планов; реализация sprint-by-sprint по приоритету
|
||||
**Связанные источники:** [docs/Открытые_вопросы_v8_3.md v1.83](../../Открытые_вопросы_v8_3.md), [docs/CRM_bp-gr_Инструкция_v8_5.md §6](../../CRM_bp-gr_Инструкция_v8_5.md), [CLAUDE.md v1.93](../../../CLAUDE.md)
|
||||
|
||||
---
|
||||
|
||||
## 1. Цель
|
||||
|
||||
Привести портал Лидерра к состоянию «всё, что обещает UI, работает» (полная функциональность для пользователя), включая опциональный модуль миграции исторических данных из crm.bp-gr.ru (§6 ТЗ), и убрать dev-артефакты перед production. Запрос заказчика 2026-05-15 night:
|
||||
|
||||
> «Проверь портал с точки зрения пользователя. Чтобы работали все кнопки, закладки, списки, справочники и т.д. Посмотри на содержание портала, убери или добавь того чего не хватает для полноценной работы портала и всех функций и задач, включая миграцию проектов и сделок. Сформулируй все предложения в табличной форме и дай на утверждение мне перед реализацией. Экономия 0%».
|
||||
|
||||
## 2. Метод аудита
|
||||
|
||||
| Шаг | Инструмент | Результат |
|
||||
|---|---|---|
|
||||
| Static-audit views/handlers/lookups | 4 параллельных `Explore`-агента (auth / app-user / admin / shared+stores+api) | 100+ raw findings с file:line |
|
||||
| Карта маршрутов | `app/resources/js/router/index.ts` + `app/routes/web.php` | 26 SPA + 23 API endpoint'а |
|
||||
| Sidebar coverage | `AppSidebar.vue` + `AdminLayout.vue` navItems | Расхождения с router'ом |
|
||||
| ТЗ-coverage | ТЗ v8.5 §6 (CSV-импорт) + cross-ref schema.sql v8.20 | §6 спецификация vs текущая реализация (0%) |
|
||||
| Реестр открытых вопросов | v1.83 (87 продуктовых / 71 ✅ / 11 ⏸) | Какие ⏸ внешние блокеры, какие можно закрыть в портале |
|
||||
| Browser smoke | Playwright MCP — `/login` + console + network | Подтверждено: Vuetify работает, Lucide рендерит, `/api/auth/me` 401 для unauth (curl-500 был артефакт без Sanctum headers), DemoSeeder credentials расходятся с БД |
|
||||
|
||||
**Что НЕ проверялось этим аудитом:**
|
||||
|
||||
- Mobile-вид (всё спроектировано в desktop-first; mobile pass — отдельный спринт после готовности баз)
|
||||
- Лендинг (⏸ Б-1, отдельный track)
|
||||
- Real load-testing (Pre-prod track)
|
||||
- Pen-test / SAST расширенный (Phase 3 трек Roadmap)
|
||||
|
||||
## 3. Sprint Schedule (по приоритету)
|
||||
|
||||
```
|
||||
Sprint 1 (P0) → Sprint 2 (P1 wave 1) → Sprint 3 (P1 wave 2 + Backend gaps)
|
||||
Sprint 4 (P1 миграция §6) → Sprint 5 (P2 UX-debt) → Sprint 6 (P3 polish + Cleanup)
|
||||
```
|
||||
|
||||
### Sprint 1 — P0 BLOCKED-UX (5 эпиков, ~1.5-2 дня)
|
||||
|
||||
| ID | Title | Effort |
|
||||
|---|---|---|
|
||||
| C2 | FilterChip popovers DealsView (Проект/Менеджер) — реализовать списки из `/api/projects` + `/api/managers` | M |
|
||||
| C4 | KanbanView DnD persist через `PATCH /api/deals/{id}` | S |
|
||||
| C5 | BulkActionsBar (projects) — `window.alert` → `v-snackbar` | XS |
|
||||
| G1 | AdminPricingTiersView — error handling submit/delete | XS |
|
||||
| G2 | AdminSupplierPricesView — error handling save | XS |
|
||||
|
||||
### Sprint 2 — P1 wave 1: UI-функционал (Settings, Billing, Auth) (~5 эпиков, ~5-7 дней)
|
||||
|
||||
| ID | Title | Effort |
|
||||
|---|---|---|
|
||||
| A2 | RecoveryCodesView continue button — redirect | XS |
|
||||
| A3 | RecoveryCodesView — подвязка на real API | S |
|
||||
| A7 | `/legal/offer` + `/legal/privacy` routes + stub blade | S |
|
||||
| D1+D2+D3+D4+D5+J5+J6 | Settings ProfileTab + ApiTab — все 6 кнопок + backend endpoints (`PATCH /me`, `POST /api-keys/regenerate`, `PUT /tenants/me/webhook-settings`, `POST /webhooks/test`, copy/regenerate logic) | L |
|
||||
| E1 | BillingView Пополнить баланс — TopupDialog + `POST /api/billing/topup` (stub без реальной оплаты на MVP) | L |
|
||||
| E3 | BillingView Overview tab — подвязка BalanceCard/TransactionsTable/InvoicesTable на real API | L |
|
||||
|
||||
### Sprint 3 — P1 wave 2: Admin + Dashboard + Reports + Reminders (~6 эпиков, ~4-6 дней)
|
||||
|
||||
| ID | Title | Effort |
|
||||
|---|---|---|
|
||||
| B1 | AppSidebar: добавить «Напоминания» в группу «Работа» | XS |
|
||||
| B4 | AdminLayout sidebar: добавить /admin/pricing-tiers + /admin/supplier-prices | XS |
|
||||
| B5 | AdminLayout impersonation-banner | M |
|
||||
| C1+J3 | Dashboard real API + `GET /api/dashboard/summary` | M |
|
||||
| C8+F3 | RemindersView openDeal + bell deep-link на `/deals?openId=` | S |
|
||||
| D6+D7 | SettingsView placeholder-tabs — реализация или скрытие (decide per-tab) | M-L per tab |
|
||||
| F1 | Reports Provider'ы — managers/sources/billing summary | M |
|
||||
| F2 | Reports скачать-файл endpoint `/api/reports/jobs/{id}/file` + signed URL 24ч | S |
|
||||
| G4 | AdminBillingView row-actions (suspend/refund/edit-tariff + backend endpoints) | L |
|
||||
| G5 | AdminIncidentsView detail-view `/admin/incidents/:id` | M |
|
||||
| G6 | AdminIncidentsView РКН-notify action + endpoint | S |
|
||||
| J1 | CTO-18 — auth+tenant middleware на /api/deals (требует Б-1 для prod) | M |
|
||||
| J2 | /api/admin/* — auth:saas-admin middleware (требует Б-1 + DO-4) | M |
|
||||
|
||||
### Sprint 4 — 🆕 Миграция исторических данных §6 (9 sub-tasks = 1 эпик, ~3-5 дней)
|
||||
|
||||
| ID | Title | Effort |
|
||||
|---|---|---|
|
||||
| H1 | Schema delta: `import_unknown_statuses` table + RLS | S |
|
||||
| H2 | Schema enrichment `import_log` (+5 колонок) | XS |
|
||||
| H3 | Backend сервисы: `CsvLeadsParser` + `StatusRuToSlugMapper` + `HistoricalImportService` | XL |
|
||||
| H4 | Backend job + controller: `ImportLeadsJob` + `ImportController` + route + email | L |
|
||||
| H5 | Frontend ImportView (dropzone + progress + результат-таблица) | L |
|
||||
| H6 | Unknown statuses wizard — sub-dialog маппинга | M |
|
||||
| H7 | Bulk-импорт проектов (18-колоночный CSV из crm.bp-gr.ru) | L |
|
||||
| H8 | UI вход — tab в Settings + кнопка в ProjectsView page-head | XS (decision) |
|
||||
| H9 | Мини-инструкция «Как перенести данные из crm.bp-gr.ru» | S |
|
||||
|
||||
**Schema delta:** v8.20 → v8.21 (+1 таблица + 5 колонок в import_log)
|
||||
|
||||
### Sprint 5 — P2 UX-debt (~19 эпиков, ~4-5 дней)
|
||||
|
||||
| ID | Title | Effort |
|
||||
|---|---|---|
|
||||
| A1 | Yandex SSO кнопка — `:disabled` + tooltip | XS |
|
||||
| A4 | ResetPassword confirmation `:error-messages` | XS |
|
||||
| A5 | ForgotPassword fallback message logic fix | XS |
|
||||
| A6 | TwoFactor реальный countdown | S |
|
||||
| A8 | DemoSeeder re-seed скрипт + dev README | XS |
|
||||
| B2 | Sidebar count «Сделки» из store + `/api/deals?count_only=1` (J4) | S |
|
||||
| B3 | ⌘K — minimal command palette ИЛИ удалить плашку | M (decide) |
|
||||
| C3 | DealsView Export button consolidation | XS |
|
||||
| C6 | NewDealDialog degradation alert при mock-fallback | XS |
|
||||
| C7 | DealDetailDrawer degradation alert | XS |
|
||||
| C9 | ProjectsView Plan 6 (regions subject-level) — review + merge после GitHub 403 unblock | S |
|
||||
| E2 | BalanceCard «Автопополнение» + «Сменить тариф» — disable+tooltip ИЛИ реализовать | XS / L |
|
||||
| E4 | BillingView pending alert — real data | S |
|
||||
| G3 | AdminPricingTiers + SupplierPrices — переписать на TypeScript | M |
|
||||
| G7 | AdminPricingTiers effective_from date-picker | S |
|
||||
| G10 | AdminBilling `confirm()` → `v-dialog` | XS |
|
||||
| I1 | DevIndexBadge + DevIndexOverlay cleanup (если решено убрать перед production) | S |
|
||||
| I3 | mocks → `tests/__mocks__/` или DEV-only feature-flag | S |
|
||||
| I4 | ImpersonationDialog devPlainCode — gate за DEV | XS |
|
||||
|
||||
### Sprint 6 — P3 polish + Cleanup tail (~8 эпиков, ~2-3 дня)
|
||||
|
||||
| ID | Title | Effort |
|
||||
|---|---|---|
|
||||
| A9 | A11y aria-labels на eye-icons | XS |
|
||||
| B6 | AdminLayout DEV-only auth-gap banner | XS |
|
||||
| F4 | usePolling → constants/polling.ts | XS |
|
||||
| F5 | `new_device_login` через session-fingerprint (требует инфра) | XL |
|
||||
| G8 | ImpersonationDialog two-person approval (требует Б-1 SSO) | M |
|
||||
| G9 | AdminSystem aria-label на edit-кнопки | XS |
|
||||
| I2 | dev-indices.json gitignore-решение | XS |
|
||||
| I5 | ProjectsView clearable workaround removal (CTO-19 closure tail) | XS |
|
||||
|
||||
## 4. Таблица предложений — полный список 70 эпиков
|
||||
|
||||
> Полная таблица с обоснованиями — см. оригинальный sync-message от 2026-05-15 в conversation. Ниже компактная версия с ссылками.
|
||||
|
||||
### A. Аутентификация и onboarding (9 эпиков)
|
||||
|
||||
| ID | Объект | Сейчас | Предложение | Приоритет | Effort |
|
||||
|---|---|---|---|---|---|
|
||||
| A1 | `LoginView.vue:107` — Yandex 360 SSO | dead stub (по плану — ⏸ Б-1) | `:disabled` + tooltip «после Б-1» | 🟡 P2 | XS |
|
||||
| A2 | `RecoveryCodesView.vue:73` | TODO no-op | redirect на /login или /dashboard | 🟠 P1 | XS |
|
||||
| A3 | `RecoveryCodesView.vue:15-24` | Статический mock | API integration | 🟠 P1 | S |
|
||||
| A4 | `ResetPasswordView.vue:110-118` | Нет `:error-messages` | Add error display | 🟡 P2 | XS |
|
||||
| A5 | `ForgotPasswordView.vue:36-38` | Fallback недостижим | Безусловный fallback | 🟡 P2 | XS |
|
||||
| A6 | `TwoFactorView.vue:129` | Hardcoded «02:34» | Реальный countdown | 🟡 P2 | S |
|
||||
| A7 | `AuthLayout.vue:47-48` | `/legal/*` → 404 | Stub-routes + blade | 🟠 P1 | S |
|
||||
| A8 | DemoSeeder dev | 422 при логине | Re-seed скрипт + README | 🟡 P2 | XS |
|
||||
| A9 | Eye-icons toggle | Нет aria-label | Добавить | 🟢 P3 | XS |
|
||||
|
||||
### B. Sidebar / Layout / Navigation (6 эпиков)
|
||||
|
||||
| ID | Объект | Сейчас | Предложение | Приоритет | Effort |
|
||||
|---|---|---|---|---|---|
|
||||
| B1 | AppSidebar — Напоминания | Отсутствует в nav | Добавить в «Работа» | 🟠 P1 | XS |
|
||||
| B2 | AppSidebar Сделки count=247 | Hardcoded | computed из store | 🟡 P2 | S |
|
||||
| B3 | ⌘K stub в sidebar+topbar | Без handler | Command palette или удалить | 🟡 P2 | M |
|
||||
| B4 | AdminLayout navItems | Нет /admin/pricing-tiers и /admin/supplier-prices | Добавить | 🟠 P1 | XS |
|
||||
| B5 | Impersonation banner | Нет глобального индикатора | Полоса в AdminLayout | 🟠 P1 | M |
|
||||
| B6 | AdminLayout auth-gap | Не виден в UI | DEV-only banner | 🟢 P3 | XS |
|
||||
|
||||
### C. App-views Dashboard/Deals/Kanban/Projects (9 эпиков)
|
||||
|
||||
| ID | Объект | Сейчас | Предложение | Приоритет | Effort |
|
||||
|---|---|---|---|---|---|
|
||||
| C1 | Dashboard KPI mock | TODO | `GET /api/dashboard/summary` | 🟠 P1 | M |
|
||||
| C2 | DealsView FilterChip popovers | console.log only | Popover'ы со списками | 🔥 P0 | M |
|
||||
| C3 | DealsView page-head Export | Заглушка | Подвязать или удалить | 🟡 P2 | XS |
|
||||
| C4 | KanbanView DnD persist | TODO | `PATCH /api/deals/{id}` | 🔥 P0 | S |
|
||||
| C5 | BulkActionsBar window.alert | Блокирует UI | `v-snackbar` | 🔥 P0 | XS |
|
||||
| C6 | NewDealDialog mock fallback | Silent | Degradation alert | 🟡 P2 | XS |
|
||||
| C7 | DealDetailDrawer MOCK_EVENTS | Silent | Degradation alert | 🟡 P2 | XS |
|
||||
| C8 | RemindersView openDeal | Пусто | `/deals?openId=` deep-link | 🟠 P1 | S |
|
||||
| C9 | ProjectsView Plan 6 regions | Локально в worktree | Review + merge после GitHub unblock | 🟠 P1 | S |
|
||||
|
||||
### D. Settings (7 эпиков)
|
||||
|
||||
| ID | Объект | Сейчас | Предложение | Приоритет | Effort |
|
||||
|---|---|---|---|---|---|
|
||||
| D1 | ProfileTab Save | Без handler | `PATCH /api/auth/me` (J6) | 🟠 P1 | M |
|
||||
| D2 | ApiTab Copy | Без handler | clipboard.writeText + toast | 🟠 P1 | XS |
|
||||
| D3 | ApiTab Regenerate | Без handler | `POST /api/api-keys/regenerate` (J5) | 🟠 P1 | M |
|
||||
| D4 | ApiTab Save Webhook | Без handler | `PUT /api/tenants/me/webhook-settings` (J5) | 🟠 P1 | S |
|
||||
| D5 | ApiTab Test Webhook | Без handler | `POST /api/webhooks/test` (J5) | 🟠 P1 | S |
|
||||
| D6 | PlaceholderTab × 4 | «В разработке» | Реализовать или скрыть | 🟠 P1 | L per tab |
|
||||
| D7 | SettingsView left-rail | 8 tab'ов, 4 заглушки | Hide-if-not-implemented + добавить «Импорт» (H8) | 🟡 P2 | XS |
|
||||
|
||||
### E. Billing (4 эпика)
|
||||
|
||||
| ID | Объект | Сейчас | Предложение | Приоритет | Effort |
|
||||
|---|---|---|---|---|---|
|
||||
| E1 | BillingView Пополнить | Без handler | TopupDialog + `POST /api/billing/topup` stub | 🟠 P1 | L |
|
||||
| E2 | BalanceCard 3 кнопки | Без handlers | Disable+tooltip или реализация | 🟡 P2 | XS/L |
|
||||
| E3 | BillingView Overview API | MOCK | Real API | 🟠 P1 | L |
|
||||
| E4 | BillingView pending alert | Hardcoded | Real data | 🟡 P2 | S |
|
||||
|
||||
### F. Reports / Reminders / Notifications (5 эпиков)
|
||||
|
||||
| ID | Объект | Сейчас | Предложение | Приоритет | Effort |
|
||||
|---|---|---|---|---|---|
|
||||
| F1 | Reports Provider'ы | 1 из 4 | Реализовать 3 оставшихся | 🟠 P1 | M |
|
||||
| F2 | Reports Скачать | Endpoint нет | `/api/reports/jobs/{id}/file` + signed URL | 🟠 P1 | S |
|
||||
| F3 | bell deep-link | `/deals` без id | `/deals?openId=` (C8) | 🟡 P2 | XS |
|
||||
| F4 | usePolling 30s hardcoded | Разбросано | `constants/polling.ts` | 🟢 P3 | XS |
|
||||
| F5 | new_device_login | Заглушка | Session-fingerprint (Post-MVP) | 🟢 P3 | XL |
|
||||
|
||||
### G. Admin SaaS (10 эпиков)
|
||||
|
||||
| ID | Объект | Сейчас | Предложение | Приоритет | Effort |
|
||||
|---|---|---|---|---|---|
|
||||
| G1 | PricingTiersView submit/delete | Silent failures | try/catch + alert + toast | 🔥 P0 | XS |
|
||||
| G2 | SupplierPricesView save | Silent failures | try/catch + alert + toast | 🔥 P0 | XS |
|
||||
| G3 | PricingTiers + SupplierPrices — plain JS | Нет типизации | TS rewrite + `api/admin.ts` | 🟡 P2 | M |
|
||||
| G4 | AdminBillingView row-actions | Нет actions | Dropdown 3 actions + backend | 🟠 P1 | L |
|
||||
| G5 | AdminIncidentsView drill-down | Нет detail-view | `/admin/incidents/:id` | 🟠 P1 | M |
|
||||
| G6 | AdminIncidentsView РКН-notify | Badge без action | Button + endpoint | 🟠 P1 | S |
|
||||
| G7 | PricingTiersView effective_from | Hardcoded next month | Date-picker | 🟡 P2 | S |
|
||||
| G8 | ImpersonationDialog two-person | TODO (CTO-15) | Реализация после Б-1 SSO | 🟢 P3 | M |
|
||||
| G9 | AdminSystem aria-label | Нет на edit-кнопках | Добавить | 🟢 P3 | XS |
|
||||
| G10 | AdminBilling `confirm()` | Браузерный | `v-dialog` confirm | 🟡 P2 | XS |
|
||||
|
||||
### H. Миграция §6 — 🆕 НОВЫЙ ЭПИК (9 sub-tasks)
|
||||
|
||||
| ID | Объект | Сейчас | Предложение | Приоритет | Effort |
|
||||
|---|---|---|---|---|---|
|
||||
| H1 | Schema delta | `import_unknown_statuses` отсутствует | Migration + RLS | 🆕 P1 | S |
|
||||
| H2 | import_log enrichment | Минимальный | +5 колонок (entity_type, source_system, mapping_config, unknown_statuses_count, dry_run) | 🆕 P1 | XS |
|
||||
| H3 | Backend services | Нет | `CsvLeadsParser` + `StatusRuToSlugMapper` + `HistoricalImportService` (advisory-lock per §6.5, balance НЕ списывается, transaction type `historical_import`) | 🆕 P1 | XL |
|
||||
| H4 | Backend job + controller | Нет | `ImportLeadsJob` + `ImportController` + route `/api/imports` + email-уведомление | 🆕 P1 | L |
|
||||
| H5 | Frontend ImportView | Нет | Dropzone + progress + результат-таблица | 🆕 P1 | L |
|
||||
| H6 | Unknown statuses wizard | Нет | Sub-dialog маппинга | 🆕 P1 | M |
|
||||
| H7 | Bulk-импорт проектов | Нет | Аналогичный flow для CSV проектов | 🆕 P1 | L |
|
||||
| H8 | UI вход — где | Нет | Tab в Settings + кнопка в ProjectsView | 🆕 P1 | XS |
|
||||
| H9 | Мини-инструкция | Нет | Markdown «Как перенести данные» | 🆕 P2 | S |
|
||||
|
||||
**ТЗ референс:** §6.1 (когда нужен) / §6.2 (формат файла) / §6.3 (маппинг полей) / §6.4 (русские названия → slug) / §6.5 (идемпотентность через `webhook_dedup_keys`) / §6.6 (workflow в UI) / §6.7 (таблица `import_log`).
|
||||
|
||||
### I. Dev-артефакты для production hygiene (5 эпиков)
|
||||
|
||||
| ID | Объект | Сейчас | Предложение | Приоритет | Effort |
|
||||
|---|---|---|---|---|---|
|
||||
| I1 | DevIndexBadge + DevIndexOverlay | Temporary feature | Удалить перед production | 🧹 P2 | S |
|
||||
| I2 | dev-indices.json | Modified in git status | .gitignore decision | 🧹 P3 | XS |
|
||||
| I3 | composables/mock*.ts | Production fallbacks | `tests/__mocks__/` или DEV-flag | 🧹 P2 | S |
|
||||
| I4 | devPlainCode banner | Visible в UI | DEV-only gate | 🧹 P2 | XS |
|
||||
| I5 | ProjectsView clearable `::after` | Workaround | Удалить (CTO-19 closure tail) | 🧹 P3 | XS |
|
||||
|
||||
### J. Backend / Infra gaps (6 эпиков)
|
||||
|
||||
| ID | Объект | Сейчас | Предложение | Приоритет | Effort |
|
||||
|---|---|---|---|---|---|
|
||||
| J1 | CTO-18 middleware на /api/deals | Реестр-open | auth:sanctum+tenant перед prod | 🟠 P1 | M |
|
||||
| J2 | /api/admin/* middleware | Per Б-1 ⏸ | auth:saas-admin после Б-1+DO-4 | 🟠 P1 | M |
|
||||
| J3 | GET /api/dashboard/summary | Нет | Создать для C1 | 🟠 P1 | M |
|
||||
| J4 | GET /api/deals?count_only=1 | Нет | Создать для B2 | 🟡 P2 | XS |
|
||||
| J5 | API-keys/Webhooks endpoints | Нет | 3 новых endpoint'а для D2-D5 | 🟠 P1 | M |
|
||||
| J6 | PATCH /api/auth/me | Только notification-preferences | Расширить для full profile (D1) | 🟠 P1 | S |
|
||||
|
||||
### K. Out-of-scope (намеренно НЕ меняем)
|
||||
|
||||
| ID | Объект | Причина |
|
||||
|---|---|---|
|
||||
| K1 | Lucide иконки | CTO-19 ✅ closed |
|
||||
| K2 | region_mask legacy | Plan 6.5 cleanup |
|
||||
| K3 | Реестровые ⏸ внешние блокеры | Б-1 / юр.редактура / DO-2/DO-4 / Биз-25..31 |
|
||||
| K4 | MagicLink 24ч | Биз-13 closed |
|
||||
| K5 | Histoire stories | Dev-tool |
|
||||
|
||||
## 5. Сводка
|
||||
|
||||
| Категория | Кол-во | 🔥 P0 | 🟠 P1 | 🟡 P2 | 🟢 P3 | 🆕 NEW | 🧹 CLEAN |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| A. Auth | 9 | 0 | 3 | 5 | 1 | 0 | 0 |
|
||||
| B. Sidebar/Layout | 6 | 0 | 3 | 2 | 1 | 0 | 0 |
|
||||
| C. App-views | 9 | 3 | 4 | 2 | 0 | 0 | 0 |
|
||||
| D. Settings | 7 | 0 | 6 | 1 | 0 | 0 | 0 |
|
||||
| E. Billing | 4 | 0 | 2 | 2 | 0 | 0 | 0 |
|
||||
| F. Reports/etc | 5 | 0 | 2 | 1 | 2 | 0 | 0 |
|
||||
| G. Admin | 10 | 2 | 4 | 3 | 1 | 0 | 0 |
|
||||
| H. Миграция §6 | 9 | 0 | 0 | 1 | 0 | 8 | 0 |
|
||||
| I. Cleanup | 5 | 0 | 0 | 3 | 2 | 0 | 5 |
|
||||
| J. Backend gaps | 6 | 0 | 5 | 1 | 0 | 0 | 0 |
|
||||
| **Итого** | **70** | **5** | **29** | **21** | **7** | **8** | **5** |
|
||||
|
||||
**Realistic эпиков после группировки:** ~30-35.
|
||||
**Грубая оценка solo-разработчика:** 6-9 недель (Sprint 1 ~2 дня, Sprint 2 ~7 дней, Sprint 3 ~6 дней, Sprint 4 ~5 дней, Sprint 5 ~4 дня, Sprint 6 ~3 дня, + buffer на code-review/testing/regression).
|
||||
|
||||
## 6. Risks & dependencies
|
||||
|
||||
| Risk | Митigation |
|
||||
|---|---|
|
||||
| GitHub push BLOCKED 403 «verify email» (Plan 6 + сегодняшние коммиты) | До закрытия — работа локально + worktree. Б-1 (ООО) не требуется для этого, нужен GitHub-account fix |
|
||||
| Б-1 (реквизиты ООО) блокирует J1 (полный production переход), J2 (saas-admin SSO), E1 (реальная ЮKassa), Диз-3/DO-2/DO-4 | Все эпики на MVP идут со stub-аутентификацией / placeholder-данными. Готовим код, но production-deploy ждёт Б-1 |
|
||||
| Биз-28 (CSV-схема поставщика) — BLOCKED credentials | Не блокирует H1-H9 (миграция работает с CSV ТЗ-формата §6.2 от пользователя, не от поставщика) |
|
||||
| Schema delta v8.20→v8.21 в Sprint 4 | Migrate:fresh на dev в начале спринта; PHPStan baseline regen; обновить CLAUDE.md §0/§2 после merge |
|
||||
| Sprint 5 (P2 UX) — большой объём | Можно дробить на 2 sub-sprint'а если устаёт фокус |
|
||||
| Mock-data fallback removal (I3) | Verify нет production-paths использующих mocks перед удалением — может потребовать feature-flag вместо удаления |
|
||||
|
||||
## 7. Acceptance criteria для каждого Sprint'а
|
||||
|
||||
- **Sprint 1 (P0):** Все 5 P0-эпиков закрыты + regression Pest --parallel + Vitest зелёные + browser smoke по каждому fix'у.
|
||||
- **Sprint 2 (P1 wave 1):** Settings (Profile/Api) + Billing (Topup) полностью функциональны от UI до DB. Auth legal-pages не выдают 404.
|
||||
- **Sprint 3 (P1 wave 2):** Dashboard живой. Admin row-actions + impersonation banner + incidents drill-down + reports backend complete. Sidebar (B1, B4) исправлен.
|
||||
- **Sprint 4 (миграция §6):** Тенант может загрузить CSV из crm.bp-gr.ru, увидеть прогресс, замапить unknown statuses, получить email-результат. Аналогично для проектов.
|
||||
- **Sprint 5 (P2):** ⌘K либо работает, либо удалён. Все toast'ы консистентны. Demo-seeder работает на чистом dev'е. Dev-артефакты удалены/гейтнуты.
|
||||
- **Sprint 6 (P3):** A11y aria-labels везде. Polling вынесен. Cleanup tail.
|
||||
|
||||
## 8. Approval log
|
||||
|
||||
- 2026-05-15 night — Дмитрий: «Полный portal-wide + браузерный smoke (Recommended)» (scope)
|
||||
- 2026-05-15 night — Дмитрий: «Да, всё в работу — спринты по приоритету P0→P1→P2→P3+Новые (Recommended)» (composition + scheduling)
|
||||
|
||||
## 9. Next steps
|
||||
|
||||
После approval этого spec'а:
|
||||
|
||||
1. `git add` + `git commit` этого spec-файла.
|
||||
2. Запустить `superpowers:writing-plans` для **Sprint 1** (5 P0-эпиков). Когда Sprint 1 закрыт — Sprint 2 и т.д.
|
||||
3. Между спринтами — verification-before-completion regression sweep (Pest --parallel + Vitest + vue-tsc + lefthook).
|
||||
4. Обновление CLAUDE.md / реестра / memory после каждого закрытого спринта (через `claude-md-management:revise-claude-md`).
|
||||
Reference in New Issue
Block a user