Skip to content

Modelo de datos ​

El sistema tiene dos bases de datos independientes, una por backend. Ningún backend lee la base del otro: se comunican por API (OAuth 2.0 / OIDC y REST).

BaseBackendApps graficadasModelos
IDPauth-backend646
SPSbackend-seleccion-postulantes21177

El motor y la conexión se configuran con las variables DATABASE_* de cada backend (ver Backends: dependencias y configuración).

Contenido ​

PáginaQué cubre
IDP: modelo de datosIdentidades, autenticación, OAuth 2.0 / OIDC, aprobaciones y notificaciones
SPS: base y transversalesUsuarios y accesos, archivos, SGC, catálogos, aprobaciones, notificaciones, soporte
SPS: preparación y convocatoriaAcefalías, informe técnico previo, convocatoria y fases, resoluciones, comisiones, difusión
SPS: postulaciónDatos del postulante, currículum vitae y postulación
SPS: trabajo de comisiones e impugnacionesEjecución de cada fase, resultados e impugnaciones
SPS: cierre, reportes e históricosInforme final, certificados y convocatorias anteriores

Cada página tiene, por app, una descripción, su diagrama y la lista de todos sus modelos: qué guarda cada uno y con qué otros modelos se relaciona (entre paréntesis, la app cuando es de otra).

Cómo se relacionan las dos bases ​

  • Usuarios: UsuarioBase (SPS) es la copia local de IdentityUser (IDP). Se enlazan por valor, UsuarioBase.idp_sub = IdentityUser.public_id, no por llave foránea. El SPS crea el UsuarioBase en el primer inicio de sesión (o cuando un sysadmin lo registra desde el directorio del IDP) y actualiza sus datos (nombre, documento, contacto) en cada inicio de sesión desde los claims que entrega el IDP.
  • Aprobación de documentos y notificaciones: el SPS registra localmente qué pidió aprobar o notificar (aprobacion_documentos y notificaciones del SPS) y el IDP guarda la solicitud real, su resultado y cada envío (las apps del mismo nombre en el IDP).
  • Sesiones: el SPS guarda su propia SesionLocal con los tokens del IDP cifrados; el IDP guarda la AuthenticationSession y los tokens emitidos.

Convenciones ​

  • Casi todos los modelos tienen created_at y updated_at. En las listas de cada página no se repiten.
  • El nombre de la tabla es el de Django, <app>_<modelo> en minúsculas (por ejemplo, postulaciones_postulacion). Las pocas excepciones se indican en la descripción del modelo.
  • Archivos: ningún modelo guarda archivos sueltos. Todos apuntan a DocumentoUsuario (SPS), que maneja el almacenamiento, la miniatura y el código de verificación del documento.
  • Relaciones genéricas: AprobacionDocumentos y SolicitudNotificacion del SPS usan ContentType + origin_object_id para colgarse de cualquier modelo (resolución, informe, planilla, etc.).
  • Resultados de fase: todas las fases escriben su resultado en el mismo modelo, ResultadoFase (preliminar o definitivo), que apunta al origen concreto (revisión DMH, calificación de méritos, examen, entrevista o evaluación psicológica).

Bitácora de auditoría ​

Los dos backends tienen una app audit sin modelos de Django: cada INSERT, UPDATE y DELETE sobre las tablas de la aplicación se registra con triggers de base de datos en audit.logged_actions, sin importar quién escribe (ORM, SQL directo o scripts). Se instala sola al final de cada migrate y se puede sincronizar a mano con python manage.py audit_sync. Por no tener modelos, no aparece en los diagramas. El detalle está en audit/README.md de cada backend.

Cómo leer los diagramas ​

Los diagramas se generan del código con graph_models (django-extensions) y Graphviz.

  • Cada caja es un modelo con sus campos y el tipo de cada uno. La llave primaria y los campos de relación van en negrita.
  • Cada línea es una relación y lleva el nombre del campo. El punto marca el modelo que tiene la llave foránea; en las relaciones uno a uno no hay punto.
  • Solo se dibujan las relaciones dentro de la misma app (o del mismo grupo, en las apps grandes). Las relaciones con otras apps están en Se relaciona con, debajo de cada modelo.
  • Clic en un diagrama para abrirlo en tamaño completo en otra pestaña. Son SVG: se pueden ampliar sin perder calidad.

trabajo_comisiones (49 modelos) y convocatorias (23 modelos) se grafican por etapa porque en un solo diagrama no se leen.

Diagramas generales ​

Muestran todas las apps de cada base juntas. Son muy grandes y se abren aparte:

BaseSolo relacionesCon campos
IDPAbrirAbrir
SPSAbrirAbrir

Cómo regenerar los diagramas ​

Las apps que se grafican están en GRAPH_MODELS del settings.py de cada backend. Si se agrega una app con modelos, hay que sumarla ahí.

El script del repositorio genera los PNG de diagramas/ (uno por app, en versión completa y -simple, más los generales):

bash
SYSTEM_STATUS=True python manage.py runscript generar_graficas

El script instala graphviz con sudo apt-get, por eso no funciona dentro del contenedor (ver Scripts de los backends). Con Graphviz ya instalado, un diagrama suelto en SVG como los de este manual se genera así:

bash
# Una app completa
SYSTEM_STATUS=True python manage.py graph_models postulaciones --dot > postulaciones.dot
# Solo algunos modelos de una app (como los grupos de trabajo_comisiones)
SYSTEM_STATUS=True python manage.py graph_models trabajo_comisiones \
  -I ResultadoFase,CriterioAplicadoDesempate,InformeCierreFase --dot > resultados.dot
# A SVG, de izquierda a derecha (más legible en diagramas anchos)
dot -Grankdir=LR -Tsvg postulaciones.dot -o postulaciones.svg

Los SVG de este manual están en docs/public/diagramas/{idp,sps}/ y se generaron desde la rama develop de cada backend.