docs: add migration plan

This commit is contained in:
2026-09-04 08:16:40 +05:00
parent 6a1c7666c4
commit 6bd1de2669
+206
View File
@@ -0,0 +1,206 @@
# План миграции: единый 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 → страницы → данные
→ деплой/конфиг → проверка.
(Реализацию начинать только по явной команде.)