# ADR: Layer mapping LegacyHUB ↔ platform CONVENTIONS Status: accepted · 2026-06-15 · scope: `legacy-knowledge-indexer` ## Контекст Платформенный `CONVENTIONS.md` описывает каноничную структуру pattern-B модуля: ``` app/{main, config, db, api, models, repositories, services, integrations, workers} ``` Исторический layout LegacyHUB сложился вокруг доменов обработки (`ingestion`, `indexing`, `storage`), а не вокруг технических слоёв. Имена папок не совпадают с конвенцией, но **доменные слои присутствуют**. ## Решение Не переименовывать рабочие пакеты. Зафиксировать маппинг документально. Перекладка проверенного OCR/Markdown/Search-кода ради совпадения имён — риск регрессий без функциональной выгоды (governance: размер/имя изменения не повод для рефактора). Новые платформенные слои (`integrations/`, аудит) добавлены явно. | Канон CONVENTIONS | Фактический пакет | Назначение | |---|---|---| | `main` | `app/main.py` | FastAPI composition shell, CORS, middleware, lifespan | | `config` | `app/config.py` | pydantic-settings, единственный читатель env | | `db` | `app/db/session.py` | engine + `session_scope` транзакция | | `models` | `app/db/models.py` | ORM (`documents`, `chunks`, `asset_ingest_jobs`, `audit_log`, …) | | `repositories` | `app/db/models.py` + `app/db/audit.py` + `app/storage/artifacts.py` | data-access; запись `audit_log` на write через `record_audit` | | `services` | `app/ingestion/*` + `app/indexing/*` | бизнес-пайплайн: OCR → извлечение → chunk → index → search | | `integrations` | `app/integrations/` (`identity`, `dispatch_client`) | seam к шлюзу/SSO и шине dispatch | | `workers` | `app/workers/` | Celery app + tasks (внутримодульный фон на Redis) | | (infra/helpers) | `app/storage/*`, `app/utils/*` | MinIO/S3, hashing, language, pdf, text | ## Аудит на write `CONVENTIONS` и `03_INTEGRATION_STANDARDS §10` требуют запись в `audit_log` в той же транзакции, что и мутация. Реализация: `app/db/audit.py::record_audit(db, …)` вызывается внутри активного `session_scope`. Покрытые write-операции: - `knowledge_ingest.register_verified_manifest` → `asset.ingest.registered` - `routes_ingestion.ingest_folder` → `ingest.folder.queued` - (P4) переиндексация и purge проекций → `asset.reindex` / `asset.projection.purged` ## Слой/границы Соблюдается направление `shell → router → service → repository/infra`. Feature-код не импортирует composition shell. Кросс-доменные обращения идут через `integrations/`. ## Последствия - Onboarding-ревьюер сверяет слои по этой таблице, а не по именам папок. - Будущий вынос `ingestion`/`indexing` в shared-core (см. `docs/ADR-shared-core.md`) не меняет этот маппинг — ядро становится зависимостью слоя `services`.