Дозакрыты находки ревью по слиянию сущностей
- Правило покрытия получило второй разряд (условный, как у точек), запрет вырождения формы и счёт содержательных элементов ряда: скелет из скаляров и ряд из null больше не затирают маршрут. Победитель внутри доставки стал функцией множества версий — общим помощником с точками, — а провенанс поднимается и при совпавшем хеше, иначе отложенная доставка возвращала витрину к прежнему содержимому. - Одно поле не того типа больше не уносит сущность, а пропуски видны в учётной записи доставки (миграция 00008, NULL = «не измерялось»); каноническая форма считается один раз и вне транзакции; откат бинаря поверх новой схемы отказывает на старте; текст ошибки разбора не несёт значений из тела. - Ревью кода профилем deep (девять проходов) нашло две регрессии и обе закрыты: безусловный второй разряд запирал законный досчёт навсегда, а выбор победителя был квадратичен по числу присланных версий одного ключа.
This commit is contained in:
@@ -7,9 +7,7 @@
|
||||
принятое, что происходит с несвёрнутым при остановке и рестарте. Цена ошибки
|
||||
здесь наивысшая в проекте — доставка, не попавшая в архив и в журнал, не
|
||||
восстанавливается: телефон её не перешлёт.
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: Ответ приёма отражает сохранность, а не разбор
|
||||
|
||||
Приём SHALL отвечать `200` после того, как тело записано в сырой архив и
|
||||
@@ -302,3 +300,24 @@ NOT: факт уходит в `DEBUG`, приём продолжается.
|
||||
|
||||
- **WHEN** запрос идёт не на приём
|
||||
- **THEN** его бюджет записи ответа остаётся общим `write_timeout`
|
||||
|
||||
### Requirement: Отказ учёта доставки называет класс причины
|
||||
|
||||
Система SHALL логировать отказ, случившийся **после** того, как тело легло в архив, но до появления учётной записи, так, чтобы владелец отличал **занятость базы** от прочих причин. Различается именно занятость: у неё уже есть доменная ошибка, и она означает конкуренцию за запись, которая будет повторяться.
|
||||
|
||||
Расширять признак до «обстоятельств вообще» система MUST NOT, хотя предикат с таким смыслом в проекте есть: он включает ещё и отмену работы снаружи, а на этом пути отмена невозможна по построению — учёт ведётся на контексте, переживающем обрыв соединения. Назвать отменённую работу занятостью базы значило бы отправить владельца искать конкуренцию там, где её нет.
|
||||
|
||||
Уровень при этом остаётся `ERROR` независимо от класса: тело лежит в архиве без
|
||||
учётной записи, то есть осиротело, и вернуть его в журнал может только
|
||||
пересборка. Занятость базы этого не отменяет — она объясняет причину, а не
|
||||
снимает работу. Смысл различения в другом: занятость означает конкуренцию за
|
||||
запись, которая будет повторяться и лечится не тем же, чем лечится сбой диска
|
||||
или испорченная база.
|
||||
|
||||
#### Scenario: Занятая база при учёте доставки видна как отдельный класс
|
||||
|
||||
- **WHEN** запись учёта доставки не проходит из-за занятости базы
|
||||
- **THEN** отказ логируется на уровне `ERROR` вместе с путём тела в архиве
|
||||
- **AND** запись отличает занятость базы от прочих причин отказа
|
||||
- **AND** тот же отказ по другой причине этого признака не несёт
|
||||
|
||||
|
||||
Reference in New Issue
Block a user