Andrey Epifancev db7df33517 chore(openspec): архив change slice-0-skeleton
Срез 0 реализован и влит (PR #3), change перенесён в openspec/changes/archive, спеки — в openspec/specs.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-04 19:44:37 +04:00

32 lines
2.5 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.

# audit-trail Specification
## Purpose
Все действия из enum `audit_action` пишутся в `audit_event` одним способом — через сервис аудита; журнал только
дополняется, записи неизменяемы (ТЗ 8.2).
## Requirements
### Requirement: Единая точка записи
Сервис аудита SHALL предоставлять метод записи события с полями `action` (из enum `audit_action`), `section`
(из `audit_section`), `object_type`, `object_id`, `user_id` (NULL для системных действий), `consolidation_version_id`,
`description`, `before_value`, `after_value` (jsonb), `comment`, `result`, `changed_field`, `ip_address`, `user_agent`;
`occurred_at` SHALL проставляться сервером (UTC). Запись SHALL выполняться в той же транзакции, что и изменение данных.
NOTE: В Срезе 0 обмен через recognition_job аудит не пишет (рулинг R-7, design #20); сервис готов к использованию Срезом 2+.
#### Scenario: Системное событие
- **WHEN** системный процесс (без пользователя) вызывает сервис аудита
- **THEN** в `audit_event` появляется строка с `user_id = NULL`, `before_value`/`after_value` содержат старый и новый статус
#### Scenario: Откат транзакции
- **WHEN** изменение данных и запись аудита выполняются в одной транзакции, и она откатывается
- **THEN** строка `audit_event` не сохраняется
### Requirement: Журнал только дополняется
ORM-модель `audit_event` MUST NOT использоваться для `UPDATE` или `DELETE` в коде ядра; тест SHALL проверять, что в
`src/` нет обращений, изменяющих или удаляющих `audit_event`, а сервис аудита не имеет методов изменения.
#### Scenario: Попытка изменить запись
- **WHEN** код вызывает обновление строки `audit_event` через сервис аудита
- **THEN** такого метода нет (ошибка на этапе типизации/теста), запись остаётся прежней