CHECK WITH VALID CHECK DEVICE

// prisma/schema.prisma
datasource db {
provider = «postgresql»
url = env(«DATABASE_URL»)
}
generator client {
provider = «prisma-client-js»
}

enum QrStatus {
ISSUED // erzeugt/ausgegeben, noch nicht eingelöst
REDEEMED // eingelöst
REVOKED // ungültig gemacht
EXPIRED // abgelaufen
}

model QrBatch {
id String @id @default(cuid())
name String
createdAt DateTime @default(now())
validFrom DateTime?
validUntil DateTime?
codes QrCode[]
}

model QrCode {
id String @id @default(cuid())
// Im QR steht nur «token» (z. B. zufällige Base58). In DB speichern wir nur den HASH.
tokenHash String @unique
status QrStatus @default(ISSUED)
batchId String
batch QrBatch @relation(fields: [batchId], references: [id])
metadata Json?
issuedTo String? // z.B. Restaurant/Reservierung
issuedAt DateTime @default(now())
expiresAt DateTime?
redeemedAt DateTime?
redeemedBy String? // z.B. Kasse/Scanner-ID
lastScanAt DateTime?
revision Int @default(0) // Optimistic locking, optional
scanEvents ScanEvent[]
}

model ScanEvent {
id String @id @default(cuid())
codeId String?
code QrCode? @relation(fields: [codeId], references: [id])
action String // VERIFY | REDEEM
result String // OK | NOT_FOUND | EXPIRED | ALREADY_REDEEMED | REVOKED | INVALID_SIG | ERROR
scannedAt DateTime @default(now())
ip String?
userAgent String?
location String?
idempotencyKey String? @unique
rawTokenHash String? //
}

NO VALID CHECK DEVICE