datasource db { provider = "postgresql" url = env("DATABASE_URL") } generator client { provider = "prisma-client-js" } model Venue { id String @id @default(uuid()) name String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt devices Device[] clientUsers ClientUser[] tabOwnerships TabOwnership[] remoteCommands RemoteCommand[] auditLogs AuditLog[] regCodes RegistrationCode[] plannedTabs PlannedTab[] } model Device { id String @id @default(uuid()) venueId String @unique name String tokenHash String @unique tokenPrefix String tokenExpiresAt DateTime lastSeenAt DateTime @default(now()) revokedAt DateTime? createdAt DateTime @default(now()) venue Venue @relation(fields: [venueId], references: [id]) tabSnapshots OpenTabSnapshot[] tabOwnerships TabOwnership[] remoteCommands RemoteCommand[] @@index([venueId, revokedAt]) } model ClientUser { id String @id @default(uuid()) venueId String email String @unique passwordHash String name String role String @default("viewer") createdAt DateTime @default(now()) venue Venue @relation(fields: [venueId], references: [id]) @@index([venueId]) } model RegistrationCode { id String @id @default(uuid()) venueId String code String @unique expiresAt DateTime usedAt DateTime? createdAt DateTime @default(now()) venue Venue @relation(fields: [venueId], references: [id]) @@index([venueId]) } model OpenTabSnapshot { id String @id @default(uuid()) deviceId String tabId String customerName String version Int totalInCents Int itemCount Int 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]) } model RemoteCommand { id String @id @default(uuid()) venueId String deviceId String targetTabId String type String @default("close_tab") expectedVersion Int paymentMethod String requestedBy String status String @default("pending") result String? acknowledgedAt DateTime? createdAt DateTime @default(now()) expiresAt DateTime venue Venue @relation(fields: [venueId], references: [id]) device Device @relation(fields: [deviceId], references: [id]) @@index([deviceId, status, createdAt]) @@index([venueId, status, createdAt]) } model AuditLog { id String @id @default(uuid()) venueId String actorType String actorId String action String details String? createdAt DateTime @default(now()) venue Venue @relation(fields: [venueId], references: [id]) @@index([venueId, createdAt]) } model RefreshToken { id String @id @default(uuid()) userId String tokenHash String @unique expiresAt DateTime revokedAt DateTime? createdAt DateTime @default(now()) @@index([userId]) } model PlannedTab { id String @id @default(uuid()) venueId String customerName String position Int @default(0) createdAt DateTime @default(now()) venue Venue @relation(fields: [venueId], references: [id]) @@unique([venueId, customerName]) @@index([venueId]) }