# Data Model: Clean Repository Enterprise Preparation ## Overview Модель данных описывает сущности, необходимые для подготовки и контроля enterprise clean-поставки в изолированном контуре без внешнего интернета. --- ## 1) ReleaseCandidate **Purpose**: Представляет конкретный релиз-кандидат, проходящий clean-подготовку и compliance-проверку. ### Fields - `candidate_id` (string, required, unique) Уникальный идентификатор релиз-кандидата. - `version` (string, required) Версия/метка релиза. - `profile` (enum, required) Допустимые значения: `enterprise-clean`, `development`. - `created_at` (datetime, required) - `created_by` (string, required) Идентификатор оператора/сервиса, создавшего candidate. - `source_snapshot_ref` (string, required) Ссылка на исходный снимок/состояние для воспроизводимости. - `status` (enum, required) `draft`, `prepared`, `compliant`, `blocked`, `released`. ### Validation Rules - `candidate_id` и `source_snapshot_ref` не могут быть пустыми. - Для `profile=enterprise-clean` переход в `released` разрешён только после `compliant`. - Переходы статусов должны быть монотонными по lifecycle (без недетерминированных откатов). --- ## 2) CleanProfilePolicy **Purpose**: Формальная политика классификации артефактов и источников ресурсов для enterprise clean-профиля. ### Fields - `policy_id` (string, required, unique) - `policy_version` (string, required) - `active` (boolean, required) - `prohibited_artifact_categories` (array[string], required) Примеры: `test-data`, `demo-data`, `load-test`, `sample-repository`. - `required_system_categories` (array[string], required) Примеры: `system-init`, `security-bootstrap`, `schema-migrations`. - `external_source_forbidden` (boolean, required; для enterprise-clean = true) - `internal_source_registry_ref` (string, required) Ссылка на реестр внутренних серверов. - `effective_from` (datetime, required) - `effective_to` (datetime, optional) ### Validation Rules - Политика не может быть активирована без `internal_source_registry_ref`. - Одновременная активность двух политик для одного профиля и периода запрещена. - Для `enterprise-clean` поле `external_source_forbidden` всегда `true`. --- ## 3) ResourceSourceRegistry **Purpose**: Реестр разрешённых внутренних серверов компании, используемых для загрузки всех ресурсов. ### Fields - `registry_id` (string, required, unique) - `name` (string, required) - `entries` (array[ResourceSourceEntry], required, min=1) - `updated_at` (datetime, required) - `updated_by` (string, required) - `status` (enum, required) `active`, `inactive`. ### ResourceSourceEntry (nested) - `source_id` (string, required, unique within registry) - `host` (string, required) - `protocol` (enum, required) `http`, `https`, `ssh`, `file`. - `purpose` (string, required) Например: `artifact-repo`, `package-mirror`, `git-mirror`. - `allowed_paths` (array[string], optional) - `enabled` (boolean, required) ### Validation Rules - В `entries` запрещены дубликаты `host + purpose`. - При `status=active` должен существовать хотя бы один `enabled=true` entry. - Внешние публичные хосты не допускаются в активном реестре enterprise clean-профиля. --- ## 4) DistributionManifest **Purpose**: Зафиксированный состав итогового дистрибутива для аудита и воспроизводимости. ### Fields - `manifest_id` (string, required, unique) - `candidate_id` (string, required, FK -> ReleaseCandidate) - `policy_id` (string, required, FK -> CleanProfilePolicy) - `generated_at` (datetime, required) - `generated_by` (string, required) - `items` (array[ManifestItem], required) - `summary` (ManifestSummary, required) - `deterministic_hash` (string, required) ### ManifestItem (nested) - `path` (string, required) - `category` (string, required) - `classification` (enum, required) `required-system`, `allowed`, `excluded-prohibited`. - `reason` (string, required) - `checksum` (string, optional for included items) ### ManifestSummary (nested) - `included_count` (integer, required, >=0) - `excluded_count` (integer, required, >=0) - `prohibited_detected_count` (integer, required, >=0) ### Validation Rules - `candidate_id` и `policy_id` должны ссылаться на существующие записи. - `deterministic_hash` должен быть одинаковым для идентичного входного состояния. - `included_count + excluded_count` должно совпадать с размером `items`. --- ## 5) ComplianceCheckRun **Purpose**: Один запуск проверки соответствия clean/compliance для релиз-кандидата. ### Fields - `check_run_id` (string, required, unique) - `candidate_id` (string, required, FK -> ReleaseCandidate) - `policy_id` (string, required, FK -> CleanProfilePolicy) - `started_at` (datetime, required) - `finished_at` (datetime, optional) - `final_status` (enum, required) `running`, `compliant`, `blocked`, `failed`. - `triggered_by` (string, required) - `execution_mode` (enum, required) `tui`, `ci`. - `checks` (array[CheckStageResult], required) ### CheckStageResult (nested) - `stage` (enum, required) `data_purity`, `internal_sources_only`, `no_external_endpoints`, `manifest_consistency`. - `status` (enum, required) `pass`, `fail`, `skipped`. - `details` (string, optional) - `duration_ms` (integer, optional, >=0) ### Validation Rules - `final_status=compliant` допускается только при `pass` для всех обязательных стадий. - `final_status=blocked` обязателен при `fail` хотя бы одной обязательной стадии. - `execution_mode=ci` и `execution_mode=tui` должны быть сопоставимы по policy/version. --- ## 6) ComplianceViolation **Purpose**: Нормализованная запись конкретного нарушения, найденного в ходе проверки. ### Fields - `violation_id` (string, required, unique) - `check_run_id` (string, required, FK -> ComplianceCheckRun) - `category` (enum, required) `data-purity`, `external-source`, `manifest-integrity`, `policy-conflict`, `operational-risk`. - `severity` (enum, required) `critical`, `high`, `medium`, `low`. - `location` (string, required) Путь/endpoint/конфигурационный ключ. - `evidence` (string, optional) - `remediation` (string, required) - `blocked_release` (boolean, required) - `detected_at` (datetime, required) ### Validation Rules - Для `category=external-source` поле `blocked_release` всегда `true` в enterprise clean-профиле. - Для `severity=critical` поле `remediation` обязательно и непустое. - `check_run_id` должен ссылаться на существующий запуск проверки. --- ## 7) ComplianceReport **Purpose**: Финальный отчёт проверки для оператора и аудита. ### Fields - `report_id` (string, required, unique) - `check_run_id` (string, required, FK -> ComplianceCheckRun) - `candidate_id` (string, required) - `generated_at` (datetime, required) - `operator_summary` (string, required) - `structured_payload_ref` (string, required) Ссылка на машинно-читаемое представление. - `violations_count` (integer, required, >=0) - `blocking_violations_count` (integer, required, >=0) ### Validation Rules - `blocking_violations_count` ≤ `violations_count`. - При `final_status=blocked` в связанном check run `blocking_violations_count` > 0. - Отчёт должен быть доступен для экспортирования из TUI сценария. --- ## Relationships 1. `ReleaseCandidate` 1—N `DistributionManifest` 2. `CleanProfilePolicy` 1—N `DistributionManifest` 3. `ReleaseCandidate` 1—N `ComplianceCheckRun` 4. `CleanProfilePolicy` 1—N `ComplianceCheckRun` 5. `ComplianceCheckRun` 1—N `ComplianceViolation` 6. `ComplianceCheckRun` 1—1 `ComplianceReport` 7. `ResourceSourceRegistry` 1—N `CleanProfilePolicy` (по ссылке active policy) --- ## State Model Highlights ### ReleaseCandidate lifecycle `draft -> prepared -> compliant -> released` `draft|prepared -> blocked` (при нарушениях) ### ComplianceCheckRun lifecycle `running -> compliant|blocked|failed` --- ## TUI Mapping Notes (from UX reference) Состояния TUI из [`ux_reference.md`](./ux_reference.md) напрямую маппятся на сущности: - `READY` -> `ReleaseCandidate.status in {draft, prepared}` - `RUNNING` -> `ComplianceCheckRun.final_status = running` - `COMPLIANT` -> `ComplianceCheckRun.final_status = compliant` + `ComplianceReport` - `BLOCKED` -> `ComplianceCheckRun.final_status = blocked` + `ComplianceViolation[*].blocked_release=true`