diff --git a/client/src/components/finance/FinanceBottomNav.tsx b/.superpowers/sdd/di2-restyle/FinanceBottomNav.reference.tsx similarity index 100% rename from client/src/components/finance/FinanceBottomNav.tsx rename to .superpowers/sdd/di2-restyle/FinanceBottomNav.reference.tsx diff --git a/.superpowers/sdd/di2-restyle/ledger.md b/.superpowers/sdd/di2-restyle/ledger.md new file mode 100644 index 0000000..8140d48 --- /dev/null +++ b/.superpowers/sdd/di2-restyle/ledger.md @@ -0,0 +1,8 @@ +# SDD ledger — plan: di2-restyle + +BASE: 6bcf4df + +- [ ] Этап 1 — удаление старого модуля финансов +- [ ] Этап 2 — мост тем/скинов +- [ ] Этап 3 — визуальный рестайл +- [ ] Этап 4 — проверка, деплой, документация diff --git a/.superpowers/sdd/di2-restyle/plan.md b/.superpowers/sdd/di2-restyle/plan.md new file mode 100644 index 0000000..b5c4dc0 --- /dev/null +++ b/.superpowers/sdd/di2-restyle/plan.md @@ -0,0 +1,90 @@ +# План: удаление старого модуля финансов + рестайл 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` и пункт «Финансы» в меню профиля → внешняя ссылка `` (паттерн как в 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) / )`), скины 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` + слушатель. +- На ``: `data-skin`, `data-theme`, класс `light|dark`; для кастомного скина — `