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]) // MetricSeriesMigraciones
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 resetRetención de Datos
Algunos datos tienen limpieza automática:
MetricDataPoint- 30 díasExtractedValueDataPoint- 7 díasCalculatedMetricDataPoint- 7 díasAuditLog- Configurable (por defecto: ilimitado)