--- id: 022 title: Add address suggestion endpoint status: DONE created: 2026-03-25 --- ## Context Перед реализацией order flow клиенту нужен отдельный endpoint, который возвращает подсказки адреса и позволяет выбрать точное значение для `from_location.address` и `to_location.address`. Выбор provider должен происходить по `country_code` через конфигурационный маппинг стран. ## Goal Добавить `POST /api/v1/delivery/address/suggest` в существующий controller и существующий service с request/response schemas, routing на address suggestion provider по `country_code` и детерминированным HTTP error mapping. ## Constraints - Controller отвечает только за DTO validation, routing и mapping service exceptions в HTTP responses. - Endpoint должен вызывать ровно один метод Service: `AggregatorService.suggest_addresses()`. - Новый endpoint должен быть добавлен в существующий controller модуль `app/controllers/v1/delivery.py`; не создавать отдельный controller модуль. - Логика provider selection должна быть добавлена в существующий service модуль `app/services/aggregator.py`; не создавать отдельный service модуль. - Service выбирает provider по `country_code` через injected config mapping и вызывает ровно один address suggestion adapter; provider HTTP-детали в Service запрещены. - Scope задачи не включает создание заказа CDEK, изменение `POST /api/v1/delivery/order`, расчёт стоимости доставки, cache behavior и concrete HTTP integration европейского provider. - Не изменять файлы в `spec/`. ## Acceptance criteria - Существует endpoint `POST /api/v1/delivery/suggest-address`, принимающий `AddressSuggestRequest` и возвращающий `list[AddressSuggestion]`. - Реализованы request/response schemas `AddressSuggestRequest` и `AddressSuggestion`. - Endpoint реализован в существующем controller `app/controllers/v1/delivery.py`. - Controller делегирует обработку только в `AggregatorService.suggest_addresses()`. - Service определяет provider по `country_code` через конфигурационный маппинг и вызывает только соответствующий registered adapter. - Если `country_code` отсутствует в маппинге или сопоставлен с незарегистрированным provider, endpoint возвращает детерминированный 400 response. - Provider request errors маппятся в 400, недоступность внешнего сервиса и transport failures — в 503. - Service и controller/API tests покрывают как минимум сценарии: route в `dadata`, route в второй provider через test double, unsupported country и provider failure. ## Definition of Done - [ ] Добавлены address suggestion request/response schemas. - [ ] Реализован метод `AggregatorService.suggest_addresses()` для provider routing и orchestration. - [ ] Реализован endpoint `POST /api/v1/delivery/address-address` в существующем controller. - [ ] Добавлены service и controller/API tests для address suggestion flow. ## Tests - Добавить `tests/services/test_address_suggestions.py` для проверки routing по `country_code`, unsupported country, незарегистрированного provider и provider failures. - Добавить `tests/controllers/v1/test_address_suggestions.py` для success case, schema validation и HTTP mapping ошибок. - При необходимости обновить `tests/smoke/test_app_import.py` для проверки подключения нового endpoint и service wiring без новых controller/service модулей. - Использовать test doubles для address suggestion adapters. ## Commands - `poetry run pytest tests/services/test_address_suggestions.py -q` - `poetry run pytest tests/controllers/v1/test_address_suggestions.py -q` - `poetry run pytest tests/smoke/test_app_import.py -q` - `python3 spec/gen_spec_index.py --check`