- Правило покрытия получило второй разряд (условный, как у точек), запрет вырождения формы и счёт содержательных элементов ряда: скелет из скаляров и ряд из null больше не затирают маршрут. Победитель внутри доставки стал функцией множества версий — общим помощником с точками, — а провенанс поднимается и при совпавшем хеше, иначе отложенная доставка возвращала витрину к прежнему содержимому. - Одно поле не того типа больше не уносит сущность, а пропуски видны в учётной записи доставки (миграция 00008, NULL = «не измерялось»); каноническая форма считается один раз и вне транзакции; откат бинаря поверх новой схемы отказывает на старте; текст ошибки разбора не несёт значений из тела. - Ревью кода профилем deep (девять проходов) нашло две регрессии и обе закрыты: безусловный второй разряд запирал законный досчёт навсегда, а выбор победителя был квадратичен по числу присланных версий одного ключа.
22 lines
2.6 KiB
Markdown
22 lines
2.6 KiB
Markdown
## ADDED Requirements
|
|
|
|
### Requirement: Отказ учёта доставки называет класс причины
|
|
|
|
Система SHALL логировать отказ, случившийся **после** того, как тело легло в архив, но до появления учётной записи, так, чтобы владелец отличал **занятость базы** от прочих причин. Различается именно занятость: у неё уже есть доменная ошибка, и она означает конкуренцию за запись, которая будет повторяться.
|
|
|
|
Расширять признак до «обстоятельств вообще» система MUST NOT, хотя предикат с таким смыслом в проекте есть: он включает ещё и отмену работы снаружи, а на этом пути отмена невозможна по построению — учёт ведётся на контексте, переживающем обрыв соединения. Назвать отменённую работу занятостью базы значило бы отправить владельца искать конкуренцию там, где её нет.
|
|
|
|
Уровень при этом остаётся `ERROR` независимо от класса: тело лежит в архиве без
|
|
учётной записи, то есть осиротело, и вернуть его в журнал может только
|
|
пересборка. Занятость базы этого не отменяет — она объясняет причину, а не
|
|
снимает работу. Смысл различения в другом: занятость означает конкуренцию за
|
|
запись, которая будет повторяться и лечится не тем же, чем лечится сбой диска
|
|
или испорченная база.
|
|
|
|
#### Scenario: Занятая база при учёте доставки видна как отдельный класс
|
|
|
|
- **WHEN** запись учёта доставки не проходит из-за занятости базы
|
|
- **THEN** отказ логируется на уровне `ERROR` вместе с путём тела в архиве
|
|
- **AND** запись отличает занятость базы от прочих причин отказа
|
|
- **AND** тот же отказ по другой причине этого признака не несёт
|