Files
ss-tools/specs/023-clean-repo-enterprise/data-model.md

253 lines
9.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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`