refactor(v2): cassette consumer + API endpoint — position-keyed (#29 v1.1)

API endpoint:
  - api_publish_machine_cassettes validates incoming payload.positions
    set matches stored cassette_configs.position set (was: denomination
    set match). Error message updated to "slot count is hardware-fixed
    — re-provision the ATM via atm-tui to add/remove physical bays."
  - Per-row upsert loop iterates payload.positions and passes
    UpsertCassetteConfigData(denomination=, count=) — operator edits
    denomination + count for a fixed slot.

Bootstrap consumer task: just a log-message field rename (now reports
"N cassettes" from len(payload.positions) instead of len(payload.
denominations)). Per-event handler already routes through the
transport's decrypt_and_parse_state_event, which returns a
PublishCassettesPayload that's now position-keyed via the model.

Tests still red until commit f.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Padreug 2026-05-30 22:26:55 +02:00
commit 34e324b4c5
2 changed files with 33 additions and 31 deletions

View file

@ -453,7 +453,7 @@ async def _handle_cassette_state_event(
if applied:
logger.info(
f"satmachineadmin: applied bootstrap state event {event_id[:12]}... "
f"to machine {machine.id} ({len(payload.denominations)} cassettes)"
f"to machine {machine.id} ({len(payload.positions)} cassettes)"
)
else:
# Replay: event_id already on file. Normal on relay reconnect.