feat(machine): add SQLite persistence and remove npub linking
Add crash-safe persistence for cassette inventory, cashbox state, and transaction history using better-sqlite3 in the Electron main process. The state machine now loads inventory from the database at runtime instead of using hardcoded values, and transactions are automatically persisted on completion. Remove the unnecessary npub linking code — Lightning.Pub auto-creates and associates Nostr users when appId is included in RPC requests, making the HTTP-based user creation and token linking redundant. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
722635a5a6
commit
f37555565e
15 changed files with 739 additions and 171 deletions
|
|
@ -103,11 +103,22 @@ export function createATMMachine(services: Partial<ATMServices> = {}) {
|
|||
),
|
||||
getInventory: fromPromise(async () => {
|
||||
if (!services.getInventory) {
|
||||
// Return mock inventory if service not provided
|
||||
return { 20: 50 } as Record<number, number>
|
||||
return {} as Record<number, number>
|
||||
}
|
||||
return services.getInventory()
|
||||
}),
|
||||
getRateAndInventory: fromPromise(async ({ input }: { input: string }) => {
|
||||
if (!services.getExchangeRate) {
|
||||
throw new Error('getExchangeRate service not provided')
|
||||
}
|
||||
const [exchangeRate, inventory] = await Promise.all([
|
||||
services.getExchangeRate(input),
|
||||
services.getInventory
|
||||
? services.getInventory()
|
||||
: Promise.resolve({} as Record<number, number>),
|
||||
])
|
||||
return { exchangeRate, inventory }
|
||||
}),
|
||||
/**
|
||||
* Callback actor that watches an invoice for payment
|
||||
* Sends PAYMENT_RECEIVED when the invoice is paid
|
||||
|
|
@ -140,8 +151,9 @@ export function createATMMachine(services: Partial<ATMServices> = {}) {
|
|||
}),
|
||||
},
|
||||
actions: {
|
||||
resetContext: assign(() => ({
|
||||
resetContext: assign(({ context }) => ({
|
||||
...initialContext,
|
||||
inventory: context.inventory,
|
||||
cashInSessionId: null,
|
||||
})),
|
||||
setStartTime: assign({
|
||||
|
|
@ -494,12 +506,13 @@ export function createATMMachine(services: Partial<ATMServices> = {}) {
|
|||
states: {
|
||||
fetchingRate: {
|
||||
invoke: {
|
||||
src: 'getExchangeRate',
|
||||
src: 'getRateAndInventory',
|
||||
input: ({ context }) => context.currency,
|
||||
onDone: {
|
||||
target: 'selectingAmount',
|
||||
actions: assign({
|
||||
exchangeRate: ({ event }) => event.output,
|
||||
exchangeRate: ({ event }) => event.output.exchangeRate,
|
||||
inventory: ({ event }) => event.output.inventory,
|
||||
}),
|
||||
},
|
||||
onError: {
|
||||
|
|
|
|||
|
|
@ -144,8 +144,8 @@ export const initialContext: ATMContext = {
|
|||
cashDispensed: false,
|
||||
dispenseAmounts: [],
|
||||
cashOutSelection: [],
|
||||
// Mock inventory: $20 bills only for Phase 1
|
||||
inventory: { 20: 50 },
|
||||
// Populated at runtime from DB (empty = no cassettes loaded yet)
|
||||
inventory: {},
|
||||
userNpub: null,
|
||||
error: null,
|
||||
retryCount: 0,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue