diff --git a/apps/api/prisma/migrations/20261026120000_drop_tab_snapshots/migration.sql b/apps/api/prisma/migrations/20261026120000_drop_tab_snapshots/migration.sql new file mode 100644 index 0000000..5275970 --- /dev/null +++ b/apps/api/prisma/migrations/20261026120000_drop_tab_snapshots/migration.sql @@ -0,0 +1,4 @@ +-- The terminals used to own the tabs and report them as snapshots; the server holds them in "Tab" now +DROP TABLE "OpenTabSnapshot"; + +DROP TABLE "TabOwnership"; diff --git a/apps/api/prisma/schema.prisma b/apps/api/prisma/schema.prisma index 6ee63b6..d6f24b0 100644 --- a/apps/api/prisma/schema.prisma +++ b/apps/api/prisma/schema.prisma @@ -15,7 +15,6 @@ model Venue { devices Device[] clientUsers ClientUser[] - tabOwnerships TabOwnership[] remoteCommands RemoteCommand[] auditLogs AuditLog[] regCodes RegistrationCode[] @@ -43,9 +42,7 @@ model Device { revokedAt DateTime? createdAt DateTime @default(now()) - venue Venue @relation(fields: [venueId], references: [id]) - tabSnapshots OpenTabSnapshot[] - tabOwnerships TabOwnership[] + venue Venue @relation(fields: [venueId], references: [id]) remoteCommands RemoteCommand[] tabEvents TabEvent[] settlements Settlement[] @@ -81,38 +78,6 @@ model RegistrationCode { @@index([venueId]) } -model OpenTabSnapshot { - id String @id @default(uuid()) - deviceId String - tabId String - customerName String - version Int - totalInCents Int - itemCount Int - // The tab's lines as reported by the terminal: [{ productName, quantity, unitPriceInCents }]. - // Null for terminals running an app version that doesn't report them. - items Json? - reportedAt DateTime - - device Device @relation(fields: [deviceId], references: [id]) - - @@unique([deviceId, tabId]) - @@index([deviceId]) - @@index([tabId, reportedAt]) -} - -model TabOwnership { - tabId String - venueId String - deviceId String - lastReportedAt DateTime - - venue Venue @relation(fields: [venueId], references: [id]) - device Device @relation(fields: [deviceId], references: [id]) - - @@id([venueId, tabId]) -} - // A request from the dashboard. close_tab used to be executed by the owning terminal; the server now settles // the tab itself and records the command as completed right away, for the history. model RemoteCommand { diff --git a/apps/api/prisma/seed.js b/apps/api/prisma/seed.js index 563928e..c34d47f 100644 --- a/apps/api/prisma/seed.js +++ b/apps/api/prisma/seed.js @@ -5,13 +5,41 @@ const crypto = require('crypto'); const prisma = new PrismaClient(); +// One line with itemCount units, priced so the tab adds up to about totalInCents +async function createTab(venueId, tab) { + const lineId = uuidv4(); + const addedAt = tab.reportedAt.toISOString(); + await prisma.tab.create({ + data: { + venueId, + id: tab.tabId, + customerName: tab.customerName, + openedAt: tab.reportedAt, + version: tab.version, + lines: [{ + id: lineId, + productId: null, + productName: 'Pils', + unitPriceInCents: Math.round(tab.totalInCents / tab.itemCount), + units: Array.from({ length: tab.itemCount }, (_, i) => ({ id: `${lineId}:${i}`, addedAt, removedAt: null })), + }], + }, + }); +} + async function main() { console.log('Seeding database...'); await prisma.auditLog.deleteMany(); + await prisma.tabEvent.deleteMany(); + await prisma.tabReminder.deleteMany(); + await prisma.plannedTab.deleteMany(); await prisma.remoteCommand.deleteMany(); - await prisma.openTabSnapshot.deleteMany(); - await prisma.tabOwnership.deleteMany(); + await prisma.settlement.deleteMany(); + await prisma.tab.deleteMany(); + await prisma.stockAdjustment.deleteMany(); + await prisma.product.deleteMany(); + await prisma.productImage.deleteMany(); await prisma.refreshToken.deleteMany(); await prisma.registrationCode.deleteMany(); await prisma.device.deleteMany(); @@ -92,12 +120,7 @@ async function main() { ]; for (const tab of tabsData) { - await prisma.tabOwnership.create({ - data: { tabId: tab.tabId, venueId, deviceId: device1Id, lastReportedAt: tab.reportedAt }, - }); - await prisma.openTabSnapshot.create({ - data: { deviceId: device1Id, tabId: tab.tabId, customerName: tab.customerName, version: tab.version, totalInCents: tab.totalInCents, itemCount: tab.itemCount, reportedAt: tab.reportedAt }, - }); + await createTab(venueId, tab); } const staleTabs = [ @@ -106,15 +129,10 @@ async function main() { ]; for (const tab of staleTabs) { - await prisma.tabOwnership.create({ - data: { tabId: tab.tabId, venueId, deviceId: device2Id, lastReportedAt: tab.reportedAt }, - }); - await prisma.openTabSnapshot.create({ - data: { deviceId: device2Id, tabId: tab.tabId, customerName: tab.customerName, version: tab.version, totalInCents: tab.totalInCents, itemCount: tab.itemCount, reportedAt: tab.reportedAt }, - }); + await createTab(venueId, tab); } - console.log('Created 6 open tabs across 2 devices'); + console.log('Created 6 open tabs'); const now = new Date(); diff --git a/apps/api/prisma/seed.ts b/apps/api/prisma/seed.ts index 432c861..021e860 100644 --- a/apps/api/prisma/seed.ts +++ b/apps/api/prisma/seed.ts @@ -10,9 +10,15 @@ async function main() { // Clean existing data so seed is idempotent await prisma.auditLog.deleteMany(); + await prisma.tabEvent.deleteMany(); + await prisma.tabReminder.deleteMany(); + await prisma.plannedTab.deleteMany(); await prisma.remoteCommand.deleteMany(); - await prisma.openTabSnapshot.deleteMany(); - await prisma.tabOwnership.deleteMany(); + await prisma.settlement.deleteMany(); + await prisma.tab.deleteMany(); + await prisma.stockAdjustment.deleteMany(); + await prisma.product.deleteMany(); + await prisma.productImage.deleteMany(); await prisma.refreshToken.deleteMany(); await prisma.registrationCode.deleteMany(); await prisma.device.deleteMany(); @@ -83,11 +89,24 @@ async function main() { ]; for (const tab of tabsData) { - await prisma.tabOwnership.create({ - data: { tabId: tab.tabId, venueId, deviceId, lastReportedAt: tab.reportedAt }, - }); - await prisma.openTabSnapshot.create({ - data: { deviceId, tabId: tab.tabId, customerName: tab.customerName, version: tab.version, totalInCents: tab.totalInCents, itemCount: tab.itemCount, reportedAt: tab.reportedAt }, + // One line with itemCount units, priced so the tab adds up to about totalInCents + const lineId = uuidv4(); + const addedAt = tab.reportedAt.toISOString(); + await prisma.tab.create({ + data: { + venueId, + id: tab.tabId, + customerName: tab.customerName, + openedAt: tab.reportedAt, + version: tab.version, + lines: [{ + id: lineId, + productId: null, + productName: 'Pils', + unitPriceInCents: Math.round(tab.totalInCents / tab.itemCount), + units: Array.from({ length: tab.itemCount }, (_, i) => ({ id: `${lineId}:${i}`, addedAt, removedAt: null })), + }], + }, }); } diff --git a/apps/api/prisma/setup.js b/apps/api/prisma/setup.js index 1962dad..6781145 100644 --- a/apps/api/prisma/setup.js +++ b/apps/api/prisma/setup.js @@ -35,8 +35,11 @@ async function main() { await tx.tabReminder.deleteMany(); await tx.plannedTab.deleteMany(); await tx.remoteCommand.deleteMany(); - await tx.openTabSnapshot.deleteMany(); - await tx.tabOwnership.deleteMany(); + await tx.settlement.deleteMany(); + await tx.tab.deleteMany(); + await tx.stockAdjustment.deleteMany(); + await tx.product.deleteMany(); + await tx.productImage.deleteMany(); await tx.refreshToken.deleteMany(); await tx.registrationCode.deleteMany(); await tx.device.deleteMany();