Módulo Documental
En una frase
El núcleo de Gestión Civis: gestión de expedientes y unidades documentales con procedimientos configurables, workflows con SLA, firma electrónica por circuitos, control de acceso granular, archivo electrónico, libros de registro, mensajería, contactos, plantillas, actas, convocatorias, propuestas de gasto y búsqueda semántica + chatbot (IA).
1. Propósito y alcance
El módulo Documental es la base sobre la que se apoyan casi todos los demás. Sus responsabilidades:
- Expedientes (
Expediente): contenedor administrativo que agrupa documentos. - Unidades documentales (
UnidadDocumental, "UD"): el documento individual (resolución, decreto, informe, propuesta…), con ciclo de vida, datos estructurados y firma. - Procedimientos (
Procedimiento): plantilla configurable que define qué campos tiene una UD y qué workflow sigue. - Workflows: máquina de estados con pasos, transiciones, responsables flexibles y SLA monitorizado.
- Firma electrónica: circuitos de firmantes por rol funcional, con órdenes secuenciales y paralelos.
- Control de acceso granular a expedientes y UDs (usuario / rol / departamento / grupo).
- Archivo electrónico, libros de registro, mensajería, contactos, plantillas, actas, convocatorias, propuestas de gasto.
- IA: búsqueda semántica (FAISS), chatbot RAG (Clara) y asistente de escritura.
2. Estructura de archivos
El módulo registra 15 blueprints (todos bajo /api, salvo los indicados):
app/modules/documental/
├── documental.py # Núcleo: expedientes, UDs, workflows, dashboard (≈2963 líneas)
├── archivo.py # Archivo electrónico (servir/listar firmados)
├── reparos.py # Reparos y comentarios
├── imputaciones_presupuestarias.py # Imputaciones del expediente
├── firma.py # Firma electrónica + circuitos (≈1085 líneas)
├── plantillas.py # Plantillas de documento
├── mensajes.py # Mensajería interna (/api/mensajes)
├── enlaces.py # Enlaces externos (/api/enlaces-externos)
├── contactos.py # Directorio de contactos
├── actas.py # Actas
├── convocatorias.py # Convocatorias
├── propuesta_gasto.py # Propuesta de gasto + proveedores + adjuntos
├── search.py # Búsqueda semántica FAISS
├── rag_utils.py # Utilidades RAG (chatbot)
├── assistant.py # Asistente de escritura
├── chatbot.py # Servicio chatbot (sin HTTP)
├── chatbot_endpoint.py # Endpoint chatbot (/api/chatbot)
├── conocimiento_api.py # CRUD base de conocimiento
├── conocimiento_mos_action.py # Cron de generación automática de conocimiento
├── sla_check.py # Acción MOS de verificación de SLA
└── errors.py # Catálogo de errores del módulo
| Blueprint | url_prefix |
|---|---|
documental_bp, search_bp, assistant_bp, contactos_bp, firma_bp, archivo_bp, reparos_bp, plantillas_bp, convocatorias_bp, actas_bp, propuesta_gasto_bp, conocimiento_bp, imputaciones_bp |
/api |
chatbot_bp |
/api/chatbot |
mensajes_bp |
/api/mensajes |
enlaces_bp |
/api/enlaces-externos |
3. Modelos de datos
3.1 Expedientes y unidades documentales
erDiagram
EXPEDIENTE ||--o{ UNIDADDOCUMENTAL : contiene
EXPEDIENTE }o--|| TIPOEXPEDIENTE : ""
EXPEDIENTE }o--|| ESTADOEXPEDIENTE : ""
UNIDADDOCUMENTAL }o--|| PROCEDIMIENTO : ""
UNIDADDOCUMENTAL }o--o| PASOWORKFLOW : "paso_actual"
UNIDADDOCUMENTAL ||--o{ UDADJUNTO : ""
UNIDADDOCUMENTAL ||--o{ FIRMAELECTRONICA : ""
UNIDADDOCUMENTAL ||--o{ REPARO : ""
UNIDADDOCUMENTAL ||--o| PROPUESTAGASTO : ""
UNIDADDOCUMENTAL ||--o| ACTA : ""
UNIDADDOCUMENTAL ||--o| CONVOCATORIA : ""
| Modelo | Tabla | Propósito |
|---|---|---|
Expediente |
expedientes |
Contenedor administrativo. Tiene acceso_restringido y relaciones de acceso por usuario/rol/depto/grupo. |
TipoExpediente / EstadoExpediente |
tipos_expediente / estados_expediente |
Catálogos por entidad. |
UnidadDocumental |
unidades_documentales |
Documento individual. Campos clave: referencia (autocalc.), csv (verificación), contenido (HTML), estado_firma, ruta_archivado, paso_actual_id, propietario_actual_id, datos según procedimiento (interesado, destinatario, registro de entrada…). |
EstadoUnidadDocumental |
estados_unidad_documental |
Catálogo de estados de UD (configurable, no enum fijo). |
UDAdjunto |
ud_adjuntos |
Ficheros adjuntos a la UD. |
UDDestinatario |
ud_destinatarios |
Destinatarios (usuario/depto/rol/grupo). |
UDAcceso |
ud_accesos |
Control de acceso por UD (usuario/rol/depto/grupo). |
Referencia autocalculada
Las referencias se generan con SecuenciaReferencia.siguiente(entidad, prefijo, año)
→ p. ej. RES2026-0000001. El campo csv (Código Seguro de Verificación) se
usa para validar documentos firmados desde la sede pública.
3.2 Procedimientos y workflows
| Modelo | Tabla | Propósito |
|---|---|---|
Procedimiento |
procedimientos |
Plantilla configurable: numerosos flags tiene_* activan campos (interesado, destinatario, propuesta de gasto, convocatoria, acta, contrato, derecho de ingreso, pago a justificar, endoso, embargo, compensación, liquidación…) y enlaza con un Workflow. |
Workflow |
workflows |
Flujo nombrado; tiene pasos ordenados. |
PasoWorkflow |
pasos_workflow |
Etapa: orden, estado_id, responsable flexible (responsable_tipo: usuario/rol/rol_funcional/depto/grupo), SLA (sla_dias/horas/minutos), notificar_al_entrar. |
TransicionWorkflow |
transiciones_workflow |
Transición permitida entre pasos (nombre_accion, paso origen/destino, estado destino). |
HistorialWorkflow |
historial_workflow |
Auditoría de tránsito: fechas entrada/salida, sla_cumplido, sla_notificado, usuario asignado y ejecutado_por. |
flowchart LR
P[Procedimiento] --> W[Workflow]
W --> S1[Paso 1<br/>estado + responsable + SLA]
S1 -->|Transición acción| S2[Paso 2]
S2 -->|Transición acción| S3[Paso N]
S1 -.registra.-> H[(HistorialWorkflow)]
S2 -.registra.-> H
3.3 Firma electrónica y circuitos
| Modelo | Tabla | Propósito |
|---|---|---|
FirmaElectronica |
firmas_electronicas |
Firma registrada: hash_documento (SHA-256), fecha_firma, sello_tiempo, orden_firma, tipo_firma (Firma / Visto Bueno / Toma de Razón / Fiscalización…). |
CircuitoFirma |
circuitos_firma |
Circuito 1:1 con un Procedimiento. |
FirmanteCircuito |
firmante_circuito |
Firmante del circuito: rol funcional + orden + tipo_firma. Varios con el mismo orden ⇒ firma en paralelo. |
3.4 Soporte documental
| Modelo | Tabla | Propósito |
|---|---|---|
Libro |
libros |
Libro de registro (1:1 con procedimiento); controla qué UDs aprobadas se registran y con qué acceso. |
Plantilla |
plantillas |
Plantilla HTML (editor Tiptap) opcionalmente ligada a un procedimiento. |
Reparo / ReparoComentario |
reparos / reparo_comentarios |
Reparos de intervención sobre UDs, con estado e hilo de comentarios. |
PropuestaGasto / PropuestaGastoProveedor |
propuestas_gasto / propuesta_gasto_proveedores |
Datos económicos 1:1 con UD: clasificación presupuestaria, base+IVA, comparativa de proveedores. |
Convocatoria / ConvocatoriaConvocado |
convocatorias / … |
Convocatorias (pleno, comisión) con orden del día (JSON) y convocados flexibles. |
Acta / ActaAsistente |
actas / … |
Actas con orden del día y asistentes flexibles. |
Contacto |
contactos |
Directorio corporativo, vinculable a expedientes (N:N). |
Mensaje |
mensajes |
Mensajería interna usuario↔usuario. |
EnlaceExterno |
enlaces_externos |
Accesos rápidos personales del usuario. |
Alerta / Notificacion |
alertas / notificaciones |
Avisos al usuario. |
3.5 Control de acceso
A dos niveles, cada uno con cuatro dimensiones (usuario / rol / departamento /
grupo) más el flag acceso_restringido:
- Expediente:
ExpedienteAccesoUsuario,…Rol,…Departamento,…Grupo. - Unidad documental:
UDAcceso(con check constraint de al menos un sujeto).
4. Endpoints REST
El módulo expone del orden de 70 endpoints. Se resumen por área (todos bajo
/api).
Expedientes
| Método | Ruta | Permiso |
|---|---|---|
POST |
/expedientes |
expediente:crear |
GET |
/expedientes · /expedientes/<id> |
expediente:ver |
PUT |
/expedientes/<id> |
expediente:editar |
DELETE |
/expedientes/<id> |
expediente:anular |
PUT |
/expedientes/<id>/accesos |
expediente:editar |
POST/GET |
/expedientes/<id>/resumen-ia · /resumen |
expediente:ver |
Unidades documentales
| Método | Ruta | Permiso |
|---|---|---|
GET/POST |
/expedientes/<id>/unidades-documentales |
ud:ver / ud:crear |
GET/PUT/DELETE |
/unidades-documentales/<id> |
ud:ver / ud:editar / ud:eliminar |
GET |
/unidades-documentales/<id>/download · /pdf |
ud:ver |
POST |
/unidades-documentales/<id>/aprobar |
ud:firmar |
PUT/GET |
/unidades-documentales/<id>/accesos · /destinatarios |
ud:ver / ud:editar |
Workflow
| Método | Ruta | Permiso |
|---|---|---|
GET |
/unidades-documentales/<id>/historial-workflow |
ud:ver |
GET |
/unidades-documentales/<id>/puede-ejecutar-transicion |
ud:ver |
POST |
/unidades-documentales/<id>/ejecutar-transicion |
ud:editar (workflow:ejecutar) |
Firma electrónica (firma.py)
| Método | Ruta | Permiso |
|---|---|---|
POST |
/unidades-documentales/<id>/solicitar-firma |
firma:solicitar |
POST |
/unidades-documentales/<id>/firmar |
firma:ejecutar |
POST |
/firmas/firmar-lote |
firma:ejecutar |
GET |
/unidades-documentales/<id>/firma-estado · /firmas |
ud:ver |
GET |
/firmas/pendientes · /firmas/bandeja |
bandeja:ver |
Archivo, libros, reparos, imputaciones
| Método | Ruta | Permiso |
|---|---|---|
GET |
/archivo-electronico · /archivo-electronico/serve/<path> |
archivo:ver |
GET |
/libros · /libros/<id> · /libros/<id>/contenido · /libros/<id>/zip |
libro:ver |
GET/POST |
/reparos/unidades-documentales/<id>/reparos |
reparos:ver / reparo:crear |
PUT |
/reparos/reparos/<id>/levantar |
reparo:levantar |
GET/POST/PUT/DELETE |
/expedientes/<id>/imputaciones · /imputaciones/<id> |
expediente:ver / expediente:editar |
Datos estructurados y auxiliares
| Área | Rutas (resumen) | Permiso |
|---|---|---|
| Propuesta de gasto | /unidades-documentales/<id>/propuesta-gasto, /proveedores, /adjuntos |
ud:ver / ud:editar |
| Actas | /unidades-documentales/<id>/acta, /asistentes/... |
ud:ver / documental:gestionar |
| Convocatorias | /unidades-documentales/<id>/convocatoria, /pdf, /convocatorias |
ud:ver / documental:gestionar |
| Contactos | /contactos, /expedientes/<id>/contactos |
contactos:ver / contactos:gestionar |
| Mensajería | /api/mensajes, /enviados, /departamento |
mensajes:usar |
| Enlaces externos | /api/enlaces-externos |
solo @token_required |
| Plantillas | /admin/plantillas |
documental:admin:gestionar_parametros |
| Dashboard | /dashboard/tareas-pendientes, /estadisticas, … |
@token_required |
5. Servicios internos e IA
Generación de PDF y firma
- El PDF de la UD se renderiza con WeasyPrint (plantilla HTML) y se calcula su hash SHA-256.
- La firma del módulo Documental es firma funcional por hash + CSV (registro
de firmante, orden, tipo, hash y sello de tiempo), no una firma criptográfica
X.509. (La firma criptográfica con
pyhanko/signxmlse usa en el módulo Registro para SICRES/SIR.) - Al completarse un circuito se genera el PDF final
{referencia}_{csv}.pdfy se archiva enruta_archivado.
Flujo de circuito de firma
flowchart TD
A[solicitar-firma] --> B[Validar: estado Revisada, sin reparos, circuito configurado]
B --> C[estado_firma = Pendiente · genera CSV · notifica orden 1]
C --> D[firmar: valida que el usuario tiene rol en el orden actual]
D --> E[Genera PDF + hash · crea FirmaElectronica]
E --> F{¿Quedan firmantes en este orden?}
F -- sí --> D
F -- no --> G{¿Hay orden siguiente?}
G -- sí --> H[Notifica siguiente orden] --> D
G -- no --> I[PDF final + hooks + workflow a Aprobada]
Hooks al completar la firma
Cuando una UD termina su circuito, según su procedimiento se disparan acciones en otros módulos: avance del workflow de Presupuesto (UD CONTROL), y en Tesorería/Recaudación las aprobaciones de Pago a Justificar, Endoso, Embargo, Compensación y Liquidación.
Búsqueda semántica (search.py)
- FAISS (
IndexFlatIP, similitud coseno, umbral 0.25) + sentence-transformers (modeloparaphrase-multilingual-MiniLM-L12-v2). - Búsqueda híbrida: combina resultados semánticos (FAISS) con búsqueda textual SQL, deduplicando.
- Índices persistidos (
search_index.faiss+search_mapping.json); reindexado incremental desde otros módulos y completo vía endpoint. POST /search-ia(expediente:ver) yPOST /search/reindex(admin:sistema:gestionar).
Chatbot "Clara" (RAG) y asistente
chatbot_endpoint.py→POST /api/chatbot/preguntar. Estrategia en dos niveles:- Herramientas (
chatbot_tools.py): intención reconocida → consulta directa (saldo de cuenta, top proveedores, resultado de periodo, resumen de trabajo…). - RAG (
rag_utils.py): búsqueda enBaseConocimiento(FAISS + fallback SQL) y respuesta generada con Google Gemini (gemini-2.5-flashpor defecto). assistant.py→POST /documental/assistant/writing: mejorar/formalizar/resumir texto.conocimiento_api.py: CRUD deBaseConocimiento.
6. Permisos y roles
≈25 permisos del dominio documental (en seed.py). Códigos principales:
| Categoría | Permisos |
|---|---|
| Expedientes | expediente:ver, expediente:ver:todos, expediente:crear, expediente:editar, expediente:anular. |
| Unidades documentales | ud:ver, ud:crear, ud:editar, ud:eliminar, ud:firmar. |
| Workflow / firma | workflow:ejecutar, firma:solicitar, firma:ejecutar, bandeja:ver. |
| Libros / archivo | libro:ver, archivo:ver. |
| Reparos | reparo:crear, reparo:levantar, reparos:ver, reparos:resolver. |
| Contactos / mensajería | contactos:ver, contactos:gestionar, mensajes:usar. |
| Administración | documental:admin:gestionar_parametros, documental:administrar. |
| Compromisos (presupuesto) | expediente:comprometidos:crear/editar/confirmar/anular/eliminar. |
Acceso efectivo a un expediente
Tener expediente:ver no basta: el acceso real a un expediente/UD concreto se
comprueba además contra las relaciones de acceso (usuario/rol/depto/grupo) y el
flag acceso_restringido. expediente:ver:todos salta esa restricción.
7. Integraciones
MOS — crons
| Acción | Periodicidad | Función |
|---|---|---|
workflow.verificar_sla |
periódica (p. ej. cada 15 min) | Detecta pasos con SLA vencido y notifica/escala al jefe o supervisor. |
conocimiento.generar_automatico |
configurable (p. ej. semanal) | Genera entradas Q&A de la base de conocimiento con Gemini, deduplicando. |
MOS — eventos
Eventos de auditoría en altas/cambios/firmas (p. ej. UD_SOLICITAR_FIRMA,
UD_FIRMAR, y eventos en expedientes, reparos, plantillas, etc.).
Otros módulos
- Presupuesto: la UD CONTROL articula el ciclo legal de aprobación; las imputaciones presupuestarias cuelgan del expediente.
- Contabilidad: la propuesta de gasto enlaza con clasificación presupuestaria, reglas contables y facturas.
- Tesorería / Recaudación: hooks al completar firma (PJ, endoso, embargo, compensación, liquidación).
- Identidad: usa
Usuario,Rol,RolFuncional,Departamento, grupos.
Sistemas externos
- Google Gemini (vía
google-genai) para chatbot, asistente y resúmenes. - WeasyPrint para generación de PDF.