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

6.8 KiB
Raw Blame History

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) — принято как есть.