- Next.js 14 frontend with dark cyan/navy theme - tRPC API with Prisma ORM - MeshCentral, LibreNMS, Headwind MDM integrations - Multi-tenant architecture - Alert system with email/SMS/webhook notifications - Docker Compose deployment - Complete documentation
362 lines
11 KiB
Plaintext
362 lines
11 KiB
Plaintext
generator client {
|
|
provider = "prisma-client-js"
|
|
}
|
|
|
|
datasource db {
|
|
provider = "postgresql"
|
|
url = env("DATABASE_URL")
|
|
}
|
|
|
|
// ==================== CLIENTES ====================
|
|
model Cliente {
|
|
id String @id @default(cuid())
|
|
nombre String
|
|
codigo String @unique
|
|
email String?
|
|
telefono String?
|
|
activo Boolean @default(true)
|
|
notas String?
|
|
meshcentralGrupo String? @map("meshcentral_grupo")
|
|
librenmsGrupo Int? @map("librenms_grupo")
|
|
headwindGrupo Int? @map("headwind_grupo")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
ubicaciones ClienteUbicacion[]
|
|
dispositivos Dispositivo[]
|
|
usuarios Usuario[]
|
|
alertas Alerta[]
|
|
alertaReglas AlertaRegla[]
|
|
|
|
@@map("clientes")
|
|
}
|
|
|
|
model ClienteUbicacion {
|
|
id String @id @default(cuid())
|
|
clienteId String @map("cliente_id")
|
|
nombre String
|
|
direccion String?
|
|
ciudad String?
|
|
estado String?
|
|
pais String @default("Mexico")
|
|
codigoPostal String? @map("codigo_postal")
|
|
latitud Float?
|
|
longitud Float?
|
|
principal Boolean @default(false)
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
|
|
cliente Cliente @relation(fields: [clienteId], references: [id], onDelete: Cascade)
|
|
dispositivos Dispositivo[]
|
|
|
|
@@map("cliente_ubicaciones")
|
|
}
|
|
|
|
// ==================== DISPOSITIVOS ====================
|
|
enum TipoDispositivo {
|
|
PC
|
|
LAPTOP
|
|
SERVIDOR
|
|
CELULAR
|
|
TABLET
|
|
ROUTER
|
|
SWITCH
|
|
FIREWALL
|
|
AP
|
|
IMPRESORA
|
|
OTRO
|
|
}
|
|
|
|
enum EstadoDispositivo {
|
|
ONLINE
|
|
OFFLINE
|
|
ALERTA
|
|
MANTENIMIENTO
|
|
DESCONOCIDO
|
|
}
|
|
|
|
model Dispositivo {
|
|
id String @id @default(cuid())
|
|
clienteId String @map("cliente_id")
|
|
ubicacionId String? @map("ubicacion_id")
|
|
tipo TipoDispositivo
|
|
nombre String
|
|
descripcion String?
|
|
estado EstadoDispositivo @default(DESCONOCIDO)
|
|
|
|
// IDs externos
|
|
meshcentralId String? @unique @map("meshcentral_id")
|
|
librenmsId Int? @unique @map("librenms_id")
|
|
headwindId Int? @unique @map("headwind_id")
|
|
|
|
// Info general
|
|
ip String?
|
|
mac String?
|
|
sistemaOperativo String? @map("sistema_operativo")
|
|
versionSO String? @map("version_so")
|
|
fabricante String?
|
|
modelo String?
|
|
serial String?
|
|
|
|
// Para equipos de computo
|
|
cpu String?
|
|
ram Int? // En MB
|
|
disco Int? // En GB
|
|
|
|
// Para celulares
|
|
imei String?
|
|
numeroTelefono String? @map("numero_telefono")
|
|
operador String?
|
|
|
|
// Para red
|
|
firmware String?
|
|
snmpCommunity String? @map("snmp_community")
|
|
|
|
// Metricas actuales
|
|
cpuUsage Float? @map("cpu_usage")
|
|
ramUsage Float? @map("ram_usage")
|
|
discoUsage Float? @map("disco_usage")
|
|
temperatura Float?
|
|
bateria Int?
|
|
|
|
// Ubicacion GPS (celulares)
|
|
latitud Float?
|
|
longitud Float?
|
|
gpsUpdatedAt DateTime? @map("gps_updated_at")
|
|
|
|
// Timestamps
|
|
lastSeen DateTime? @map("last_seen")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
cliente Cliente @relation(fields: [clienteId], references: [id], onDelete: Cascade)
|
|
ubicacion ClienteUbicacion? @relation(fields: [ubicacionId], references: [id])
|
|
software DispositivoSoftware[]
|
|
metricas DispositivoMetrica[]
|
|
metricasHourly DispositivoMetricaHourly[]
|
|
alertas Alerta[]
|
|
sesiones SesionRemota[]
|
|
auditLogs AuditLog[]
|
|
|
|
@@index([clienteId])
|
|
@@index([tipo])
|
|
@@index([estado])
|
|
@@map("dispositivos")
|
|
}
|
|
|
|
model DispositivoSoftware {
|
|
id String @id @default(cuid())
|
|
dispositivoId String @map("dispositivo_id")
|
|
nombre String
|
|
version String?
|
|
editor String?
|
|
instaladoEn DateTime? @map("instalado_en")
|
|
tamanio Int? // En MB
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
|
|
dispositivo Dispositivo @relation(fields: [dispositivoId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([dispositivoId, nombre, version])
|
|
@@map("dispositivo_software")
|
|
}
|
|
|
|
model DispositivoMetrica {
|
|
id String @id @default(cuid())
|
|
dispositivoId String @map("dispositivo_id")
|
|
timestamp DateTime @default(now())
|
|
cpuUsage Float? @map("cpu_usage")
|
|
ramUsage Float? @map("ram_usage")
|
|
discoUsage Float? @map("disco_usage")
|
|
temperatura Float?
|
|
bateria Int?
|
|
redIn BigInt? @map("red_in") // bytes
|
|
redOut BigInt? @map("red_out") // bytes
|
|
|
|
dispositivo Dispositivo @relation(fields: [dispositivoId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([dispositivoId, timestamp])
|
|
@@map("dispositivo_metricas")
|
|
}
|
|
|
|
model DispositivoMetricaHourly {
|
|
id String @id @default(cuid())
|
|
dispositivoId String @map("dispositivo_id")
|
|
hora DateTime
|
|
cpuAvg Float? @map("cpu_avg")
|
|
cpuMax Float? @map("cpu_max")
|
|
ramAvg Float? @map("ram_avg")
|
|
ramMax Float? @map("ram_max")
|
|
discoAvg Float? @map("disco_avg")
|
|
tempAvg Float? @map("temp_avg")
|
|
tempMax Float? @map("temp_max")
|
|
redInTotal BigInt? @map("red_in_total")
|
|
redOutTotal BigInt? @map("red_out_total")
|
|
|
|
dispositivo Dispositivo @relation(fields: [dispositivoId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([dispositivoId, hora])
|
|
@@map("dispositivo_metricas_hourly")
|
|
}
|
|
|
|
// ==================== ALERTAS ====================
|
|
enum SeveridadAlerta {
|
|
INFO
|
|
WARNING
|
|
CRITICAL
|
|
}
|
|
|
|
enum EstadoAlerta {
|
|
ACTIVA
|
|
RECONOCIDA
|
|
RESUELTA
|
|
}
|
|
|
|
model Alerta {
|
|
id String @id @default(cuid())
|
|
clienteId String @map("cliente_id")
|
|
dispositivoId String? @map("dispositivo_id")
|
|
reglaId String? @map("regla_id")
|
|
severidad SeveridadAlerta
|
|
estado EstadoAlerta @default(ACTIVA)
|
|
titulo String
|
|
mensaje String
|
|
origen String? // meshcentral, librenms, headwind, sistema
|
|
origenId String? @map("origen_id")
|
|
reconocidaPor String? @map("reconocida_por")
|
|
reconocidaEn DateTime? @map("reconocida_en")
|
|
resueltaPor String? @map("resuelta_por")
|
|
resueltaEn DateTime? @map("resuelta_en")
|
|
notificada Boolean @default(false)
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
|
|
cliente Cliente @relation(fields: [clienteId], references: [id], onDelete: Cascade)
|
|
dispositivo Dispositivo? @relation(fields: [dispositivoId], references: [id])
|
|
regla AlertaRegla? @relation(fields: [reglaId], references: [id])
|
|
|
|
@@index([clienteId, estado])
|
|
@@index([severidad])
|
|
@@index([createdAt])
|
|
@@map("alertas")
|
|
}
|
|
|
|
model AlertaRegla {
|
|
id String @id @default(cuid())
|
|
clienteId String? @map("cliente_id") // null = global
|
|
nombre String
|
|
descripcion String?
|
|
activa Boolean @default(true)
|
|
tipoDispositivo TipoDispositivo? @map("tipo_dispositivo")
|
|
metrica String // cpu, ram, disco, temperatura, etc
|
|
operador String // >, <, >=, <=, ==
|
|
umbral Float
|
|
duracionMinutos Int @default(5) @map("duracion_minutos")
|
|
severidad SeveridadAlerta
|
|
notificarEmail Boolean @default(true) @map("notificar_email")
|
|
notificarSms Boolean @default(false) @map("notificar_sms")
|
|
notificarWebhook Boolean @default(false) @map("notificar_webhook")
|
|
webhookUrl String? @map("webhook_url")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
cliente Cliente? @relation(fields: [clienteId], references: [id], onDelete: Cascade)
|
|
alertas Alerta[]
|
|
|
|
@@map("alerta_reglas")
|
|
}
|
|
|
|
// ==================== USUARIOS ====================
|
|
enum RolUsuario {
|
|
SUPER_ADMIN
|
|
ADMIN
|
|
TECNICO
|
|
CLIENTE
|
|
VIEWER
|
|
}
|
|
|
|
model Usuario {
|
|
id String @id @default(cuid())
|
|
clienteId String? @map("cliente_id") // null = acceso global
|
|
email String @unique
|
|
nombre String
|
|
passwordHash String? @map("password_hash")
|
|
meshcentralUser String? @unique @map("meshcentral_user")
|
|
rol RolUsuario @default(VIEWER)
|
|
activo Boolean @default(true)
|
|
avatar String?
|
|
telefono String?
|
|
notificarEmail Boolean @default(true) @map("notificar_email")
|
|
notificarSms Boolean @default(false) @map("notificar_sms")
|
|
lastLogin DateTime? @map("last_login")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
cliente Cliente? @relation(fields: [clienteId], references: [id], onDelete: SetNull)
|
|
permisos UsuarioPermiso[]
|
|
sesiones SesionRemota[]
|
|
auditLogs AuditLog[]
|
|
|
|
@@map("usuarios")
|
|
}
|
|
|
|
model UsuarioPermiso {
|
|
id String @id @default(cuid())
|
|
usuarioId String @map("usuario_id")
|
|
recurso String // dispositivos, alertas, reportes, configuracion, etc
|
|
accion String // read, write, delete, execute
|
|
permitido Boolean @default(true)
|
|
|
|
usuario Usuario @relation(fields: [usuarioId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([usuarioId, recurso, accion])
|
|
@@map("usuario_permisos")
|
|
}
|
|
|
|
// ==================== SESIONES Y AUDITORIA ====================
|
|
model SesionRemota {
|
|
id String @id @default(cuid())
|
|
usuarioId String @map("usuario_id")
|
|
dispositivoId String @map("dispositivo_id")
|
|
tipo String // desktop, terminal, files
|
|
meshSessionId String? @map("mesh_session_id")
|
|
iniciadaEn DateTime @default(now()) @map("iniciada_en")
|
|
finalizadaEn DateTime? @map("finalizada_en")
|
|
duracion Int? // segundos
|
|
ip String?
|
|
|
|
usuario Usuario @relation(fields: [usuarioId], references: [id])
|
|
dispositivo Dispositivo @relation(fields: [dispositivoId], references: [id])
|
|
|
|
@@map("sesiones_remotas")
|
|
}
|
|
|
|
model AuditLog {
|
|
id String @id @default(cuid())
|
|
usuarioId String? @map("usuario_id")
|
|
dispositivoId String? @map("dispositivo_id")
|
|
accion String
|
|
recurso String
|
|
detalles Json?
|
|
ip String?
|
|
userAgent String? @map("user_agent")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
|
|
usuario Usuario? @relation(fields: [usuarioId], references: [id])
|
|
dispositivo Dispositivo? @relation(fields: [dispositivoId], references: [id])
|
|
|
|
@@index([usuarioId])
|
|
@@index([createdAt])
|
|
@@map("audit_log")
|
|
}
|
|
|
|
// ==================== CONFIGURACION ====================
|
|
model Configuracion {
|
|
id String @id @default(cuid())
|
|
clave String @unique
|
|
valor Json
|
|
tipo String // string, number, boolean, json
|
|
categoria String // general, integracion, notificacion, etc
|
|
descripcion String?
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
@@map("configuracion")
|
|
}
|