Добавлены задачи на сервис подсказок

This commit is contained in:
Раис Юсупалиев
2026-03-28 02:55:23 +03:00
parent 163f379a65
commit 5f6406c712
7 changed files with 8143 additions and 447 deletions
@@ -6,7 +6,7 @@ created: 2026-03-14
---
## Context
Сейчас API поддерживает только `POST /api/v1/delivery/price`. Для нового пользовательского сценария нужен отдельный endpoint `/order`, который создаёт заказ в CDEK по контракту из `http-client.http`.
Сейчас order flow должен принимать уже готовые точные адреса в полях `from_location.address` и `to_location.address`. Для нового пользовательского сценария нужен отдельный endpoint `/order`, который создаёт заказ в CDEK по контракту из `http-client.http`, не выполняя address suggestion lookup внутри order flow.
## Goal
Добавить `POST /api/v1/delivery/order` в существующий controller и существующий service с request/response schemas и error mapping для регистрации заказа в CDEK через adapter contract из задачи `016`.
@@ -17,9 +17,10 @@ created: 2026-03-14
- Новый endpoint должен быть добавлен в существующий controller модуль `app/controllers/v1/delivery.py`; не создавать отдельный controller модуль.
- Логика создания заказа должна быть добавлена в существующий service модуль `app/services/aggregator.py`; не создавать отдельный service модуль.
- Service оркестрирует только вызов injected CDEK order adapter и не содержит business logic или provider HTTP-деталей.
- `from_location.address` и `to_location.address` считаются уже выбранными точными строками адреса; в рамках этой задачи запрещено добавлять address suggestion routing, внешние address lookup вызовы и нормализацию адреса.
- Контракт входного запроса должен соответствовать разделу `Регистрация заказа (тип "доставка", до двери)` из `http-client.http`.
- В scope задачи входят только значения `type=2` и `tariff_code=535`; не расширять поддержку на другие типы заказа и тарифы.
- Scope задачи не включает кеширование, агрегацию тарифов, расчёт стоимости, новые провайдеры и расширение order flow за пределы CDEK.
- Scope задачи не включает `POST /api/v1/delivery/address/suggest`, конфигурацию address suggestion providers, кеширование, агрегацию тарифов, расчёт стоимости, новые провайдеры и расширение order flow за пределы CDEK.
- Не изменять файлы в `spec/`.
## Acceptance criteria
@@ -29,6 +30,7 @@ created: 2026-03-14
- Controller делегирует обработку только в `AggregatorService.create_order()`.
- Service вызывает injected adapter для регистрации заказа и возвращает `OrderCreateResponse` с `provider` и `order_uuid`.
- Логика orchestration размещена в существующем service `app/services/aggregator.py`.
- Endpoint принимает значения `from_location.address` и `to_location.address` как opaque input strings и не выполняет address suggestion lookup перед вызовом adapter.
- Ошибки валидации входного payload возвращают 422, provider request errors маппятся в 400, недоступность CDEK и transport failures — в 503.
- API и service tests покрывают success case и основные failure scenarios.
@@ -0,0 +1,45 @@
---
id: 021
title: Add address suggestion adapter and country provider mapping
status: TODO
created: 2026-03-25
---
## Context
Перед созданием заказа клиенту нужно получить точное значение адреса для полей `from_location.address` и `to_location.address`. Для этого нужен отдельный address suggestion flow с внешним provider, а выбор provider должен определяться по `country_code` через YAML-конфиг.
## Goal
Добавить contract для address suggestion adapters, секцию конфигурации address suggestions с маппингом `country_code -> provider_id` и реализовать интеграцию с `dadata.ru` для стран, сопоставленных с provider id `dadata`.
## Constraints
- Изменения ограничены Adapter layer, config schema/loading и моделями, необходимыми для стабильного adapter contract.
- Внешний IO должен оставаться внутри address suggestion adapter modules.
- В scope задачи входит только интеграция с `dadata.ru`; concrete HTTP integration второго европейского provider не реализовывать в рамках этой задачи.
- Конфигурация должна читаться из `.yaml` и содержать отдельную секцию для address suggestion providers и country mapping.
- Adapter не должен содержать business decisions; он только отправляет запрос, маппит ответ и детерминированно обрабатывает provider/transport errors.
- Не изменять файлы в `spec/`.
- Поищи описание api dadata и следуй её описанию при составлении payload запроса
## Acceptance criteria
- Существует интерфейс `AddressSuggestionProvider` со стабильным контрактом `suggest(request: AddressSuggestRequest) -> list[AddressSuggestion]`.
- В YAML-конфиге добавлена секция address suggestions с настройками `dadata` и маппингом `country_code -> provider_id`.
- Реализован adapter `dadata`, который принимает internal request model и возвращает унифицированный список `AddressSuggestion`.
- Provider-specific поля ответа `dadata` не утекают за пределы adapter contract.
- Ошибки `dadata` класса 4xx маппятся в детерминированную provider request error, а transport/5xx ошибки — в adapter client error.
- Тесты покрывают загрузку конфигурации address suggestions, request/response mapping `dadata` и основные error scenarios.
## Definition of Done
- [ ] Добавлен base contract для address suggestion providers.
- [ ] Добавлена YAML-конфигурация address suggestions и country mapping.
- [ ] Реализован adapter `dadata` для address suggestions.
- [ ] Добавлены config и adapter tests для нового flow.
## Tests
- Обновить `tests/config/test_config_sections.py` для проверки секции address suggestions и маппинга стран на provider id.
- Добавить `tests/adapters/address_suggestions/dadata/test_client.py` для success/error сценариев и mapping.
- Проверить, что наружу возвращается только унифицированная model `AddressSuggestion`.
## Commands
- `poetry run pytest tests/config/test_config_sections.py -q`
- `poetry run pytest tests/adapters/address_suggestions/dadata/test_client.py -q`
- `python3 spec/gen_spec_index.py --check`
@@ -0,0 +1,49 @@
---
id: 022
title: Add address suggestion endpoint
status: TODO
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/address/suggest`, принимающий `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/suggest` в существующем 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`