Files
iistwin/.superpowers/sdd/di2-embed/task-1-brief.md
Ильяс Султанов 254950f151 DI2 внедрение, таск 1: серверная интеграция Data-Insight2 (server/finance-di2)
- Копия DI2-сервера в server/finance-di2/ с правками: schema/db-client/cache/table-config/override-tables/google-auth/audit-agent/routes
- db-client — обёртка над существующим пулом server/finance/db-client (второй пул не создаётся, добавлен экспорт isConnectionError)
- ai-config.ts — чистое IO конфигов из ai-agent.ts без Telegram-поллинга; роуты /api/ai/toggle и /api/ai/status удалены, без compression/startAuditScheduler/autoStartIfEnabled
- Обёртка registerDi2Routes с auth-gate (authenticateToken + finance.manage), регистрация строго перед registerFinanceRoutes
- Статика /di2 из dist/public-di2 перед веткой vite/static (dev и prod)
- Фикс предсуществующего бага DI2: buildGlobalExclusionConditions без cats в /api/profitability
2026-09-06 19:27:43 +03:00

60 lines
10 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 1 — Серверная интеграция Data-Insight2
Цель: перенести серверную часть DI2 (`C:\1Ai\1iistwin\tmp\Data-Insight2\server`) в `server/finance-di2/` репозитория `C:\1Ai\1iistwin\1Project`, обёрнуть в авторизацию iistwin и зарегистрировать роуты ДО старого модуля финансов. Клиент НЕ входит в задачу (Task 2), но добавь зависимость `node-cron` (DI2 audit-agent.ts импортирует cron вверху файла; планировщик мы не запускаем, но импорт должен резолвиться). НЕ меняй `scripts.build` в package.json (это Task 2).
## Источник (только чтение)
- `C:\1Ai\1iistwin\tmp\Data-Insight2\server\`: routes.ts (6387 строк), cache.ts, table-config.ts, override-tables.ts, google-auth.ts, audit-agent.ts (477 строк), db-client.ts, storage.ts (5 строк).
- `C:\1Ai\1iistwin\tmp\Data-Insight2\shared\schema.ts` (366 строк, чистые типы/константы, без drizzle).
## Что создать в 1Project
1. **`server/finance-di2/`** — копии файлов DI2 с правками:
- `schema.ts` ← копия `tmp/Data-Insight2/shared/schema.ts` (типы и константы).
- `db-client.ts` — НЕ копировать DI2-версию. Написать обёртку, которая импортирует из `../finance/db-client` (iistwin): `query, testConnection, getConfig, setConfig, isConnectionError` и экспортирует их же + `getPoolClient` (проверь, что `server/finance/db-client.ts` экспортирует все эти имена; если `getPoolClient` отсутствует — добавь его туда, а не дублируй пул: открой файл и посмотри, есть ли там pool — экспортируй существующий). Формат конфига (data/db-config.json) идентичен — это тот же код по происхождению.
- `cache.ts`, `table-config.ts`, `override-tables.ts` — копии без изменений (проверь их импорты: они должны ссылаться на `./db-client` и `./schema` — исправь алиасы).
- `google-auth.ts` — копия с правкой `getRedirectUri()`: вместо `process.env.REPLIT_DOMAINS` использовать `process.env.APP_BASE_URL || "https://iistwin.ru"`, redirect `${APP_BASE_URL}/api/auth/google/callback`. Протокол всегда https.
- `ai-config.ts` — НОВЫЙ файл: вырезать из `tmp/Data-Insight2/server/ai-agent.ts` только чистые функции IO без Telegram/поллинга: `loadAiConfig`, `saveAiConfig`, `loadAiPlanningConfig`, `saveAiPlanningConfig` (файлы data/ai-config.json, data/ai-planning-config.json), а также `getAiLog`, `saveLogEntry` (посмотри их реализацию в ai-agent.ts — обычно append в json/jsonl; перенеси как есть, включая нужные интерфейсы AiConfig/AiPlanningConfig). Без cron, без fetch, без Telegram.
- `audit-agent.ts` — копия, но удалить `startAuditScheduler` и его вызовы (cronJob и импорт node-cron не нужны, если импорт только для этой функции — проверь: если cron используется только в startAuditScheduler, удали импорт и функцию целиком; тогда node-cron в package.json НЕ нужен — не добавляй). Оставить `runIntegrityAudit`, `getAuditHistory`.
- `routes.ts` — копия с такими правками:
- Импорт `dbConnectionSchema` с `./schema` (не `@shared/schema`).
- Удалить `import compression from "compression"` и `app.use(compression());` (строка ~1142).
- Строку 1371 `const {...} = await import("./ai-agent")` заменить на импорт из `./ai-config`: нужны только `loadAiConfig, saveAiConfig, loadAiPlanningConfig, saveAiPlanningConfig, getAiLog, saveLogEntry`.
- Удалить роуты `app.post("/api/ai/toggle", ...)` и `app.get("/api/ai/status", ...)` (используют startPolling/stopPolling/isPolling).
- Удалить вызов `autoStartIfEnabled();` (~строка 1508).
- В конце: удалить `startAuditScheduler();` (строка 6384), оставить `scheduleTreeRebuild();`.
- Проверь, что в routes.ts больше нет ссылок на ai-agent, compression, node-cron (grep).
- Проверь остальные импорты вверху routes.ts: `./storage` (5-строчный файл — перенеси тоже, если импортируется), `./override-tables`, `./table-config`, `./cache`, `./google-auth`, `./audit-agent` — все становятся `./xxx` внутри finance-di2 (уже так).
- `index.ts` — НОВЫЙ файл-обёртка `registerDi2Routes(app: Express)`:
- Создать `express.Router()`.
- Middleware на роутере: если `req.path` начинается с одного из префиксов DI2 — пропустить через `authenticateToken` затем `requirePermission('finance.manage')` (импорт из `../middleware/auth.middleware`), иначе `next()`.
- Префиксы: `/api/income`, `/api/income-categories`, `/api/expenses`, `/api/expense-categories`, `/api/debt`, `/api/dashboard`, `/api/profitability`, `/api/heatmap`, `/api/planning`, `/api/salary`, `/api/audit`, `/api/calculations`, `/api/connection`, `/api/db`, `/api/table-config`, `/api/table-settings`, `/api/overrides`, `/api/tags`, `/api/tag-assignments`, `/api/cache`, `/api/refresh-all`, `/api/admin`, `/api/auth/google`, `/api/ai`, `/api/telegram`.
- Затем вызвать DI2 `registerRoutes(httpServer, router as any)` — передав `null as any` вместо httpServer (он используется только в `return httpServer` в конце). Функция async — await. Затем `app.use(router)` — но НЕ сmount-префиксом, роуты абсолютные.
- ВАЖНО порядок middleware: `router.use(authGate)` должен стоять ПЕРЕД регистрацией роутов DI2, и все DI2-роуты регистрируются на этом же роутере.
2. **`server/routes/index.ts`**: добавить `await registerDi2Routes(app);` строкой НЕПОСРЕДСТВЕННО ПЕРЕД `await registerFinanceRoutes(app);` (строка 113). Импорт добавь рядом с импортом registerFinanceRoutes (строка 33).
3. **`server/index.ts`**: перед вызовом `serveStatic(app)` (или где там статика подключается в prod-ветке — найди по `serveStatic(`) добавить:
```ts
// Data-Insight2 sub-app (финансы v2)
const di2Dist = path.resolve(import.meta.dirname, "public-di2");
if (fs.existsSync(di2Dist)) {
app.use("/di2", express.static(di2Dist));
app.use("/di2", (_req, res) => res.sendFile(path.resolve(di2Dist, "index.html")));
}
```
(проверь, какие импорты path/fs уже есть в index.ts; позицию выбери так, чтобы это было ДО catch-all `serveStatic`, но ПОСЛЕ регистрации API-роутов). В dev-режиме (setupVite) тоже должен работать: setupVite вешает `app.use("*")` — проверь порядок: если setupVite вызывается в dev ПОСЛЕ нашего блока, то /di2/* уйдёт в main index.html. Чтобы dev тоже работал, добавь этот блок ПЕРЕД веткой `if (process.env.NODE_ENV === "development") setupVite(...) else serveStatic(app)` (найди эту ветку и вставь до неё). Проверь наличие fs/path импортов.
4. **package.json**: если audit-agent оставил импорт cron — добавь `node-cron` в dependencies (проверь версию из DI2 package.json). Если импорт удалён — не добавляй. `scripts.build` НЕ трогать.
## Проверки (обязательно выполнить и приложить вывод)
1. `grep -rn "ai-agent\|compression\|REPLIT" server/finance-di2/` — пусто.
2. `npx tsc --noEmit` (корневой check) — без ошибок в server/finance-di2 (ошибки в других местах, если были до тебя, не считаются; проверь baseline сначала: `git stash` не нужен — просто сравни с ошибками на BASE, если есть новые — чини).
3. `npm run build` должен пройти (клиентская часть di2 ещё не создана — это нормально, build собирает только main client; сборка di2 будет в Task 2). Если build падает из-за твоих изменений — чини.
4. Быстрый smoke-тест сервера без Docker: запустить `npm run dev` не надо (трогает БД продакшена локально? нет — локальный dev стучится в локальную БД; НЕ запускай дев-сервер). Достаточно typecheck+build.
## Контракт отчёта
Напиши файл `C:\1Ai\1iistwin\1Project\.superpowers\sdd\di2-embed\task-1-report.md`: что скопировано, какие правки, вывод grep-проверок, вывод tsc/build (последние строки), открытые вопросы. Верни: статус, список коммитов, одну строку по проверкам, опасения.
## Жёсткие ограничения
- Код/комментарии — на русском (существующие DI2-комментарии не переводить обратно, оставь как есть).
- Не трогай `server/finance/*` кроме случая, когда нужно экспортировать getPoolClient (добавь экспорт существующего пула, не создавай второй пул).
- Не коммить изменения в tmp/Data-Insight2.
- Pre-push hook прогоняет check+build — коммить в main.