Files
iistwin/.superpowers/sdd/di2-restyle/task-1-report.md

8.8 KiB
Raw Blame History

Отчёт этапа 1 — Удаление старого модуля финансов

Дата: 2026-09-07. Исполнитель: субагент Kimi (этап 1 плана .superpowers/sdd/di2-restyle/plan.md).

Итог

Этап выполнен полностью, без блокировок. Коммит: 66f4e5e — DI2: удаление старого модуля финансов — пул БД и аудит перенесены в finance-di2 (68 файлов, +212/−14471). Push в main выполнен, pre-push hook прогнал check + build — оба чисто («All checks passed»). Автодеплой запущен.

Проверки до удаления (grep-разведка)

  • server/: внешними потребителями server/finance/ были только server/routes/index.ts (registerFinanceRoutes) и server/finance-di2/db-client.ts (импорт пула). Других потребителей нет — server/index.ts finance не импортировал.
  • client/src: lib/format, useFinance, useColumnLabels импортировались только удаляемыми файлами (pages/finance/, components/finance/, pages/salary.tsx). После удаления — нулевых ссылок.
  • client-di2 имеет собственный src/lib/format.ts — не затронут.
  • Хуки pages/finance/use-mobile.tsx, use-theme.tsx, use-toast.ts никем вне папки не импортировались.

Сервер

Создано:

  • server/finance-di2/db-core.ts — точная копия server/finance/db-client.ts (внутренних относительных импортов не было, только pg/fs/path). Комментарий про google-sheets.ts поправлен на google-auth.ts (актуальный потребитель getPoolClient в DI2).
  • server/finance-di2/audit-scheduler.ts — порт startAuditScheduler из удалённого server/finance/audit.ts (cron «03:00 МСК» через setInterval-тик 60 сек, первый запуск через 10 сек, без node-cron), вызывает DI2 runIntegrityAudit из ./audit-agent. Защита от двойного запуска — модульный флаг schedulerStarted (так же, как в оригинале).

Изменено:

  • server/finance-di2/db-client.ts — реэкспорт из ./db-core вместо ../finance/db-client; DI2-совместимая обёртка getConfig() сохранена.
  • server/finance-di2/audit-agent.ts — добавлена персистентность истории аудита (порт из старого audit.ts): HISTORY_PATH = data/finance-audit-history.json, loadHistory() при загрузке модуля, saveHistory() после каждого runIntegrityAudit (unshift + обрезка до MAX_HISTORY = 50).
  • server/finance-di2/index.ts — вызов startAuditScheduler() в конце registerDi2Routes.
  • server/routes/index.ts — убраны import { registerFinanceRoutes } и его вызов; registerDi2Routes остался строго на том же месте (порядок middleware прежний).

Удалено: папка server/finance/ целиком (19 файлов): audit.ts, auto-detect.ts, cache.ts, calculations.ts, category-matching.ts, contract-sync.ts, customer-sync.ts, db-client.ts, debt.ts, google-sheets.ts, overrides.ts, routes.ts, salary-routes.ts, settings.ts, sync-utils.ts, table-config.ts, tags.ts, timeseries.ts, views.ts.

Вместе с модулем умерли endpoint'ы: /api/finance-settings, /api/audit/status, /api/finance/customer-sync/*, /api/finance/contract-sync/*, /api/finance/google/* (DI2 покрывает audit/history, audit/run, salary, google-auth под /api/auth/google/*). Потребителей этих endpoint'ов вне удалённого UI не было (по разведке плана).

Клиент (основное приложение)

Сохранено: client/src/components/finance/FinanceBottomNav.tsx → .superpowers/sdd/di2-restyle/FinanceBottomNav.reference.tsx (референс для этапа 3; git увидел это как rename 100%).

Удалено:

  • client/src/pages/finance/ (14 файлов, включая index.ts, use-mobile.tsx, use-theme.tsx, use-toast.ts)
  • client/src/components/finance/ (22 файла)
  • client/src/hooks/useFinance.ts, client/src/hooks/useColumnLabels.ts
  • client/src/lib/format.ts
  • client/src/pages/salary.tsx

Изменено:

  • client/src/App.tsx — убраны lazy-импорты (FinanceDashboard, Income*, Expenses*, FinanceSettingsPage, DebtPage, CalculationsPage, AuditPage, SalaryPage), роуты /finance, /finance/debt, /finance/calculations, /finance/audit, /finance/settings, /income*, /expenses*, /salary, записи ROUTE_TITLES для них.
  • client/src/index.css — удалён блок .hover-elevate/.hover-elevate-2 (строки ~343-376). Заодно удалены .active-elevate/.active-elevate-2 (строки ~378-383): они только переключали :active-opacity у ::after псевдоэлементов hover-elevate, вне удалённого finance DataTable не использовались (grep подтвердил — ноль вхождений в client/src; у DI2 свои классы в client-di2/src/index.css). Отклонение от буквы плана (план не упоминал active-elevate) — минимально корректное решение, зафиксировано здесь.
  • client/src/components/Sidebar.tsx — FinanceNavItem теперь внешняя ссылка <a href="/di2" target="_blank" rel="noopener"> (с иконкой ExternalLink), без active-состояния (роутов /finance больше нет); гейт moduleAccess.finance !== false && (isAdmin || hasPermission('finance.view')) сохранён. Пункт «Финансы» в меню профиля — также внешняя ссылка на /di2 с тем же расширенным гейтом (был только isAdmin). Импорт ExternalLink из lucide добавлен.
  • client/src/components/MobileBottomNav.tsx — пункт «Финансы» в меню ведёт на /di2 (внешняя ссылка); гейт расширен с isAdmin-only до isAdmin || hasPermission('finance.view') (добавлен импорт hasPermission) — по указанию плана «гейт сохранить».

Не тронуто (по плану): сиды прав finance.view/finance.manage (server/storage/roles.storage.ts), finance_access (shared/schema.ts, module-access, Users.tsx), client-di2/, внешняя финансовая БД.

Результаты проверок

  • npm run check (tsc основного + tsc -p client-di2/tsconfig.json) — чисто, без ошибок.
  • npm run build (main → di2 → server bundle) — успешно; предупреждения о размере чанков — прежние, не новые.
  • Push в main — успешен (6bcf4df..66f4e5e), pre-hook: «All checks passed».

Отклонения от плана / замечания

  1. .active-elevate/.active-elevate-2 удалены вместе с hover-elevate (см. выше) — мёртвый код после удаления hover-elevate.
  2. В папку коммита попали файлы плана .superpowers/sdd/di2-restyle/plan.md и ledger.md (были неотслеживаемыми, git add -A их подхватил; .superpowers в репозитории отслеживается — прецедент: коммит 2b3e768). Это артефакты SDD-процесса, вред не наносят.
  3. DI2-роут /api/audit/integrity (finance-di2/routes.ts:6144) не защищён auth-gate отдельно, но весь роутер DI2 проходит через authenticateToken + requirePermission('finance.manage') в registerDi2Routes — поведение прежнее.
  4. Env сервера (п. 1.1.5 плана — проверка GOOGLE_CLIENT_ID/GOOGLE_CLIENT_SECRET в .env сервера) — кодовое действие не требуется; DI2 google-auth использует /api/auth/google/callback (ручной шаг пользователя на этапе 4, OAuth-клиент).

Оставшееся (этапы 2–4)

Этап 2 (мост тем/скинов), этап 3 (визуальный рестайл DI2), этап 4 (smoke прод-API, документация AGENTS.md/Obsidian, ручной Google redirect URI) — не входили в эту задачу.