78 lines
6.7 KiB
Markdown
78 lines
6.7 KiB
Markdown
# api-contract-generation Specification
|
||
|
||
## Purpose
|
||
|
||
Определяет единый, проверяемый контракт HTTP API между backend и frontend, исключающий ручное расхождение типов и маршрутов.
|
||
|
||
## Requirements
|
||
|
||
### Requirement: Backend публикует машиночитаемый API-контракт
|
||
Backend SHALL публиковать версионированный OpenAPI-документ, описывающий доступные HTTP-маршруты, параметры, тела запросов, ответы и ошибки API `/api/v1`.
|
||
|
||
#### Scenario: Разработчик получает контракт API
|
||
- **WHEN** backend запущен в локальной среде разработки
|
||
- **THEN** разработчик может получить OpenAPI-документ для генерации frontend-клиента
|
||
|
||
### Requirement: Frontend использует сгенерированный API-клиент
|
||
Frontend SHALL хранить в репозитории версионируемый snapshot опубликованного OpenAPI-документа и генерировать transport types из этого snapshot. Команда синхронизации MUST получать документ из backend, а затем обновлять snapshot и сгенерированный результат только при успешном завершении всего процесса. Сгенерированный результат MUST храниться в frontend-репозитории.
|
||
|
||
#### Scenario: API-контракт синхронизируется
|
||
- **WHEN** разработчик запускает команду синхронизации при доступном backend с валидным OpenAPI-документом
|
||
- **THEN** frontend обновляет versioned snapshot и сгенерированные transport types из опубликованного контракта
|
||
|
||
#### Scenario: API-контракт изменяется
|
||
- **WHEN** backend меняет опубликованный API-контракт
|
||
- **THEN** frontend может синхронизировать snapshot и повторно сгенерировать transport types до интеграции изменения
|
||
|
||
#### Scenario: Синхронизация контракта завершается ошибкой
|
||
- **WHEN** backend недоступен или публикует невалидный OpenAPI-документ
|
||
- **THEN** команда завершается с ошибкой и существующие snapshot и сгенерированные transport types не изменяются
|
||
|
||
### Requirement: Frontend не зависит от OpenAPI во время работы
|
||
Работающий frontend MUST использовать ранее сгенерированные transport types и MUST NOT требовать доступность Swagger или OpenAPI endpoint во время запуска, выполнения пользовательского сценария или локальной проверки актуальности generated artifact. Доступ к backend OpenAPI endpoint разрешён только команде синхронизации snapshot и отдельной read-only runtime-contract command.
|
||
|
||
#### Scenario: OpenAPI endpoint недоступен после сборки frontend
|
||
- **WHEN** frontend уже собран, а endpoint OpenAPI временно недоступен
|
||
- **THEN** frontend продолжает использовать сгенерированный код для запросов к API
|
||
|
||
#### Scenario: Локальная проверка выполняется без backend
|
||
- **WHEN** разработчик запускает локальный frontend quality gate
|
||
- **THEN** проверка актуальности generated artifact использует сохранённый snapshot и не обращается к OpenAPI endpoint
|
||
|
||
#### Scenario: Разработчик проверяет runtime-контракт
|
||
- **WHEN** разработчик запускает отдельную runtime-contract command
|
||
- **THEN** command может поднять изолированный local backend только для сравнения
|
||
его полного runtime OpenAPI document с committed frontend snapshot и не
|
||
обновляет ни один из артефактов
|
||
|
||
### Requirement: Отдельная команда обнаруживает runtime drift OpenAPI
|
||
Runtime-contract command MUST получать полный OpenAPI document от изолированного
|
||
local backend по `/api/docs-json`, рекурсивно canonicalize порядок JSON object
|
||
keys, сохраняя каждое field и array order, и сравнивать его SHA-256 с canonical
|
||
committed frontend snapshot. При любом content mismatch она MUST завершаться
|
||
ошибкой и показывать diff. Verification MUST NOT вызывать snapshot
|
||
synchronization command или записывать committed OpenAPI либо generated type
|
||
artifacts.
|
||
|
||
#### Scenario: Runtime success status отличается от committed snapshot
|
||
- **WHEN** backend runtime OpenAPI описывает response status, отличный от
|
||
committed frontend snapshot
|
||
- **THEN** runtime-contract command завершается ошибкой с diff и оставляет
|
||
snapshot и generated types без изменений
|
||
|
||
#### Scenario: Runtime OpenAPI совпадает с committed snapshot
|
||
- **WHEN** каждое field canonical runtime document совпадает с canonical
|
||
committed frontend snapshot
|
||
- **THEN** runtime-contract stage завершается успешно без изменения frontend files
|
||
|
||
### Requirement: Frontend обнаруживает дрейф сгенерированного контракта
|
||
Frontend SHALL проверять, что committed generated transport types соответствуют versioned OpenAPI snapshot, и MUST завершать quality gate с ошибкой при расхождении.
|
||
|
||
#### Scenario: Generated artifact устарел
|
||
- **WHEN** OpenAPI snapshot изменён, а generated transport types не обновлены
|
||
- **THEN** проверка контракта завершается с ошибкой
|
||
|
||
#### Scenario: Generated artifact изменён вручную
|
||
- **WHEN** generated transport types отличаются от результата генерации из сохранённого snapshot
|
||
- **THEN** проверка контракта завершается с ошибкой
|