Español
Arquitectura
Esquema de Base de Datos

Esquema de Base de Datos

ReliaPulse usa PostgreSQL con Prisma ORM. Este documento cubre el diseño de la base de datos y los modelos principales.

Vista General de Relaciones

┌─────────────────┐       ┌─────────────────┐
│  Organization   │───────│ OrganizationMember│
└────────┬────────┘       └────────┬────────┘
         │                         │
         │                         ▼
         │                  ┌─────────────┐
         │                  │    User     │
         │                  └─────────────┘

    ┌────┴─────────────────────────────────────┐
    │                                          │
    ▼                ▼               ▼         ▼
┌──────────┐   ┌──────────┐   ┌──────────┐ ┌──────────┐
│Component │   │ Incident │   │StatusPage│ │Integration│
└────┬─────┘   └────┬─────┘   └────┬─────┘ └────┬─────┘
     │              │              │            │
     │              ▼              ▼            ▼
     │        ┌──────────┐   ┌──────────┐ ┌──────────┐
     │        │ Update   │   │ Widget   │ │ Metrics  │
     │        └──────────┘   └──────────┘ │  Query   │
     │                                     └──────────┘

┌──────────┐
│SubComps  │
└──────────┘

Modelos Principales

Organization

El modelo raíz de tenant. Todos los datos están asociados a una organización.

model Organization {
  id                  String   @id @default(cuid())
  name                String
  slug                String   @unique
  logo                String?
  logoDark            String?
  primaryColor        String   @default("#3b82f6")
 
  // Seguridad
  require2FA          Boolean  @default(false)
  ssoEnforced         Boolean  @default(false)
  allowedEmailDomains String[]
 
  // Onboarding
  onboardingCompleted Boolean  @default(false)
 
  // Tema
  themePreset         String   @default("system")
 
  // Relaciones
  members             OrganizationMember[]
  components          Component[]
  incidents           Incident[]
  statusPages         StatusPage[]
  // ... muchas más
}

User

Cuentas de usuario con datos de autenticación.

model User {
  id               String    @id @default(cuid())
  email            String    @unique
  name             String?
  password         String?   // Null para usuarios solo OAuth
 
  // 2FA
  twoFactorEnabled Boolean   @default(false)
  twoFactorSecret  String?   // Encriptado con AES-256-GCM
 
  // Relaciones
  memberships      OrganizationMember[]
}

OrganizationMember

Vincula usuarios a organizaciones con roles.

model OrganizationMember {
  id             String     @id @default(cuid())
  userId         String
  organizationId String
  role           MemberRole @default(MEMBER)
  teamId         String?
  customRoleId   String?
 
  // Relaciones
  user           User         @relation(...)
  organization   Organization @relation(...)
  team           Team?        @relation(...)
  customRole     CustomRole?  @relation(...)
}
 
enum MemberRole {
  OWNER
  ADMIN
  MEMBER
  VIEWER
  INCIDENT_MANAGER
  ONCALL_RESPONDER
  STATUS_EDITOR
  SUBSCRIBER_MANAGER
}

Sistema de Componentes

Component (Polimórfico)

Los componentes representan servicios, endpoints o métricas siendo monitoreados.

model Component {
  id               String        @id @default(cuid())
  name             String
  description      String?
  status           ComponentStatus @default(OPERATIONAL)
  type             ComponentType   @default(SERVICE)
  organizationId   String
 
  // Jerarquía
  parentComponentId String?
  displayOrder     Int           @default(0)
 
  // Campos tipo ENDPOINT
  url              String?
  method           HttpMethod?
  checkInterval    Int?
  expectedStatus   Int?
  conditions       Json?
 
  // Campos tipo METRIC
  integrationId    String?
  query            String?
  warningThreshold Float?
  criticalThreshold Float?
 
  // Relaciones
  subComponents    Component[]   @relation("ComponentHierarchy")
  incidents        Incident[]
  uptimeRecords    UptimeRecord[]
}
 
enum ComponentType {
  SERVICE          // Control manual de estado
  ENDPOINT         // Health checks HTTP
  METRIC           // Métricas externas
  CALCULATED_METRIC // Métricas calculadas
}
 
enum ComponentStatus {
  OPERATIONAL
  DEGRADED_PERFORMANCE
  PARTIAL_OUTAGE
  MAJOR_OUTAGE
  UNDER_MAINTENANCE
  UNKNOWN
}

Incidentes y Mantenimientos

Incident

Rastrea interrupciones de servicio.

model Incident {
  id             String         @id @default(cuid())
  title          String
  message        String
  status         IncidentStatus @default(INVESTIGATING)
  severity       Severity       @default(MINOR)
  organizationId String
 
  // Relaciones
  updates        IncidentUpdate[]
  components     Component[]
  postmortem     Postmortem?
}
 
enum IncidentStatus {
  INVESTIGATING
  IDENTIFIED
  MONITORING
  RESOLVED
}
 
enum Severity {
  MINOR
  MAJOR
  CRITICAL
}

Maintenance

Ventanas de mantenimiento programado.

model Maintenance {
  id             String            @id @default(cuid())
  title          String
  message        String
  status         MaintenanceStatus @default(SCHEDULED)
  scheduledStart DateTime
  scheduledEnd   DateTime
  organizationId String
 
  // Relaciones
  updates        MaintenanceUpdate[]
  components     Component[]
}
 
enum MaintenanceStatus {
  SCHEDULED
  IN_PROGRESS
  VERIFYING
  COMPLETED
  CANCELLED
}

Páginas de Estado

StatusPage

Configuración de página de estado pública.

model StatusPage {
  id             String           @id @default(cuid())
  name           String
  slug           String
  visibility     PageVisibility   @default(PUBLIC)
  accessToken    String?          // Para páginas PRIVATE
  organizationId String
 
  // Branding
  customDomain   String?
  logo           String?
  primaryColor   String?
 
  // Relaciones
  widgets        StatusPageWidget[]
}
 
enum PageVisibility {
  PUBLIC
  PRIVATE
  DRAFT
}

Métricas e Integraciones

Integration

Conexiones a servicios externos.

model Integration {
  id             String          @id @default(cuid())
  name           String
  type           IntegrationType
  config         Json            // Campos sensibles encriptados
  isEnabled      Boolean         @default(true)
  organizationId String
 
  // Relaciones
  metricsQueries MetricsQuery[]
}
 
enum IntegrationType {
  PROMETHEUS
  DATADOG
  NEWRELIC
  GRAFANA
  PINGDOM
  CUSTOM_WEBHOOK
}

Notificaciones

NotificationChannel

Configuración de canales de entrega.

model NotificationChannel {
  id             String            @id @default(cuid())
  name           String
  type           NotificationChannelType
  config         Json              // Webhook URL, API keys, etc.
  isEnabled      Boolean           @default(true)
  organizationId String
}
 
enum NotificationChannelType {
  EMAIL
  SLACK
  DISCORD
  TEAMS
  SMS
  WEBHOOK
}

Subscriber

Personas/sistemas que reciben notificaciones.

model Subscriber {
  id             String         @id @default(cuid())
  type           SubscriberType
  contact        String         // Email, teléfono o URL webhook
  isVerified     Boolean        @default(false)
  organizationId String
}
 
enum SubscriberType {
  EMAIL
  SMS
  WEBHOOK
}

On-Call

OnCallSchedule

Horarios de rotación para guardias.

model OnCallSchedule {
  id             String       @id @default(cuid())
  name           String
  timezone       String       @default("UTC")
  rotationType   RotationType @default(WEEKLY)
  organizationId String
 
  // Relaciones
  participants   OnCallParticipant[]
  escalationPolicy EscalationPolicy?
}
 
enum RotationType {
  DAILY
  WEEKLY
  CUSTOM
}

Índices

Índices clave para rendimiento:

// Scope de organización (en la mayoría de modelos)
@@index([organizationId])
 
// Jerarquía de componentes
@@index([parentComponentId])
@@index([organizationId, parentComponentId])
 
// Consultas basadas en tiempo
@@index([createdAt])
@@index([recordedAt])
 
// Restricciones únicas
@@unique([organizationId, slug])  // StatusPage
@@unique([organizationId, name])  // Component, Team
@@unique([queryId, tagsHash])     // MetricSeries

Migraciones

Prisma gestiona las migraciones automáticamente:

# Crear una nueva migración
npx prisma migrate dev --name add_feature
 
# Aplicar migraciones en producción
npx prisma migrate deploy
 
# Resetear base de datos (solo desarrollo)
npx prisma migrate reset

Retención de Datos

Algunos datos tienen limpieza automática:

  • MetricDataPoint - 30 días
  • ExtractedValueDataPoint - 7 días
  • CalculatedMetricDataPoint - 7 días
  • AuditLog - Configurable (por defecto: ilimitado)