Appearance
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).
| Base | Backend | Apps graficadas | Modelos |
|---|---|---|---|
| IDP | auth-backend | 6 | 46 |
| SPS | backend-seleccion-postulantes | 21 | 177 |
El motor y la conexión se configuran con las variables DATABASE_* de cada backend (ver Backends: dependencias y configuración).
Contenido
| Página | Qué cubre |
|---|---|
| IDP: modelo de datos | Identidades, autenticación, OAuth 2.0 / OIDC, aprobaciones y notificaciones |
| SPS: base y transversales | Usuarios y accesos, archivos, SGC, catálogos, aprobaciones, notificaciones, soporte |
| SPS: preparación y convocatoria | Acefalías, informe técnico previo, convocatoria y fases, resoluciones, comisiones, difusión |
| SPS: postulación | Datos del postulante, currículum vitae y postulación |
| SPS: trabajo de comisiones e impugnaciones | Ejecución de cada fase, resultados e impugnaciones |
| SPS: cierre, reportes e históricos | Informe 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 deIdentityUser(IDP). Se enlazan por valor,UsuarioBase.idp_sub=IdentityUser.public_id, no por llave foránea. El SPS crea elUsuarioBaseen 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_documentosynotificacionesdel 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
SesionLocalcon los tokens del IDP cifrados; el IDP guarda laAuthenticationSessiony los tokens emitidos.
Convenciones
- Casi todos los modelos tienen
created_atyupdated_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:
AprobacionDocumentosySolicitudNotificaciondel SPS usanContentType+origin_object_idpara 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:
| Base | Solo relaciones | Con campos |
|---|---|---|
| IDP | Abrir | Abrir |
| SPS | Abrir | Abrir |
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_graficasEl 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.svgLos SVG de este manual están en docs/public/diagramas/{idp,sps}/ y se generaron desde la rama develop de cada backend.
