// Schema do domínio de aplicação do B2BCall. Vive no schema "public" do // Postgres — nunca misturado com as tabelas do Asterisk Realtime (schema // "asterisk", ver infrastructure/postgres/init/002-asterisk-realtime.sql). // // Modelado incrementalmente por fase (ver TODO.md): esta primeira migration // cobre apenas autenticação, RBAC e auditoria (Fase 3). Demais entidades // (agentes, troncos, filas, campanhas, leads, ...) chegam em migrations // subsequentes, nunca alteração manual de schema. generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } model User { id String @id @default(uuid()) name String email String @unique passwordHash String @map("password_hash") isActive Boolean @default(true) @map("is_active") mustChangePassword Boolean @default(false) @map("must_change_password") lastLoginAt DateTime? @map("last_login_at") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") roles UserRole[] sessions Session[] passwordResetTokens PasswordResetToken[] auditLogs AuditLog[] @@map("users") } model Session { id String @id @default(uuid()) userId String @map("user_id") refreshTokenHash String @map("refresh_token_hash") userAgent String? @map("user_agent") ipAddress String? @map("ip_address") expiresAt DateTime @map("expires_at") revokedAt DateTime? @map("revoked_at") createdAt DateTime @default(now()) @map("created_at") user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@index([userId]) @@index([expiresAt]) @@map("sessions") } model PasswordResetToken { id String @id @default(uuid()) userId String @map("user_id") tokenHash String @unique @map("token_hash") 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) @@index([userId]) @@map("password_reset_tokens") } model Role { id String @id @default(uuid()) name String @unique description String? isSystem Boolean @default(false) @map("is_system") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") users UserRole[] permissions RolePermission[] @@map("roles") } model Permission { id String @id @default(uuid()) key String @unique description String? roles RolePermission[] @@map("permissions") } model UserRole { userId String @map("user_id") roleId String @map("role_id") user User @relation(fields: [userId], references: [id], onDelete: Cascade) role Role @relation(fields: [roleId], references: [id], onDelete: Cascade) @@id([userId, roleId]) @@map("user_roles") } model RolePermission { roleId String @map("role_id") permissionId String @map("permission_id") role Role @relation(fields: [roleId], references: [id], onDelete: Cascade) permission Permission @relation(fields: [permissionId], references: [id], onDelete: Cascade) @@id([roleId, permissionId]) @@map("role_permissions") } model AuditLog { id BigInt @id @default(autoincrement()) userId String? @map("user_id") action String entityType String? @map("entity_type") entityId String? @map("entity_id") before Json? after Json? ipAddress String? @map("ip_address") userAgent String? @map("user_agent") createdAt DateTime @default(now()) @map("created_at") user User? @relation(fields: [userId], references: [id], onDelete: SetNull) @@index([userId]) @@index([entityType, entityId]) @@index([createdAt]) @@map("audit_logs") }