013 add price multiplier

This commit is contained in:
Раис Юсупалиев
2026-03-09 16:14:49 +03:00
parent da301d4bc4
commit 2bd884c8d5
20 changed files with 312 additions and 25 deletions
@@ -0,0 +1,47 @@
---
id: 013
title: Add configurable provider price multiplier in domain logic
status: DONE
created: 2026-03-09
---
## Context
Сейчас `app/domain/price.py` валидирует и сортирует тарифы провайдеров без дополнительной постобработки цены. Появилось новое требование: перед возвратом результата применять к цене провайдера конфигурируемый multiplier из YAML-конфига и округлять итог до целого числа.
## Goal
Добавить в Business Logic детерминированное правило пересчёта `DeliveryPrice.price` через multiplier из секции `business_logic` и провести это значение через конфигурацию и service orchestration без переноса формулы в Service или Adapter.
## Constraints
- Соблюдать layered architecture из `AGENTS.md`.
- Формула умножения и округления должна жить только в `app/domain/`; Service может только передавать нужный параметр и делегировать вызов.
- Значение multiplier должно читаться из YAML-конфига через секцию `business_logic`.
- После применения multiplier цена должна оставаться `Decimal`, но иметь целочисленное значение.
- Правило округления должно быть явным и детерминированным: до `Decimal("1")` c `ROUND_HALF_UP`.
- Не изменять provider adapters, внешние HTTP-контракты и формат ответа кроме нового значения `price`.
- Не изменять файлы в `spec/`.
## Acceptance criteria
- В `business_logic` configuration section добавлено обязательное поле для multiplier цены провайдера с валидацией положительного значения.
- Domain functions применяют multiplier к каждой валидной цене провайдера до сортировки результата.
- Итоговая цена после умножения округляется до целого значения по правилу `ROUND_HALF_UP`.
- Service не содержит формулу расчёта и по-прежнему делегирует обработку цен в domain logic.
- Поведение одинаково для свежих ответов провайдера и для cache hit: в обоих случаях наружу возвращается уже пересчитанная цена.
## Definition of Done
- [ ] Обновлена конфигурация `business_logic` и YAML fixtures/example configs для multiplier.
- [ ] Реализована pure domain logic для пересчёта и округления цены.
- [ ] Service wiring передаёт multiplier в domain logic без добавления business rules в Service.
- [ ] Unit/service/config tests покрывают стандартные и edge-case сценарии.
## Tests
- Обновить `tests/domain/test_price.py` для проверки multiplier, округления `ROUND_HALF_UP`, пустого input и невалидных цен.
- Обновить `tests/services/test_aggregator.py` для проверки делегирования multiplier и одинакового поведения fresh/cache hit.
- Обновить `tests/config/test_config_sections.py` для проверки чтения multiplier из YAML и валидации невалидных значений.
- При необходимости обновить `tests/smoke/test_app_import.py` под обязательное новое поле конфигурации.
## Commands
- `poetry run pytest tests/domain/test_price.py -q`
- `poetry run pytest tests/services/test_aggregator.py -q`
- `poetry run pytest tests/config/test_config_sections.py -q`
- `poetry run pytest tests/smoke/test_app_import.py -q`
- `python3 spec/gen_spec_index.py --check`