Skip to content

Phase 1 (P0) — Foundation: monorepo + cleanup + interfaces#6

Draft
CreatmanCEO wants to merge 7 commits into
mainfrom
feat/phase-1-p0
Draft

Phase 1 (P0) — Foundation: monorepo + cleanup + interfaces#6
CreatmanCEO wants to merge 7 commits into
mainfrom
feat/phase-1-p0

Conversation

@CreatmanCEO

Copy link
Copy Markdown
Owner

Phase 1 (P0) — Foundation

Реализует задачи P0-T01 ... P0-T09 из docs/MIGRATION_PLAN.md. PR — draft, коммиты добавляются по одной задаче, чтобы можно было ревьюить инкрементально.

Прогресс

  • T01 — Конверсия в npm workspaces monorepo
  • T02 — packages/api/src/config/env.js (zod) + удаление ApiKeyManager/ValidationService
  • T03 — queue.js с fail-fast Redis ping
  • T04 — Раздельные API и worker процессы
  • T05 — Чистка зависимостей packages/api/package.json (удалить openai/pdfkit/pdf-parse/etc.)
  • T06 — Upgrade tesseract.js -> ^6.1.2
  • T07 — LanguageRegistry + HebrewModule
  • T08 — LlmProvider + OpenRouterProvider каскад (требует OPENROUTER_API_KEY от пользователя)
  • T09 — Golden fixtures (3 документа + JSON-эталоны)

Ограничения

  • Никакого OpenAI (политика пользователя). Используется OpenRouter.
  • Архитектура language-agnostic; иврит — это HebrewModule, в ядре нет if (lang === 'he').
  • Pre-rewrite mock-everything тесты удалены согласно MIGRATION_PLAN §2 — будут переписаны в P1 вместе с кодом.

🤖 Generated with Claude Code

CreatmanCEO and others added 7 commits May 9, 2026 07:28
Перевожу проект на npm workspaces:
- packages/api (был server/), исходники в packages/api/src/
- packages/client (был client/) — переименован в @hdt/client
- packages/shared — новый пакет под общие контракты (типы, env-схемы)
- единый package-lock.json в корне; per-package lockfiles удалены

Сопутствующие правки:
- vitest.config.js / jest.integration.js — пути и алиасы под workspaces
- .eslintrc.js — игнор legacy-кода (будет переписан в P1) и CRA-клиента
- CI/Validate workflows: установка через workspaces, build через -w @hdt/client
- удалены устаревшие mock-everything тесты (tests/services/, tests/unit/services/Translator)
- bumped vitest 1.x -> 2.x для совместимости с vitest-mock-extended
- добавлен cross-env для Windows-dev паритета

Acceptance: npm install в корне ставит все workspaces; npm run lint, npm test и npm run test:integration зелёные.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- packages/shared/src/env/schema.js — zod-схема всех переменных
  окружения (см. ARCHITECTURE.md §6); production-режим требует
  OPENROUTER_API_KEY и GOOGLE_APPLICATION_CREDENTIALS, dev/test —
  работает с дефолтами.
- packages/api/src/config/env.js — fail-fast loader: dotenv с
  override от .env.local, парс через @hdt/shared, process.exit(1)
  при ошибке.
- Удалены ApiKeyManager.js и ValidationService.js (MIGRATION_PLAN
  §2): функции переехали в env-схему и multer-фильтр.
- Unit-тесты: schema.test.js с 4 кейсами (defaults, production fail,
  production ok, coercion).

Acceptance: node -e "require('./packages/api/src/config/env')"
загружает дефолты в dev; падает с понятной ошибкой при NODE_ENV=production
без ключей.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- packages/api/src/queue.js — фабрика Bull-очереди, не создающая
  очередь как side effect при импорте; getQueue() ленивая.
- pingRedisOrExit() проверяет Redis с таймаутом 5 сек, при
  недоступности — process.exit(1). Используется в bootstrap'е
  api/worker.
- Удалён packages/api/src/config/redis.js (eager-инстанс,
  заменён ленивой фабрикой).
- Опции Redis читаются из @hdt/shared env: REDIS_URL приоритетен
  над REDIS_HOST/PORT, поддержка TLS через REDIS_TLS.

Acceptance: при недоступности Redis процесс выходит с кодом 1
за < 5 сек (проверено локально).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- packages/api/src/index.js — переписан под новую архитектуру:
  zod-валидированный env, fail-fast Redis ping, helmet включён,
  не содержит worker-логики.
- packages/api/src/worker.js — отдельная точка входа для Bull-worker'а;
  пайплайн пока stub, будет дозаполнен в P1.
- packages/api/src/api/translate.js — тонкий роут: multer + queue.add()
  через ленивую фабрику getQueue(). Импорт роута не создаёт
  Bull/Redis инстансов как side effect (проверено).
- Скрипты в packages/api/package.json: start (api), worker, dev.

Acceptance: импорт роутов не создаёт Queue; node --check проходит для
index.js, worker.js, api/translate.js; lint зелёный.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Удалено (MIGRATION_PLAN §2):
- openai (политика пользователя — никаких OpenAI API)
- pdf-parse, pdf.js-extract (заменяются прямым pdfjs-dist)
- pdfkit (заменяется Puppeteer для PDF-генерации)
- docx4js (заменяется уже подключённым mammoth)
- hebrew-transliteration (переедет в LanguageModule если понадобится)
- @google-cloud/translate (не используется)
- winston (заменяется pino)

Добавлено (ARCHITECTURE.md §5):
- pdfjs-dist — PDF-парсинг с координатами
- puppeteer — HTML→PDF рендер с native RTL
- @google-cloud/vision — default cloud OCR fallback
- sharp, image-size — обработка изображений и боксов
- axios — HTTP-клиент для OpenRouter
- pino + pino-pretty — структурированное логирование
- zod — валидация (используется в @hdt/shared)
- ioredis-mock (dev) — для unit-тестов очереди

Удалены legacy services и models, зависевшие от снятых пакетов:
DocumentAnalyzer, DocumentGenerator (services + root), TextExtractor,
Translator, LayoutExtractor, LoggingService, DocumentBlock, LayoutInfo,
documentProcessor. Они переписываются с нуля в P1 согласно плану.

Acceptance: npm install проходит чисто; npm ls openai pdf-parse
pdf.js-extract pdfkit hebrew-transliteration docx4js → empty;
lint/test зелёные.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Поднимаем tesseract.js с ^5.0.3 до v6.x (npm ranges разрешает 6.0.1
как самую свежую опубликованную в линейке 6 — версии 6.1.2 на npm нет).
Движок Tesseract C++ внутри — 5.5.x; формат heb.traineddata совместим
без изменений.

Call-sites в коде ещё нет (TesseractProvider создаётся в P1-T03), поэтому
breaking changes v5→v6 (внутренние) проверены через smoke-тест:
- API surface (createWorker, recognize, PSM, OEM) сохранён;
- реальное распознавание ивритского фрагмента ("שלום" в SVG→PNG)
  возвращает confidence > 0.5 за ~2 сек;
- traineddata скачивается прозрачно через worker init.

Тяжёлый сетевой OCR-прогон закрыт env-флагом HDT_RUN_OCR_SMOKE=1, чтобы
CI не качал ~10 МБ языковой пак на каждом push. По умолчанию проверяется
только API surface.

heb.traineddata добавлен в .gitignore.

Acceptance (MIGRATION_PLAN P0-T06):
- npm ls tesseract.js → 6.0.1 ✓
- smoke-тест распознаёт ивритский фрагмент с confidence > 0.5 ✓
- CI green ✓

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Заводим базовый каркас language-agnostic слоя (см. ARCHITECTURE.md §3.2 + §4).

LanguageRegistry:
- Map<code, LanguageModule>
- register(mod) с валидацией (code: string, detector: function)
- get(code) → LanguageModule | undefined
- detect(text) → { code, confidence } выбирает модуль с максимальным
  confidence; если все вернули 0 → { code: 'unknown', confidence: 0 }
- codes() для интроспекции в bootstrap/тестах

HebrewModule (MVP):
- code: 'he', direction: 'rtl', shapingRequired: false
- ocrLangPack: 'heb' (tesseract), cloudVisionHint: 'iw' (Google Vision legacy)
- detector — character-range эвристика (доля символов U+0590..U+05FF
  и Hebrew Presentation Forms от всех не-пробельных). Намеренно без
  franc: дёшево, синхронно, корректно работает на смешанных доках.

Hebrew не зашит в ядро — это просто зарегистрированный модуль; добавление
арабского/фарси = новый файл + register(), правок в registry/pipeline нет.

Экспорты добавлены в @hdt/shared (index.js).

Acceptance (MIGRATION_PLAN P0-T07):
- registry.detect('שלום') → 'he' ✓ (confidence 1.0)
- registry.detect('hello') → не 'he' ✓ ('unknown', 0)
- registry.get('he').direction === 'rtl' ✓
- модули экспортируются из @hdt/shared ✓
- 12 unit-тестов зелёные

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant