Files
rubber-duck-mcp/docs/migration-plan.md
T
2026-09-04 08:16:40 +05:00

207 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.
# План миграции: единый SvelteKit-проект + типизированный eval
> Статус: **утверждён для проработки** (запуск реализации — по отдельной команде).
> Последнее обновление: 2026-09-04
---
## 1. Общая цель
Убрать избыточное разделение на два проекта и перевести всё в **один SvelteKit-проект**
на Vercel, а eval-harness — с JavaScript (`.mjs`) на **TypeScript**, с **общими типами**
между eval и сайтом.
Итог: один домен, один деплой, один контракт данных для отчётов (он не «ломается»,
потому что eval и рендер сидят на одних типах).
---
## 2. Целевая архитектура
### 2.1. Общий пакет типов — `packages/types`
Workspace-пакет `@duck/types`, используемый и eval, и `apps/web`.
```txt
packages/types/
package.json # name: "@duck/types" (через pnpm pkg)
tsconfig.json
src/index.ts # общий контракт
```
Типы (защищают контракт отчёта):
- `Task { id, question, answer }`
- `ScenarioName = "control" | "blind" | "mentor"`
- `ScenarioSummary { tasks, reviewed, correct, accuracy, pending, duckUsed, toolCalls, avgCalls }`
- `PerTaskRow { id, scenario, correct: boolean|null, duckUsed, toolCalls, promptTokens, genTokens, duckTokens, response, expected, question }`
- `ModelReport`, `ReportRoot { generatedAt, mcpUrl, prompts, models, aggregate, reviewedAt? }`
- `Reviews` (контракт `review.json`)
Роль: и `apps/eval` при записи `out/report.json`, и `apps/web` при рендере `/reports`
используют эти типы. Рассогласование схемы → ошибка на этапе компиляции, а не падение в проде.
### 2.2. Приложение — `apps/web` (единственный деплой на Vercel)
```txt
apps/web/ # SvelteKit + TypeScript + @sveltejs/adapter-vercel
src/routes/
+layout.svelte # общий nav-каркас
+page.svelte # / — домашняя (заглушка «скоро»)
/mcp/+page.svelte # /mcp — описание MCP + FAQ/README
/reports/+page.svelte # /reports — полные отчёты (рендер из report.json)
/api/mcp/+server.ts # /api/mcp — MCP endpoint (mcp-handler)
src/lib/
mcp.ts # перенос из apps/mcp/lib/mcp.ts
reports.ts # рендер-хелперы на базе @duck/types
static/report.json # коммитится — источник для /reports
```
**Домен:** `rubber-duck-mcp.vercel.app` — единственный. Всё на нём:
- `/` → домашняя
- `/mcp` → описание
- `/reports` → отчёты
- `/api/mcp` → MCP endpoint
### 2.3. Eval — типизация в TS
```txt
apps/eval/
src/*.ts # run, runner, report, review, report-html (из .mjs)
lib/mcpClient.ts # (из lib/mcpClient.mjs)
lib/ollama.ts # (из lib/ollama.mjs)
tsconfig.json
out/report.json # генерируется (НЕ коммитится)
data/tasks.json # (как есть)
```
---
## 3. Все решённые вопросы (закрытые решения)
| Вопрос | Решение |
| --------------------- | --------------------------------------------------------------------------------------- |
| Домен | единый `rubber-duck-mcp.vercel.app` |
| Куда класть SvelteKit | новая папка `apps/web` |
| Линковка Vercel | перелинковать существующий project `mcp` на `apps/web` (домен сохр.) |
| Frontend-домен | удалить `rubber-duck-frontend.vercel.app` и Vercel-проект `frontend` |
| `report.json` в проде | коммитить в `apps/web/static/report.json` |
| Страница `/reports` | полный формат (сводные таблицы по моделям + разбивка по задачам) |
| MCP-фреймворк | mcp-handler совместим с SvelteKit (web-standard `(Request) => Response`), Next не нужен |
| Язык eval | TypeScript + общий пакет типов |
---
## 4. Изменение запуска (было → стало)
Сейчас (JS):
```bash
node src/run.mjs
node src/review.mjs
node src/report-html.mjs
```
Стало (TS): компиляция не требуется для dev — запуск через `tsx`:
```bash
# apps/eval
tsx src/run.ts
tsx src/review.ts
tsx src/report-html.ts
```
Скрипты в `apps/eval/package.json` и корневом `package.json` (`eval:*`) обновляются на `tsx`.
Добавляется:
- **typecheck**: `tsc --noEmit` для eval и web (контракт не ломается).
- dev-зависимости eval: `tsx`, `typescript`, `@types/node`.
---
## 5. Шаги реализации (поэтапно)
### Шаг 1 — `packages/types`
- Создать workspace-пакет `@duck/types` (манифест через `pnpm pkg`).
- Написать `src/index.ts` с общим контрактом + `tsconfig.json`.
- Убедиться, что pnpm-workspace (`packages: apps/*`) знает про `packages/*`.
### Шаг 2 — eval → TypeScript
- Переименовать `lib/*.mjs``.ts`, `src/*.mjs``.ts`.
- Подключить `@duck/types`, поправить импорты.
- Добавить `tsconfig.json`, зависимости (`tsx`, `typescript`, `@types/node`) через `pnpm pkg`/`pnpm add`.
- Обновить скрипты запуска (`eval:*``tsx ...`).
- Проверка: `tsc --noEmit` + короткий прогон `tsx src/run.ts --limit 1`.
### Шаг 3 — `apps/web` (SvelteKit)
- Инициализировать SvelteKit + TypeScript + `@sveltejs/adapter-vercel`.
- Подключить `@duck/types`.
### Шаг 4 — Перенос MCP
- `apps/mcp/lib/mcp.ts``apps/web/src/lib/mcp.ts`.
- `apps/mcp/app/api/mcp/route.ts``apps/web/src/routes/api/mcp/+server.ts`
(mcp-handler принимает `Request` → из SvelteKit передаём `event.request`).
- Убедиться, что `runtime = "nodejs"` задан.
### Шаг 5 — Страницы
- `+layout.svelte` — навигация;
- `/` — заглушка «скоро» (дизайн позже);
- `/mcp` — описание + FAQ + README (перенести текст из старой `page.tsx`);
- `/reports``load` из `static/report.json` через `lib/reports.ts` на общих типах;
рендер карточек/таблиц переиспользует логику и стили из `report-html.mjs`.
### Шаг 6 — Данные
- Скопировать `apps/eval/out/report.json``apps/web/static/report.json` и закоммитить.
- Добавить команду «sync отчёта на сайт» (копирует report.json после прогона eval).
### Шаг 7 — Деплой/конфиг
- `apps/web/package.json` + корневой: `dev`, `build`, `deploy``apps/web`;
`eval:*``tsx`; убрать `deploy-mcp`, `deploy-frontend`.
- Удалить `apps/frontend` + скрипты + Vercel-проект/домен frontend.
- Удалить `apps/mcp` (Next) после переноса.
- Перелинковать Vercel-проект `mcp` на `apps/web`; проверить, что домен назначен на проект.
### Шаг 8 — Проверка
- `tsc --noEmit` (eval + web).
- `pnpm dev` → проверить страницы и `/api/mcp`.
- `vercel --prod` → verify на домене: `/`, `/mcp`, `/reports`, `/api/mcp` (quack).
---
## 6. Что НЕ делаем сейчас
- Детальный дизайн страниц/домашней (делаем позднее, отдельно).
- Автоматическое обновление `report.json` на каждый прогон (только sync-команда).
- Расширенное наполнение FAQ/README (только перенос базового текста).
---
## 7. Риски и митигация
| Риск | Митигация |
| -------------------------------------------- | ------------------------------------------------------------------------- |
| `mcp-handler` под Next | фреймворк-агностичен (web-standard Request/Response), проверено по `d.ts` |
| Нужна компиляция для запуска eval | dev — `tsx`; при необходимости `tsc build` для prod-скриптов |
| Несовместимость схемы отчёта | общие типы `@duck/types` + `tsc --noEmit` в eval и web |
| Необратимое удаление Vercel-проектов | frontend/mcp удаляем аккуратно, после успешного переноса |
| `report.json` рассинхронизируется с прогоном | явная команда sync + коммит |
---
## 8. Порядок выполнения
Поэтапно, с проверкой на каждом шаге:
`packages/types` → eval-TS → `apps/web` (скелет) → перенос MCP → страницы → данные
→ деплой/конфиг → проверка.
(Реализацию начинать только по явной команде.)