generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" } enum Role { USER ADMIN } enum QrStatus { PENDING SCANNED CONFIRMED EXPIRED } model User { id String @id @default(uuid()) @db.Uuid email String @unique phone String? @unique passwordHash String? @map("password_hash") displayName String? @map("display_name") avatarUrl String? @map("avatar_url") role Role @default(USER) isActive Boolean @default(true) @map("is_active") emailVerifiedAt DateTime? @map("email_verified_at") phoneVerifiedAt DateTime? @map("phone_verified_at") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") ownedClients Client[] @relation("ClientOwner") sessions Session[] auditLogs AuditLog[] verificationCodes VerificationCode[] qrSessions QrSession[] @@map("users") } model Client { id String @id @default(uuid()) @db.Uuid name String description String? clientId String @unique @map("client_id") clientSecret String? @map("client_secret") redirectUris String[] @map("redirect_uris") grants String[] isConfidential Boolean @default(true) @map("is_confidential") ownerId String? @map("owner_id") @db.Uuid logoUrl String? @map("logo_url") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") owner User? @relation("ClientOwner", fields: [ownerId], references: [id], onDelete: SetNull) sessions Session[] @@map("clients") } model Session { id String @id @default(uuid()) @db.Uuid userId String @map("user_id") @db.Uuid clientId String? @map("client_id") @db.Uuid ip String? userAgent String? @map("user_agent") isActive Boolean @default(true) @map("is_active") expiresAt DateTime @map("expires_at") createdAt DateTime @default(now()) @map("created_at") lastUsedAt DateTime @default(now()) @map("last_used_at") user User @relation(fields: [userId], references: [id], onDelete: Cascade) client Client? @relation(fields: [clientId], references: [id], onDelete: SetNull) refreshTokens RefreshToken[] @@map("sessions") } model RefreshToken { id String @id @default(uuid()) @db.Uuid tokenHash String @unique @map("token_hash") sessionId String @map("session_id") @db.Uuid expiresAt DateTime @map("expires_at") revoked Boolean @default(false) createdAt DateTime @default(now()) @map("created_at") session Session @relation(fields: [sessionId], references: [id], onDelete: Cascade) @@map("refresh_tokens") } model VerificationCode { id String @id @default(uuid()) @db.Uuid userId String? @map("user_id") @db.Uuid target String channel String code String purpose String @default("AUTH") expiresAt DateTime @map("expires_at") usedAt DateTime? @map("used_at") createdAt DateTime @default(now()) @map("created_at") user User? @relation(fields: [userId], references: [id], onDelete: Cascade) @@map("verification_codes") } model QrSession { id String @id @default(uuid()) @db.Uuid sessionId String @unique @map("session_id") userId String? @map("user_id") @db.Uuid status QrStatus @default(PENDING) qrData String? @map("qr_data") deviceInfo String? @map("device_info") expiresAt DateTime @map("expires_at") createdAt DateTime @default(now()) @map("created_at") confirmedAt DateTime? @map("confirmed_at") user User? @relation(fields: [userId], references: [id], onDelete: SetNull) @@map("qr_sessions") } model AuditLog { id String @id @default(uuid()) @db.Uuid userId String? @map("user_id") @db.Uuid action String details Json? ip String? userAgent String? @map("user_agent") createdAt DateTime @default(now()) @map("created_at") user User? @relation(fields: [userId], references: [id], onDelete: SetNull) @@map("audit_logs") }