# Estándares - Modelado e Integridad PostgreSQL (Prisma) El proyecto utiliza **PostgreSQL** para persistencia estructurada y transaccionalidad. A continuación se detallan las directrices y los esquemas clave. --- ## 1. Reglas Generales de Base de Datos - **Transacciones de Reservas:** Las reservas de espacios deben usar exclusión mutua en consultas o bloqueos optimistas para asegurar que no ocurran solapamientos de reservas. - **Relaciones Claras:** Los artículos del CMS se relacionan con el perfil de usuario del Directorio. - **Trazabilidad:** Cada cambio de estado de un ticket o workflow de publicación debe registrar una fila en una tabla de auditoría (`StateHistory`). --- ## 2. Esquema Conceptual (Prisma Schema Reference) ```prisma // Esquema de Base de Datos App Intranet model User { id String @id @default(uuid()) email String @unique name String role String // 'EMPLOYEE', 'MANAGER', 'ADMIN' department String position String phoneNumber String? managerId String? manager User? @relation("Hierarchy", fields: [managerId], references: [id]) subordinates User[] @relation("Hierarchy") articles Article[] reservations Reservation[] tickets Ticket[] @relation("UserTickets") assignedTickets Ticket[] @relation("AgentTickets") createdAt DateTime @default(now()) } model Article { id String @id @default(uuid()) title String content String @db.Text status String // 'DRAFT', 'PENDING', 'APPROVED', 'PUBLISHED' authorId String author User @relation(fields: [authorId], references: [id]) category String tags String[] version Int @default(1) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } model Reservation { id String @id @default(uuid()) spaceName String // 'SALA_A', 'OFICINA_3', 'PARQUEO_12' spaceType String // 'MEETING_ROOM', 'OFFICE', 'PARKING' userId String user User @relation(fields: [userId], references: [id]) startTime DateTime endTime DateTime createdAt DateTime @default(now()) } model Ticket { id String @id @default(uuid()) title String description String @db.Text priority String // 'LOW', 'MEDIUM', 'HIGH', 'CRITICAL' status String // 'OPEN', 'ASSIGNED', 'RESOLVED', 'CLOSED' creatorId String creator User @relation("UserTickets", fields: [creatorId], references: [id]) assigneeId String? assignee User? @relation("AgentTickets", fields: [assigneeId], references: [id]) slaLimit DateTime createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } ```