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

10 KiB
Raw Blame History

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() добавить:
    // 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.