Skill (en)

# Skill: Check Balance by Track (iiko)

## What it does
Fetches guest wallet balances from iiko by `cardTrack`.

If the guest is not found (iiko returns 404), the function returns an explicit `not_found` result instead of raising.

## Inputs
- `settings: IikoSettings` (client configuration loaded from environment variables)
- `organization_id: str` (optional explicit iiko loyalty organization id)
- `all_organizations: bool` (when `True`, process all discovered organizations one by one; otherwise use the first discovered organization by default)
- `card_track: str` (guest track number)
- `transport: IikoTransport` (HTTP transport; can be mocked for tests)
- `token_provider: Callable[[IikoSettings], Awaitable[str]]` (defaults to `shared.auth.get_access_token`)

CLI also supports `--use-local-env` / `--no-use-local-env`; the MCP tool accepts `use_local_env` (see `IIKO_DEFAULT_USE_LOCAL_ENV`).

## Output
`dict[str, Any]` with one of the following shapes:
- Found guest:
  - `status: "found"`
  - `guest_id: <customer id>`
  - `card_track: <input track>`
  - `wallet_balances: <list>` (best-effort list; empty list if missing/invalid)
- Not found guest:
  - `status: "not_found"`
  - `guest_id: ""`
  - `card_track: <input track>`
  - `wallet_balances: []`

## How it works (implementation)
1. Acquire an iiko access token via `shared.auth.get_access_token` (or injected `token_provider`).
2. Resolve organizations:
   - use `organization_id` if it was provided
   - otherwise use the first discovered organization by default
   - if `all_organizations=True`, run the command for each discovered organization one by one
3. Lookup guest by `cardTrack` using `shared.customers.get_customer_by_card_track`:
   - POST `/loyalty/iiko/customer/info`
4. Handle “not found”:
   - if `IikoApiError.status_code == 404`, return `not_found`
   - for any other status code, re-raise
5. Parse `walletBalances` from the customer payload:
   - if `walletBalances` is a list, return it
   - otherwise, return an empty list

## Shared components used
- `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`, error mapping)
- `src/iiko_api_mcp_server/shared/customers.py` (guest lookup helper)
- `src/iiko_api_mcp_server/commands/check_balance.py` (orchestration logic)

## Testing
Unit tests live in:
- `tests/commands/test_check_balance.py`

The tests validate:
- found guest path (returns `status="found"` and preserves returned `walletBalances`)
- not found path (maps 404 into `status="not_found"` and empty balances)
- first discovered organization is used by default when several organizations are returned
- `--all-organizations` opt-in behavior is passed through the CLI

Tests use an in-memory `RecordingTransport` and a fake token provider to avoid live iiko calls.

## Debugging checklist
1. Run the focused tests:
   - `python -m pytest tests/commands/test_check_balance.py -v`
2. If parsing looks wrong, inspect how `walletBalances` is represented in the payload from `RecordingTransport.responses`.
3. Confirm the “404 => not_found” mapping is happening as expected.