# 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
}
```
