feat(v2): m007 cassette_configs schema + Pydantic models (#29 v1)
Add the operator-side schema for per-machine ATM cassette inventory (aiolabs/satmachineadmin#29). Schema choice mirrors the ATM-side denomination-as-key invariant audited at coord-log 2026-05-30T06:40Z across bitspire/atm-tui/src/db.zig:31, lamassu-next state-store.ts:54, and hal-service.ts:116/189 — every ATM layer keys on denomination, so the operator-side PK is (machine_id, denomination) to make duplicate-denomination payloads impossible at the schema boundary. Reserved nullable columns (state_count, state_at, state_event_id) hold the latest bitspire-cassettes-state:<atm_pubkey_hex> event the ATM publishes. v1 populates them on bootstrap-event receipt; v1 UI doesn't render reconciliation. v2 reconciliation UI consumes them without a migration. Pydantic models in this commit: - CassetteConfig — read model for a stored row - UpsertCassetteConfigData — operator-edit form (count and/or position) - CassettePayloadRow — one denomination's wire-format values - PublishCassettesPayload — the full kind-30078 content payload, bidirectional (operator → ATM and ATM → operator share the shape). Validates int-coerced denomination keys, positive ints, no duplicate positions, and exposes to_wire_dict() that re-stringifies keys for JSON compatibility. CRUD + transport + API + UI land in subsequent commits. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
58a0974117
commit
13684e7134
2 changed files with 161 additions and 0 deletions
|
|
@ -538,3 +538,40 @@ async def m005_lock_deposit_currency_to_machine_fiat_code(db):
|
|||
AND m.fiat_code != d.currency
|
||||
)
|
||||
""")
|
||||
|
||||
|
||||
async def m007_add_cassette_configs(db):
|
||||
"""Add cassette_configs table for operator-driven ATM cassette inventory.
|
||||
|
||||
Tracks per-machine cassette state (denomination, count, position) editable
|
||||
via the satmachineadmin dashboard and published to the ATM as encrypted
|
||||
kind-30078 events. See aiolabs/satmachineadmin#29 + lamassu-next#56.
|
||||
|
||||
Schema choice: PK (machine_id, denomination) mirrors the ATM-side
|
||||
denomination-as-key invariant in
|
||||
bitspire/atm-tui/src/db.zig:31 and
|
||||
lamassu-next/apps/machine/electron/state-store.ts:54
|
||||
(the cassettes table PK is denomination; HAL inventory map keys on
|
||||
denomination; dispense lookup is cassetteDenominations.indexOf —
|
||||
duplicates collapse silently). Position is operator-assignable display
|
||||
order, not the addressable unit.
|
||||
|
||||
Reserved nullable columns (state_count, state_at, state_event_id) hold
|
||||
the latest bitspire-cassettes-state:<atm_pubkey_hex> event the ATM
|
||||
publishes (one-shot bootstrap in v1; continuous in v2). v1 UI doesn't
|
||||
render them; v2 reconciliation UI consumes them without a migration.
|
||||
"""
|
||||
await db.execute(f"""
|
||||
CREATE TABLE IF NOT EXISTS satoshimachine.cassette_configs (
|
||||
machine_id TEXT NOT NULL,
|
||||
denomination INTEGER NOT NULL,
|
||||
count INTEGER NOT NULL,
|
||||
position INTEGER NOT NULL,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT {db.timestamp_now},
|
||||
updated_by TEXT,
|
||||
state_count INTEGER,
|
||||
state_at TIMESTAMP,
|
||||
state_event_id TEXT,
|
||||
PRIMARY KEY (machine_id, denomination)
|
||||
);
|
||||
""")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue