VEU.WathBody/1-docs/4-modules/m03-program-store/api_specs/01-lifecycle.md

57 lines
3.4 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.

# Спецификация: жизненный цикл программы (EnsureProgram, CreateDraft, Activate, Archive)
> Сервис `ProgramStore` (`Server.WatchBody.Core\Programs\`); работа —
> через репозитории m01. Ошибки — `ProgramStoreException(message)`.
## 1. `EnsureProgram(int athleteId, string title)` → `Program`
Создаёт программу атлета при отсутствии (UNIQUE(athlete_id) — одна на
атлета), иначе возвращает существующую. `title` — только при создании.
| # | Тест | Ожидание |
|---|---|---|
| 1 | первый вызов | программа создана (title как задан) |
| 2 | повторный вызов с другим title | возвращена та же программа (id не меняется, title не перезаписывается) |
## 2. `CreateDraft(int athleteId, string body, string author, string rationale, int? basedOnVersion = null)` → `ProgramVersion`
Новая draft-версия. `basedOnVersion = null` → явное значение = актуальная
максимальная версия (цепочка истории); число валидируется против
существующих. `author` ∈ `user | admin | rules` (`llm` — v2, иначе
ошибка). `body` — непустой (не валидируется по схеме, v1). Тело после
создания не меняется (🛡); `version = max+1` считает БД.
| # | Тест | Ожидание |
|---|---|---|
| 3 | первая версия атлета без программы | созданы `program` и версия 1 (draft, based_on = NULL) |
| 4 | вторая версия | version = 2, based_on_version = 1 |
| 5 | author = "llm" | ошибка (v2) |
| 6 | author = "rules" | создана (для m05) |
| 7 | basedOnVersion = 5 при max = 2 | ошибка (цепочка нарушена) |
| 8 | пустой body | ошибка |
| 9 | два draft подряд | version 3 и 4, обе draft (активация — отдельно) |
## 3. `Activate(int athleteId, Guid versionId)` → `void`
`draft → active`; прежняя активная версия программы (если была) →
`archived` (БД гарантирует ровно одну). Не-draft версия → ошибка; чужая
версия атлета → ошибка (изоляция).
| # | Тест | Ожидание |
|---|---|---|
| 10 | активация draft при активной v1 | v1 → archived, v2 → active; `GetActive` = v2 |
| 11 | активация первой версии (активной не было) | единственная active |
| 12 | активация archived-версии | ошибка (🛡 переходы только вперёд) |
| 13 | повторная активация уже активной | ошибка (не draft) |
| 14 | активация чужой версии | ошибка |
## 4. `Archive(int athleteId, Guid versionId)` → `void`
`active → archived` (например, атлет хочет остаться без активной
программы). Не-active → ошибка.
| # | Тест | Ожидание |
|---|---|---|
| 15 | архивация активной | archived, `GetActive` → null |
| 16 | архивация draft | ошибка |