Files
iistwin/.superpowers/sdd/di2-embed/task-2-report.md
Ильяс Султанов 23ed1ecf3d DI2 внедрение, таск 2: клиентский субапп Data-Insight2 (client-di2)
- client-di2/: копия фронтенда DI2 + shared/schema.ts, main.tsx обёрнут в wouter Router base=/di2, favicon относительный
- client-di2/tailwind.config.ts (свои токены DI2) подключён через @config в index.css — иначе postcss взял бы корневой конфиг iistwin
- vite.config.di2.ts: base /di2/, root client-di2, outDir dist/public-di2
- package.json: build/check через && включают сборку и typecheck di2 (build:di2, check:di2), новых зависимостей нет
- Навигация финансов: ссылка «Data-Insight (полная версия)» → /di2 (target=_blank) в FinanceSidebar и FinanceBottomNav
- Типовые фиксы предсуществующих ошибок DI2 (casts, ruleLogic в mutation-типах, Set<string>)
2026-09-06 19:46:28 +03:00

47 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Task 2 — Клиентский субапп Data-Insight2 (client-di2): отчёт
## Статус: DONE
## Что создано
### `client-di2/` — копия фронтенда DI2
- `src/` (78 файлов: App.tsx, pages/, components/ + ui/, hooks/, lib/, index.css), `public/favicon.png`, `index.html` — как есть, кроме правок ниже.
- `shared/schema.ts` ← копия `tmp/Data-Insight2/shared/schema.ts`.
- `tsconfig.json` — копия DI2-tsconfig: `include: ["src/**/*", "shared/**/*"]`, `target: ES2022` (сначала забыл — tsc ругался на ES5, добавлено), `strict`, paths `@/*`/`@shared/*` → `./src`, `./shared`, `types: ["node", "vite/client"]`, `tsBuildInfoFile: ../node_modules/typescript/tsbuildinfo-di2` (бриф предлагал `./node_modules/...` — функционально то же, но без мусорной папки client-di2/node_modules).
- `tailwind.config.ts` ← копия DI2-конфига (у DI2 свои токены/радиусы, отличные от iistwin!). Content-глобы: `./client-di2/index.html`, `./client-di2/src/**/*` — **относительно cwd сборки** (npm-скрипты всегда из корня). Вариант `{ relative: true, files: [...] }` относительно конфига проверен — глобы не матчились, утилиты вырезались (css 11 kB, 0 классов `.flex/.grid/...`); с cwd-глобами — 88 kB, утилиты на месте.
- `src/index.css` — добавлена директива `@config "../tailwind.config.ts";` в начало: без неё postcss-плагин tailwindcss от cwd (корень репо) взял бы корневой `tailwind.config.ts` iistwin и вырезал бы стили DI2.
- `src/main.tsx` — обёртка `<Router base="/di2"><App /></Router>` (wouter 3.10, проп `base` поддерживается — проверено в types/router.d.ts и фактической версии node_modules).
- `index.html` — favicon сделан относительным (`href="favicon.png"`), чтобы не 404 на проде; script-src `/src/main.tsx` — дев-режим, vite переписывает при сборке.
### `vite.config.di2.ts` (корень)
Минимальный конфиг: `react()` без replit-плагинов, `base: "/di2/"`, `root: client-di2`, alias `@`/`@shared` → client-di2, `build.outDir: dist/public-di2`, `emptyOutDir: true`. `__BUILD_SHA__` в client-di2 не используется (grep пуст) — define не добавлял. server/fs-секций нет.
### `package.json`
- `build`: `vite build && vite build -c vite.config.di2.ts && esbuild server/index.ts ...` (main client → di2 → server bundle);
- `build:di2`, `check`: `tsc && tsc -p client-di2/tsconfig.json`, `check:di2`.
- **Новых dependencies НЕ добавлено** — все пакеты DI2 (wouter, @tanstack/react-query, radix-набор, recharts, cmdk, vaul, embla, input-otp, date-fns, xlsx, tailwindcss-animate, @tailwindcss/typography и пр.) уже есть в package.json iistwin (проверено скриптом).
### Прочее
- `Dockerfile` — менять не нужно: `RUN npm run build` подхватит новую сборку, `COPY --from=builder /app/dist ./dist` скопирует и public-di2.
- `.gitignore` — `dist` уже игнорируется, не тронут.
- **Навигация финансов**: desktop-список — `client/src/components/finance/FinanceSidebar.tsx` (пункт после navItems, plain `<a href="/di2" target="_blank" rel="noopener">` с иконкой ExternalLink, стили как у Link, поддержка collapsed); мобильная — `client/src/components/finance/FinanceBottomNav.tsx` (пункт в DropdownMenu «Разделы» после категорий, тот же паттерн `<a><DropdownMenuItem>`). Финансовые страницы оборачиваются в FinanceLayout → ссылка появляется на всех экранах финансов.
### Типовые фиксы предсуществующих ошибок DI2 (DI2 под tsx никогда не прогонял tsc)
- `calculations.tsx`: литеральные массивы полей → `as any[]` (2 места), `addCumulativeVat(grouped as any, ...)` — дженерик `groupMonthlyData` выводил T как `{period: string}`.
- `income-categories.tsx` / `expense-categories.tsx`: в типы mutationFn добавлен `ruleLogic?: "and" | "or"` (UI его отправляет, типы отставали).
- `income.tsx` / `expenses.tsx` / `expenses-overview.tsx`: `new Set<string>(...)` для filterableSet (строка не assignable в Set литерального union).
Рантайм-поведение не менялось.
## Проверки
1. `npm run check` — **чисто** (оба tsc: основной + client-di2).
2. `npm run build` — **проходит**: main client (24.9s) → di2 (6.7s, `dist/public-di2/index.html` 2.03 kB, css 88.3 kB, js 1363 kB) → esbuild `dist\index.js` 2.7mb.
3. `ls dist/public-di2/` — `index.html`, `assets/index-*.css`, `assets/index-*.js`, `favicon.png`.
4. `grep -o 'src="[^"]*"' dist/public-di2/index.html` → `src="/di2/assets/index-D5btRW62.js"`, css `href="/di2/assets/index-CLXURD96.css"` — префикс `/di2/` на месте.
5. Стыковка с Task 1: серверный бандл `dist/index.js` лежит рядом с `dist/public-di2` → `path.resolve(import.meta.dirname, "public-di2")` из Task 1 сходится. Статика `/di2` отдастся через express.static + fallback sendFile index.html (глубокие ссылки wouter работают).
## Открытые вопросы / опасения
- Рантайм-smoke в браузере не выполнялся (по брифу достаточно check/build + контроль путей). Первый реальный прогон — на проде после деплоя; если DI2-страница откроется неавторизованной — auth-gate из Task 1 редиректа не делает (вернёт 401 JSON на API, SPA покажет ошибки БД) — стоит глянуть глазами.
- DI2-SPA шрифты грузит с Google Fonts (как в оригинале) — на проде зависит от доступности fonts.googleapis.com.
- CSS предупреждение «A PostCSS plugin did not pass the `from` option» при di2-сборке — косметическое, на выхлоп не влияет.
- Размер di2-бандла 1.36 МБ без код-сплиттинга (как в оригинале DI2) — принято как есть.