Phase 1 (P0) — Foundation: monorepo + cleanup + interfaces#6
Draft
CreatmanCEO wants to merge 7 commits into
Draft
Phase 1 (P0) — Foundation: monorepo + cleanup + interfaces#6CreatmanCEO wants to merge 7 commits into
CreatmanCEO wants to merge 7 commits into
Conversation
Перевожу проект на 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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phase 1 (P0) — Foundation
Реализует задачи P0-T01 ... P0-T09 из
docs/MIGRATION_PLAN.md. PR — draft, коммиты добавляются по одной задаче, чтобы можно было ревьюить инкрементально.Прогресс
packages/api/src/config/env.js(zod) + удаление ApiKeyManager/ValidationServicequeue.jsс fail-fast Redis pingpackages/api/package.json(удалить openai/pdfkit/pdf-parse/etc.)tesseract.js->^6.1.2LanguageRegistry+HebrewModuleLlmProvider+OpenRouterProviderкаскад (требуетOPENROUTER_API_KEYот пользователя)Ограничения
HebrewModule, в ядре нетif (lang === 'he').🤖 Generated with Claude Code