Files
Ильяс Султанов 66f4e5ef53 DI2: удаление старого модуля финансов — пул БД и аудит перенесены в finance-di2
- server/finance/ (19 файлов) удалён: пул финансовой БД перенесён в server/finance-di2/db-core.ts, db-client.ts теперь реэкспортирует из ./db-core
- Шедулер аудита перенесён в server/finance-di2/audit-scheduler.ts (03:00 МСК, setInterval, без node-cron), запуск из registerDi2Routes с защитой от повторного старта
- История аудита DI2 теперь персистентна: загрузка/запись data/finance-audit-history.json в audit-agent.ts (порт из удалённого server/finance/audit.ts)
- registerFinanceRoutes убран из server/routes/index.ts, registerDi2Routes остался на его месте
- Клиент: удалены pages/finance/, components/finance/, hooks/useFinance.ts, hooks/useColumnLabels.ts, lib/format.ts, pages/salary.tsx; роуты /finance*, /income*, /expenses*, /salary и lazy-импорты убраны из App.tsx
- Навигация: «Финансы» в Sidebar и MobileBottomNav ведёт на субапп /di2 (внешняя ссылка), гейт moduleAccess.finance + finance.view сохранён
- index.css: удалён блок .hover-elevate/.hover-elevate-2/.active-elevate (использовался только старым модульным DataTable)
- FinanceBottomNav.tsx сохранён как референс для этапа 3 (.superpowers/sdd/di2-restyle/FinanceBottomNav.reference.tsx)
- Не тронуто: client-di2/, сиды прав finance.view/manage, finance_access (module-access)
2026-09-06 21:53:47 +03:00

15 KiB
Raw Permalink Blame History

План: удаление старого модуля финансов + рестайл DI2 под дизайн iistwin

Репозиторий: C:\1Ai\1iistwin\1Project (main, автодеплой через push). Субапп DI2 уже в проде на /di2 (server/finance-di2 + client-di2).

Решения пользователя (зафиксированы): /salary удалить и вести на /di2; рестайл = мост токенов + точечные правки (без замены 45 shadcn-компонентов); мобильная навигация = нижняя панель.


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

1.1 Сервер

  1. Перенос пула БД: содержимое server/finance/db-client.ts → новый server/finance-di2/db-core.ts (правка внутренних импортов: там только fs/path/pg). Обновить server/finance-di2/db-client.ts: реэкспорт из ./db-core вместо ../finance/db-client. Удалить папку server/finance/ целиком (19 файлов).
  2. Шедулер аудита: создать server/finance-di2/audit-scheduler.ts — порт startAuditScheduler (cron 03:00 МСК) из удаляемого server/finance/audit.ts:524, но вызывающий DI2-функцию runIntegrityAudit из ./audit-agent. Запускать из registerDi2Routes (server/finance-di2/index.ts). Реализация — setInterval-проверка времени (как в оригинале) или порт через обычный таймер; node-cron НЕ добавлять.
  3. Персистентность истории аудита: в server/finance-di2/audit-agent.ts добавить загрузку/запись data/finance-audit-history.json (порт логики из старого audit.ts): загрузка при старте модуля, append после каждого runIntegrityAudit. Сейчас история в памяти и теряется при рестарте.
  4. Регистрация: server/routes/index.ts — убрать import { registerFinanceRoutes } (стр. 33) и вызов (стр. 116), оставить registerDi2Routes.
  5. Env сервера (проверка, не код): DI2 Google-флоу использует GOOGLE_CLIENT_ID/GOOGLE_CLIENT_SECRET — проверить наличие в .env сервера; старый FINANCE_GOOGLE_REDIRECT_URI больше не нужен.

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

  1. Удалить: client/src/pages/finance/ (14 файлов), 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.
    • Перед удалением: grep -rn "lib/format\|useFinance" client/src --include=*.tsx --include=*.ts — все внешние импорты должны отсутствовать (по разведке используются только удаляемыми файлами — перепроверить!).
  2. client/src/index.css — удалить блок .hover-elevate/.hover-elevate-2 (строки ~343-374, использовался только finance DataTable).
  3. client/src/App.tsx:
    • Убрать lazy-импорты finance-страниц (строки 61-72) и роуты /finance, /finance/debt, /finance/calculations, /finance/audit, /income*, /expenses*, /salary (строки 117-120, 187-200).
    • ROUTE_TITLES: убрать записи этих путей.
  4. Навигация:
    • client/src/components/Sidebar.tsx (строки 1084-1122, 1544, 1641-1645): FinanceNavItem и пункт «Финансы» в меню профиля → внешняя ссылка <a href="/di2" target="_blank" rel="noopener"> (паттерн как в FinanceSidebar.tsx:88-99), гейт moduleAccess.finance !== false && (isAdmin || hasPermission('finance.view')) сохранить.
    • client/src/components/MobileBottomNav.tsx (строки 383-389): пункт «Финансы» → /di2.
  5. Не трогать: сиды прав finance.view/manage (server/storage/roles.storage.ts:300-301 — gate DI2 ломается без них), finance_access (shared/schema.ts, module-access, Users.tsx матрица доступа).

1.3 Проверка этапа

npm run check + npm run build чисто; ключевые API DI2 авторизованно 200 (список из этапа 4).


Этап 2 — Мост тем/скинов iistwin в DI2

Ключевая несовместимость: DI2 ждёт голые HSL-тройки (hsl(var(--x) / <alpha>)), скины iistwin генерируют полные значения (hsl(...)). Решение — перевод DI2 на формат основного клиента + общий generated-skins.css + свой провайдер.

2.1 Общий код тем

  • Vite-алиас в vite.config.di2.ts: "@skin": path.resolve(import.meta.dirname, "client/src/themes") (через ../client → фактически 1Project/client/src/themes); пути в client-di2/tsconfig.json: "@skin/*": ["../client/src/themes/*"].
  • Импортируемые модули (чистый TS, без React): tokens.ts (generateSkinCss, Skin типы), skins/index.ts (BUILT_IN_SKINS, DEFAULT_SKIN_ID, getBuiltInSkinById), styles/generated-skins.css — через CSS-@import в index.css (путь ../../client/src/themes/styles/generated-skins.css первой строкой).

2.2 Di2ThemeProvider — client-di2/src/themes/Di2ThemeProvider.tsx

Порт логики client/src/themes/ThemeProvider.tsx (строки 75-92, 151-209) минус useAuth/useQuery:

  • Приоритет скина: localStorage['skin'] (если id валиден среди BUILT_IN_SKINS + кастомных с сервера) → GET /api/organization/current-skin ({skinId, skin}) → 'iistwin'.
  • Кастомные скины: список через GET /api/organization/skins, токены через GET /api/organization/skins/:id (только для не-встроенного текущего).
  • Тема: localStorage['theme'] → prefers-color-scheme + слушатель.
  • На <html>: data-skin, data-theme, класс light|dark; для кастомного скина — <style id="skin-runtime"> с generateSkinCss(skin, theme).
  • Ключи localStorage 'skin'/'theme' — те же, что в основном приложении: выбор пользователя синхронизируется между iistwin и /di2 автоматически.
  • В client-di2/src/main.tsx: <Router base="/di2"><Di2ThemeProvider><App/></Di2ThemeProvider></Router>.

2.3 Перевод DI2 на полный формат токенов

  1. client-di2/tailwind.config.ts: все цвета hsl(var(--x) / <alpha-value>) → var(--x) (как в корневом tailwind.config.ts); borderRadius: хардкод lg/md/sm → var(--radius) + каскад calc(var(--radius) - 2px)/-4px (скопировать блок из корневого конфига); добавить warning/success/info из var(--warning) и т.д. Если DI2 использует alpha-модификаторы семантических цветов (bg-primary/50) — заменить на color-mix(in oklab, var(--primary) 50%, transparent) (grep при исполнении).
  2. client-di2/src/index.css:
    • Заменить собственные :root/.dark HSL-тройки (строки 9-169) на fallback-блоки, скопированные из client/src/index.css:13-80 (iistwin light/dark до гидратации).
    • DI2-only переменные — переопределить от семантических токенов через color-mix: --card-border/--popover-border → var(--border); --primary-border, --secondary-border, --muted-border, --accent-border, --destructive-border, --sidebar-primary-border, --sidebar-accent-border → color-mix(in oklab, var(--X) 82%, black); --button-outline → color-mix(in oklab, var(--primary) 35%, transparent); --badge-outline → color-mix(in oklab, var(--muted-foreground) 35%, transparent); --elevate-1/2 → rgba(0,0,0,.05/.08) (в .dark — светлые значения). Убрать --opaque-button-border-intensity и hsl(from ...) relative-color вычисления.
  3. client-di2/index.html: lang="ru"; убрать оба preconnect и мега-link Google Fonts (23 семейства) → оставить только Inter (+DM Mono) как в client/index.html:23; viewport — убрать maximum-scale=1, добавить interactive-widget=resizes-content (паттерн фикса 2026-08-26).
  4. Шрифты приходят из скина: generateSkinCss эмитит --font-sans/--font-mono — в index.css DI2 удалить жёсткие --font-sans: Open Sans.

2.4 Проверка этапа

npm run check, npm run build; визуально: /di2 рендерится, светлая/тёмная тема переключается; смена скина в /settings/appearance основного приложения меняет вид /di2 после обновления (проверить data-skin на <html>).


Этап 3 — Визуальный рестайл (точечный)

  1. Графики recharts: заменить hex-палитры (77 вхождений: #2563eb и т.п. в income/expenses-overview, debt, calculations, planning, dashboard, heatmap, salary) на var(--chart-1..5) для палитр и var(--success)/var(--destructive)/var(--warning) для семантики. Recharts принимает CSS-переменные в fill/stroke.
  2. Хардкод Tailwind-цветов (133 вхождения text-red-500, bg-amber-50, text-green-600 и т.п.): заменить на семантические классы (text-destructive, text-success, bg-warning/10 + парные dark: где отсутствуют). Механическая замена по всем страницам client-di2.
  3. Таблицы по UI Style Guide: client-di2/src/components/ui/table.tsx — шапка bg-muted/50 text-[12px] font-medium text-muted-foreground, строки h-[var(--table-row-height,40px)], hover bg-muted/40, ячейки px-3 (как в основном клиенте). Density из Темы 2.0 подхватится автоматически.
  4. Контролы: скопировать client/src/components/fields/field-styles.ts в client-di2/src/lib/field-styles.ts (зависит только от cn), применить fieldControlClass в кастомных компонентах DI2 (column-filter, draggable-column-list, copyable-cell) — density/control-вид скина применится.
  5. app-sidebar: активный пункт через sidebar-accent (уже так), убраить лишние отступы, привести брендинг-блок к нашему виду (оставить «ОмегаПром / Финансы»).
  6. Мобильная нижняя панель — новый client-di2/src/components/bottom-nav.tsx по образцу client/src/components/finance/FinanceBottomNav.tsx (удаляемого — скопировать логику до удаления): три кнопки «Обзор» (дашборд), «Разделы» (dropdown: Доходы, Расходы, Дебиторка, Расчёты, Планирование, Зарплата, Аудит, Прибыльность, Тепловая карта), «Настройки»; видна только <md, контент получает pb-20 md:pb-0, сайдбар на мобильном скрывается (hidden md:flex на обёртке + отключить Sheet-триггер). Переходы — wouter Link (base-aware).
  7. Переключатель темы в хедере DI2 (App.tsx): кнопка Sun/Moon, пишет localStorage['theme'] и дергает перерендер Di2ThemeProvider (через кастомное событие/контекст — проще: Di2ThemeProvider экспортирует контекст с toggleTheme, как основной ThemeProvider).
  8. Хедер/страницы: page-gutter через var(--page-gutter, 1rem) где уместно; крупные заголовки страниц — text-lg font-semibold (как основной клиент).

Этап 4 — Проверка, деплой, документация

  1. npm run check (оба tsc) + npm run build (main → di2 → server) — чисто.
  2. Авторизованный smoke прод-API DI2: /api/di2/dashboard, /api/income/tree-summary, /api/debt/analytics, /api/connection, /api/audit/history — 200.
  3. После деплоя: /finance, /salary, /income → 404/редирект (страниц нет); «Финансы» в Sidebar/MobileBottomNav открывает /di2; /di2 светлая+тёмная, скин организации применяется; мобильная нижняя панель на телефоне.
  4. Документация: AGENTS.md — удалить устаревшие разделы старого модуля (мобильная навигация финансов, деревья категорий, баг дебиторки, Google-флоу /api/finance/google/*) и дописать раздел про /di2 (мост тем, Di2ThemeProvider, нижняя панель); новая Obsidian-заметка Features/2026-09-0X — Finance module replaced by Data-Insight2 subapp.md + ссылка в Agent Guide Index; пометить устаревшей заметку 2026-09-05 — Finance debt calculations audit and Data-Insight2 migration.
  5. Ручной шаг пользователя (вне кода): Google Cloud Console — в OAuth-клиент добавить redirect URI https://iistwin.ru/api/auth/google/callback (нужен для синхронизации зарплаты из Google Sheets в DI2; старый /api/finance/google/callback удаляется вместе с модулем).

Риски и ограничения

  • Удаление lib/format.ts/useFinance.ts — только после grep-подтверждения отсутствия внешних импортов.
  • /api/finance-settings, /api/audit/status, customer-sync/contract-sync, /api/finance/google/* умирают с модулем — потребителей кроме удаляемого UI нет (по разведке).
  • Docker-compose не меняется → бэкап serverfix не нужен; миграций БД нет (iistwin-БД не трогаем; внешняя финансовая БД — только чтение + override-таблицы DI2, которые уже созданы).
  • Если замена хардкод-цветов в графиках сломает читаемость в тёмной теме — вернуть семантические пары вручную (проверить глазами ключевые страницы).