020 update city code resolving
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
---
|
||||
id: 020
|
||||
title: Rename price request model and use cities_map for CDEK codes
|
||||
status: DONE
|
||||
created: 2026-03-21
|
||||
---
|
||||
|
||||
## Context
|
||||
Текущий price flow принимает `DeliveryRequest` со строковыми `from_city` и `to_city`, а также использует внешний lookup города через `_resolve_city_code()` в CDEK client. Новый контракт API переходит на идентификаторы городов и локальный справочник `cities_map`, который хранит provider-specific данные города. Для этого изменения нужен только минимальный набор новых валидаций, необходимый для корректного price flow.
|
||||
|
||||
## Goal
|
||||
Переименовать request model расчёта доставки в `DeliveryCalculationRequest`, перевести поля `from_city` и `to_city` на тип `int`, убрать `country_code` из price API и использовать `cities_map` как источник provider city codes для CDEK tariff request вместо `_resolve_city_code()`, добавив только минимально необходимые валидации для этого перехода.
|
||||
|
||||
## Constraints
|
||||
- Scope задачи ограничен price calculation flow: request schema, controller/service wiring, domain normalization, cache key composition, provider contract и CDEK adapter/client.
|
||||
- `POST /api/v1/delivery/order`, `OrderCreateRequest`, `OrderCreateResponse` и `country_code` внутри order payload не изменять.
|
||||
- Controller не добавляет business rules; Service не реализует provider-specific lookup; pure validation и normalization остаются в Business Logic.
|
||||
- Для расчёта CDEK использовать только локальный `cities_map`; внешний city lookup через CDEK API и `_resolve_city_code()` должен быть удалён из client.
|
||||
- Не требовать полноты `cities_map`; отсутствие записи города или provider-specific данных должно обрабатываться детерминированно.
|
||||
- Учитывать provider-specific структуру `cities_map`, но не реализовывать новых providers в рамках этой задачи.
|
||||
- Новые проверки ограничить минимально необходимыми для работы контракта и CDEK lookup: тип city identifier во входной schema и наличие валидного `cdek.code` для используемого города.
|
||||
- Не добавлять предварительную валидацию всего `cities_map`, проверку неиспользуемых provider sections, проверку `city_uuid`, `full_name`, `label`, `country` или иные дополнительные consistency-checks.
|
||||
- Не добавлять новые range/business validations для city identifier сверх тех, что нужны для поиска города в `cities_map`.
|
||||
- Не изменять файлы в `spec/`, кроме этой задачи, `spec/overview.md` и сгенерированного `spec/index.md`.
|
||||
|
||||
## Acceptance criteria
|
||||
- Модель запроса расчёта переименована в `DeliveryCalculationRequest`; controller, service и provider contract для price flow используют новое имя.
|
||||
- Поля `from_city` и `to_city` в price request принимают целочисленные идентификаторы города; поле `country_code` отсутствует в публичном API расчёта доставки.
|
||||
- Domain normalization и service cache key больше не используют `country_code` и корректно работают с city identifiers.
|
||||
- Новые валидации, добавленные этой задачей, ограничены:
|
||||
- schema-level проверкой, что `from_city` и `to_city` передаются как `int`
|
||||
- runtime-проверкой, что для конкретного city identifier, использованного в CDEK price flow, существует валидный `cdek.code`
|
||||
- CDEK client строит payload `from_location.code` и `to_location.code` на основе `cities_map` и значений `cdek.code` для переданных city identifiers.
|
||||
- Если city identifier отсутствует в `cities_map` или для него нет валидного `cdek.code`, CDEK price flow завершается детерминированной provider request error без внешнего city lookup.
|
||||
- Метод `_resolve_city_code()` и связанный HTTP lookup `location/suggest/cities` удалены из CDEK client; price flow не обращается к CDEK API подсказок городов.
|
||||
- Existing order creation flow и order schemas остаются без изменения.
|
||||
|
||||
## Definition of Done
|
||||
- [ ] Обновлены request schema, controller/service/provider type hints и связанные импорты для нового имени `DeliveryCalculationRequest`.
|
||||
- [ ] Удалён `country_code` из price calculation contract, normalization и cache key.
|
||||
- [ ] Реализован lookup CDEK city codes через `cities_map` без внешнего city suggest API.
|
||||
- [ ] Удалён `_resolve_city_code()` и обновлены adapter tests под новое поведение.
|
||||
- [ ] Добавлены или обновлены tests только для минимально необходимой schema validation, service wiring, cache key и CDEK payload mapping/error scenarios.
|
||||
|
||||
## Tests
|
||||
- Обновить `tests/domain/test_price.py` только для проверки, что normalizer корректно принимает и сохраняет city identifiers без `country_code`.
|
||||
- Обновить `tests/services/test_aggregator.py` для проверки нового request model, отсутствия `country_code` в service flow и обновлённого cache key.
|
||||
- Обновить `tests/controllers/v1/test_delivery.py` только для проверки API schema с `from_city`/`to_city` типа `int` и 422 на невалидные значения типа.
|
||||
- Обновить `tests/adapters/delivery_providers/cdek/test_client.py` для проверки построения payload по `cities_map`, ошибок при отсутствии `cdek.code` или city entry и отсутствия city lookup request.
|
||||
- При необходимости обновить `tests/smoke/test_app_import.py` только для совместимости нового request model с app wiring.
|
||||
|
||||
## Commands
|
||||
- `poetry run pytest tests/domain/test_price.py -q`
|
||||
- `poetry run pytest tests/services/test_aggregator.py -q`
|
||||
- `poetry run pytest tests/controllers/v1/test_delivery.py -q`
|
||||
- `poetry run pytest tests/adapters/delivery_providers/cdek/test_client.py -q`
|
||||
- `poetry run pytest tests/smoke/test_app_import.py -q`
|
||||
- `python3 spec/gen_spec_index.py --check`
|
||||
Reference in New Issue
Block a user