Modelo de datos Vecinal
Vecinal · planificación de base de datos

Modelo entidad-relación

Un solo conjunto residencial por instancia. Todas las tablas usan id como llave primaria; en los diagramas solo aparecen las llaves foráneas. Los atributos de negocio se omiten a propósito.

Decisiones tomadas

Un conjunto por instanciaSe elimina la tabla Condominio y todos los condominio_id. Los datos del conjunto (nombre, NIT, logo) van en ConfiguracionConjunto, una tabla de una sola fila. El portal multi-conjunto vive fuera, en otra app.
Tablas de catálogoRoles, tipos y estados salen de catálogos con codigo fijo. El código del backend compara contra codigo, nunca contra el id.
Soft deletedeleted_at y deleted_by en las tablas de negocio. No aplica a tablas de registro que solo crecen: Auditoria, Notificacion, RegistroAcceso, TicketHistorial, Voto y PagoCargo.
Notificaciones y auditoríaDos tablas transversales. Apuntan a cualquier registro con entidad_tipo + entidad_id, sin FK física hacia cada tabla.
||--o{ uno a muchos
||--o| uno a uno opcional
|o--o{ FK opcional (nullable)
FK llave foránea

Vista general

Las tablas principales de cada módulo y cómo se conectan, sin catálogos. Usuario y Propiedad son el centro: casi todo cuelga de una de las dos.

erDiagram
  Usuario ||--o{ PropiedadPersona : "vive o es dueño"
  Propiedad ||--o{ PropiedadPersona : "tiene"
  Propiedad ||--o{ Adicional : "tiene asignado"
  Propiedad ||--o{ Ticket : "reporta"
  Propiedad ||--o{ Cargo : "debe"
  Propiedad ||--o{ Pago : "paga"
  Pago ||--o{ PagoCargo : "se aplica en"
  Cargo ||--o{ PagoCargo : "se cubre con"
  Amenidad ||--o{ ReservaAmenidad : "se reserva en"
  Propiedad ||--o{ ReservaAmenidad : "reserva"
  ReservaAmenidad |o--o| Cargo : "genera"
  Sesion ||--o{ AsistenciaSesion : "registra"
  Sesion ||--o| Acta : "produce"
  Sesion |o--o{ Votacion : "incluye"
  Votacion ||--o{ Voto : "recibe"
  Propiedad ||--o{ Voto : "emite"
  Propiedad ||--o{ AutorizacionVisita : "autoriza"
  AutorizacionVisita |o--o{ RegistroAcceso : "genera entradas"
  Propiedad ||--o{ Trasteo : "solicita"
  Adicional ||--o{ ReservaParqueadero : "se reserva en"
  Usuario ||--o{ Notificacion : "recibe"
  Usuario ||--o{ Auditoria : "realiza"

Usuarios y seguridad

erDiagram
  Rol ||--o{ Usuario : "define permisos"
  TipoDocumento ||--o{ Usuario : "clasifica"
  Usuario ||--o{ TokenRecuperacion : "solicita"
  Usuario {
    int rol_id FK
    int tipo_documento_id FK
  }
  TokenRecuperacion {
    int usuario_id FK
  }
  ConfiguracionConjunto {
    string nota "una sola fila, sin FKs"
  }

Propiedades, residentes y arrendatarios

erDiagram
  Torre ||--o{ Propiedad : "agrupa"
  TipoPropiedad ||--o{ Propiedad : "clasifica"
  Propiedad |o--o{ Adicional : "tiene asignado"
  TipoAdicional ||--o{ Adicional : "clasifica"
  Propiedad ||--o{ Vehiculo : "registra"
  Propiedad ||--o{ PropiedadPersona : "tiene"
  Usuario ||--o{ PropiedadPersona : "pertenece a"
  TipoRelacion ||--o{ PropiedadPersona : "define"
  Propiedad {
    int torre_id FK
    int tipo_propiedad_id FK
  }
  Adicional {
    int propiedad_id FK "nullable"
    int tipo_adicional_id FK
  }
  Vehiculo {
    int propiedad_id FK
  }
  PropiedadPersona {
    int propiedad_id FK
    int usuario_id FK
    int tipo_relacion_id FK
  }

Mantenimiento

erDiagram
  Propiedad |o--o{ Ticket : "reporta"
  Usuario ||--o{ Ticket : "solicita"
  Usuario |o--o{ Ticket : "atiende"
  CategoriaTicket ||--o{ Ticket : "clasifica"
  PrioridadTicket ||--o{ Ticket : "prioriza"
  EstadoTicket ||--o{ Ticket : "estado actual"
  Ticket ||--o{ TicketHistorial : "registra cambios"
  Usuario ||--o{ TicketHistorial : "hace el cambio"
  Ticket ||--o{ TicketAdjunto : "adjunta"
  Ticket {
    int propiedad_id FK "nullable, zona común"
    int solicitante_id FK "Usuario"
    int asignado_a_id FK "Usuario, nullable"
    int categoria_ticket_id FK
    int prioridad_ticket_id FK
    int estado_ticket_id FK
  }
  TicketHistorial {
    int ticket_id FK
    int usuario_id FK
    int estado_anterior_id FK "EstadoTicket"
    int estado_nuevo_id FK "EstadoTicket"
  }
  TicketAdjunto {
    int ticket_id FK
  }

Pagos

erDiagram
  Propiedad ||--o{ Cargo : "debe"
  ConceptoCobro ||--o{ Cargo : "clasifica"
  EstadoCargo ||--o{ Cargo : "estado"
  Propiedad ||--o{ Pago : "paga"
  Usuario ||--o{ Pago : "registra pago"
  Usuario |o--o{ Pago : "aprueba"
  MetodoPago ||--o{ Pago : "medio"
  EstadoPago ||--o{ Pago : "estado"
  Pago ||--o{ PagoCargo : "se aplica en"
  Cargo ||--o{ PagoCargo : "se cubre con"
  Cargo {
    int propiedad_id FK
    int concepto_cobro_id FK
    int estado_cargo_id FK
  }
  Pago {
    int propiedad_id FK
    int pagador_id FK "Usuario"
    int aprobado_por_id FK "Usuario, nullable"
    int metodo_pago_id FK
    int estado_pago_id FK
  }
  PagoCargo {
    int pago_id FK
    int cargo_id FK
  }

Amenidades

erDiagram
  Amenidad ||--o{ HorarioAmenidad : "disponible en"
  Amenidad ||--o{ BloqueoAmenidad : "cerrada en"
  Amenidad ||--o{ ReservaAmenidad : "se reserva en"
  Propiedad ||--o{ ReservaAmenidad : "reserva"
  Usuario ||--o{ ReservaAmenidad : "solicita"
  EstadoReserva ||--o{ ReservaAmenidad : "estado"
  ReservaAmenidad |o--o| Cargo : "genera cobro"
  HorarioAmenidad {
    int amenidad_id FK
  }
  BloqueoAmenidad {
    int amenidad_id FK
  }
  ReservaAmenidad {
    int amenidad_id FK
    int propiedad_id FK
    int usuario_id FK
    int estado_reserva_id FK
    int cargo_id FK "nullable, único"
  }

Comunales: sesiones, actas y votaciones

erDiagram
  TipoSesion ||--o{ Sesion : "clasifica"
  EstadoSesion ||--o{ Sesion : "estado"
  Usuario ||--o{ Sesion : "crea"
  Sesion ||--o{ AsistenciaSesion : "registra"
  Propiedad ||--o{ AsistenciaSesion : "asiste"
  Usuario ||--o{ AsistenciaSesion : "representa"
  Sesion ||--o| Acta : "produce"
  Usuario ||--o{ Acta : "redacta"
  Sesion |o--o{ Votacion : "incluye"
  EstadoVotacion ||--o{ Votacion : "estado"
  Votacion ||--o{ OpcionVotacion : "ofrece"
  Votacion ||--o{ Voto : "recibe"
  OpcionVotacion ||--o{ Voto : "elegida en"
  Propiedad ||--o{ Voto : "emite"
  Usuario ||--o{ Voto : "vota"
  Sesion {
    int tipo_sesion_id FK
    int estado_sesion_id FK
    int creado_por_id FK "Usuario"
  }
  AsistenciaSesion {
    int sesion_id FK
    int propiedad_id FK
    int usuario_id FK
  }
  Acta {
    int sesion_id FK "único"
    int redactada_por_id FK "Usuario"
  }
  Votacion {
    int sesion_id FK "nullable"
    int estado_votacion_id FK
    int creado_por_id FK "Usuario"
  }
  OpcionVotacion {
    int votacion_id FK
  }
  Voto {
    int votacion_id FK
    int opcion_votacion_id FK
    int propiedad_id FK
    int usuario_id FK
  }

Control de acceso

erDiagram
  TipoDocumento ||--o{ Visitante : "clasifica"
  Visitante ||--o{ AutorizacionVisita : "es autorizado"
  Propiedad ||--o{ AutorizacionVisita : "autoriza"
  Usuario ||--o{ AutorizacionVisita : "firma"
  TipoVisita ||--o{ AutorizacionVisita : "esporádica o recurrente"
  AutorizacionVisita |o--o{ RegistroAcceso : "genera entradas"
  Visitante ||--o{ RegistroAcceso : "entra"
  Propiedad ||--o{ RegistroAcceso : "recibe"
  Usuario ||--o{ RegistroAcceso : "registra en portería"
  Propiedad ||--o{ Trasteo : "solicita"
  Usuario ||--o{ Trasteo : "solicita o aprueba"
  TipoTrasteo ||--o{ Trasteo : "ingreso o salida"
  EstadoReserva ||--o{ Trasteo : "estado"
  Trasteo |o--o| Cargo : "genera depósito"
  Adicional ||--o{ ReservaParqueadero : "se reserva en"
  Propiedad ||--o{ ReservaParqueadero : "reserva"
  AutorizacionVisita |o--o| ReservaParqueadero : "acompaña"
  EstadoReserva ||--o{ ReservaParqueadero : "estado"
  Visitante {
    int tipo_documento_id FK
  }
  AutorizacionVisita {
    int propiedad_id FK
    int visitante_id FK
    int autorizado_por_id FK "Usuario"
    int tipo_visita_id FK
  }
  RegistroAcceso {
    int autorizacion_visita_id FK "nullable"
    int visitante_id FK
    int propiedad_id FK
    int registrado_por_id FK "Usuario vigilante"
  }
  Trasteo {
    int propiedad_id FK
    int solicitado_por_id FK "Usuario"
    int aprobado_por_id FK "Usuario, nullable"
    int tipo_trasteo_id FK
    int estado_reserva_id FK
    int cargo_id FK "nullable"
  }
  ReservaParqueadero {
    int adicional_id FK "parqueadero de visitantes"
    int propiedad_id FK
    int autorizacion_visita_id FK "nullable"
    int estado_reserva_id FK
  }

Notificaciones y auditoría

erDiagram
  Usuario ||--o{ Notificacion : "recibe"
  TipoNotificacion ||--o{ Notificacion : "clasifica"
  Usuario |o--o{ Auditoria : "realiza"
  Notificacion {
    int usuario_id FK "destinatario"
    int tipo_notificacion_id FK
    string entidad_tipo "ej. Ticket"
    int entidad_id "id del registro"
  }
  Auditoria {
    int usuario_id FK "nullable, procesos del sistema"
    string tabla "ej. Pago"
    int registro_id "id del registro"
  }

Catálogos y datos de prueba

Todos los catálogos comparten la misma forma: id, codigo (único y fijo, el que usa el backend), nombre (el que ve el usuario), orden y activo. Los valores de abajo son el codigo sugerido para el seed.

CatálogoLo usaValores de ejemplo
Usuarios y propiedades
RolUsuario
ADMINPROPIETARIORESIDENTEVIGILANTECONSEJO
TipoDocumentoUsuario, Visitante
CCCETIPASAPORTENIT
TipoPropiedadPropiedad
APARTAMENTOCASALOCALOFICINA
TipoAdicionalAdicional
PARQUEADEROBODEGATERRAZA
TipoRelacionPropiedadPersona
PROPIETARIOARRENDATARIORESIDENTEFAMILIAR
Mantenimiento
CategoriaTicketTicket
PLOMERIAELECTRICOHUMEDADCERRAJERIAZONAS_COMUNESASCENSOR
PrioridadTicketTicket
BAJAMEDIAALTAURGENTE
EstadoTicketTicket, TicketHistorial
PENDIENTEAPROBADOEN_PROGRESOCOMPLETADOCANCELADO
Pagos
ConceptoCobroCargo
CUOTA_ADMINCUOTA_EXTRAORDINARIAMULTAINTERES_MORARESERVA_AMENIDADDEPOSITO_TRASTEO
EstadoCargoCargo
PENDIENTEPARCIALPAGADOVENCIDOANULADO
MetodoPagoPago
TRANSFERENCIAPSECONSIGNACIONEFECTIVOTARJETA
EstadoPagoPago
PENDIENTE_APROBACIONAPROBADORECHAZADO
Reservas y acceso
EstadoReservaReservaAmenidad, Trasteo, ReservaParqueadero
SOLICITADAAPROBADARECHAZADACANCELADAREALIZADA
TipoVisitaAutorizacionVisita
ESPORADICARECURRENTE
TipoTrasteoTrasteo
INGRESOSALIDA
Comunales y notificaciones
TipoSesionSesion
ASAMBLEA_ORDINARIAASAMBLEA_EXTRAORDINARIAREUNION_CONSEJO
EstadoSesionSesion
PROGRAMADAEN_CURSOFINALIZADACANCELADA
EstadoVotacionVotacion
BORRADORABIERTACERRADA
TipoNotificacionNotificacion
PAGO_APROBADOPAGO_RECHAZADOCARGO_POR_VENCERTICKET_ACTUALIZADORESERVA_APROBADAVISITA_EN_PORTERIANUEVA_VOTACION