Skill (ru)
# Навык: Создать гостя (iiko)
## Что делает
Создаёт (или обновляет) гостя в iiko на основе пары `cardTrack` + `cardNumber`.
Если гость уже существует, функция возвращает его, а не создаёт нового.
## Входные данные
- `settings: IikoSettings` (настройки клиента, загружаются из переменных окружения)
- `organization_id: str` (необязательный явный iiko loyalty organization id)
- `all_organizations: bool` (если `True`, команда обрабатывает все найденные организации по очереди; иначе по умолчанию использует первую найденную организацию)
- `card_track: str` (track-номер гостя)
- `card_number: str` (номер карты)
- `name: str` (имя гостя; используется как запасной вариант)
- `transport: IikoTransport` (HTTP транспорт; можно подменить для тестов)
- `token_provider: Callable[[IikoSettings], Awaitable[str]]` (по умолчанию `shared.auth.get_access_token`)
В CLI: `--use-local-env` / `--no-use-local-env`; в MCP: аргумент `use_local_env` (см. `IIKO_DEFAULT_USE_LOCAL_ENV`).
## Выходные данные
`dict[str, str]` со структурой:
- Для существующего гостя:
- `status: "existing"`
- `guest_id: <id customer>`
- `name: <существующее имя или предоставленное имя>`
- Для созданного гостя:
- `status: "created"`
- `guest_id: <id customer>`
- `name: <указанное имя>`
## Как работает (реализация)
1. Получает iiko access token через `shared.auth.get_access_token` (или через внедрённый `token_provider`).
2. Разрешает организации:
- использует `organization_id`, если он передан явно
- иначе по умолчанию использует первую найденную организацию
- если `all_organizations=True`, выполняет команду для всех найденных организаций по очереди
3. Делает поиск гостя по `cardTrack` через:
- `shared.customers.get_customer_by_card_track`
- POST `/loyalty/iiko/customer/info`
4. Обрабатывает случай “не найдено”:
- если `IikoApiError.status_code == 404`, считаем это “гость не найден” и идём дальше
- при любой другой ошибке пробрасываем исключение наверх
5. Создаёт/обновляет гостя через:
- `shared.customers.create_customer_with_card_track`
- POST `/loyalty/iiko/customer/create_or_update`
6. Возвращает небольшую структурированную пачку данных, удобную для CLI и для будущих MCP tool output.
## Используемые общие модули
- `src/iiko_api_mcp_server/config.py` (`IikoSettings`)
- `src/iiko_api_mcp_server/shared/auth.py` (`get_access_token`)
- `src/iiko_api_mcp_server/shared/http.py` (`IikoTransport`, маппинг `IikoApiError`)
- `src/iiko_api_mcp_server/shared/customers.py` (поиск и create/update хелперы)
- `src/iiko_api_mcp_server/commands/create_guest.py` (координационная логика)
## Тестирование
Юнит-тесты находятся в:
- `tests/commands/test_create_guest.py`
Тесты проверяют:
- путь для существующего гостя (возвращается `status="existing"` и делается только запрос info)
- путь для создания гостя (404 обрабатывается, затем выполняется create/update)
- по умолчанию при нескольких организациях используется первая найденная организация
- CLI корректно передаёт opt-in флаг `--all-organizations`
В тестах используется `RecordingTransport` и фейковый token provider, чтобы не обращаться к live iiko.
## Чеклист отладки
1. Запустить точечные тесты:
- `python -m pytest tests/commands/test_create_guest.py -v`
2. Если форма запроса выглядит неверно, проверьте `RecordingTransport.calls`.
3. Если упало исключение, проверьте тип:
- `IikoApiError` с `status_code == 404` (ожидаемый сценарий “не найдено”)
- или другой статус (его нужно пробрасывать)