Saltar a contenido

Módulo Padrón de Habitantes

En una frase

Padrón municipal completo conforme a la Ley 7/1985 y al RD 1690/1986: territorio y callejero (Catastro + INE), habitantes y residencias con cifrado en reposo, movimientos con hash-chain, comunicación mensual con el INE (IDA clásico y eIDA), inspección, renovaciones (NIE-NC y comunitarios), volantes y certificados firmados, cifras oficiales anuales, explorador estadístico y verificación de residencia (SVDR/SCSP) en ambos sentidos.

1. Propósito y alcance

  • Territorio y callejero: distritos, secciones censales, vías, fincas, viviendas. Importación masiva desde Catastro y cartografía oficial del INE (shapefile).
  • Habitantes: alta, baja, modificación, cambio de domicilio. Datos sensibles (DNI, fecha y lugar de nacimiento) cifrados en reposo (Fernet) con hash de búsqueda no reversible.
  • Hojas padronales: representan la unidad de convivencia por vivienda.
  • Movimientos: log inmutable con hash-chain (SHA-256 encadenado) para integridad demostrable ante INE y auditoría.
  • Comunicación INE (IDA/eIDA): generación mensual del fichero de variaciones (Resolución INE/DGCAH 17/02/2020), envío al portal o por web service y procesado de devoluciones (incidencias).
  • Inspección: 8 reglas automáticas que crean casos para revisión humana (sobrepoblación, NIE caducando, etc.).
  • Renovaciones: bianual (NIE-NC) y quinquenal (comunitarios sin certificado permanente), con notificación oficial al ciudadano vía Registro de Salida + PDF con CSV verificable.
  • Volantes y certificados: 4 variantes (individual / colectivo / histórico / convivencia) con firma electrónica PAdES-T y verificación pública en la sede.
  • Cifras oficiales: snapshot anual a 1 enero, aprobado por Decreto de Alcaldía (art. 81 RD 1690/1986) con informe PDF y métricas detalladas (pirámide, nacionalidades, distritos).
  • Explorador estadístico: análisis libre por dimensión (distrito / sección / vía / finca), con comparativa real A vs B y exportación a PDF / XLSX con gráficos.
  • Verificación de residencia (SVDR/SCSP): cesión entrante (API keys
  • audit log) y saliente al padrón nacional INE/PID (modo MOCK operativo + PRODUCTION cuando haya convenio + certificado FNMT).
  • Mapas Leaflet con visor de finca, mapa de vía y mapa de calor por sección censal (point-in-polygon con shapely).

2. Estructura de archivos

app/modules/padron_habitantes/
├── routes.py                     # Blueprint principal (~5800 líneas, ~250 endpoints)
├── models.py                     # Todos los modelos (~2300 líneas, 22 tablas)
├── permisos.py                   # Catálogo de 42 permisos canónicos
└── servicios/
    ├── operaciones.py            # Alta / modificar / cambio_domicilio / baja
    ├── validador_documentos.py   # DNI/NIE/Pasaporte + hash_documento (SHA-256)
    ├── inspeccion.py             # 8 reglas + cron diario
    ├── renovaciones.py           # Detección bianual/quinquenal + cron mensual
    ├── snapshot_anual.py         # Cifras oficiales + cron 2 enero
    ├── estadisticas.py           # Explorador (cálculos)
    ├── estadisticas_export.py    # PDF (WeasyPrint + SVG) y XLSX (openpyxl BarChart)
    ├── bandeja_ida.py            # Generación fichero IDA mensual
    ├── procesador_devoluciones.py# Parsing CSV/TXT de respuesta INE
    ├── cliente_eida.py           # Cliente SOAP eIDA (mock + production)
    ├── generador_certificados.py # PDF de volantes y certificados (PyHanko PAdES-T)
    ├── firma_*.py                # Sello órgano / cert personal / AutoFirma / TSA
    ├── csv_verificacion.py       # CSV público verificable en sede
    ├── svdr_saliente.py          # Cliente saliente al INE/PID (MOCK + production)
    ├── svdr.py                   # API keys + consultas SVDR entrantes
    ├── geo_secciones.py          # Point-in-polygon vía→sección (shapely)
    ├── cartografia_ine.py        # Import shapefile INE (pyshp + pyproj)
    ├── catastro.py / catastro_sync.py # Cliente Catastro + sincronización
    ├── importador_csv.py         # Importador legacy CSV-INE
    ├── importador_masivo.py      # Importador masivo desde Catastro
    └── dashboard.py              # Métricas para el cuadro de mando

Blueprint registrado en app/__init__.py:

Blueprint url_prefix
padron_habitantes_bp /api/padron-habitantes

Dónde viven los modelos

A diferencia de Tesorería, todos los modelos del Padrón están en app/modules/padron_habitantes/models.py. No comparte modelos con otros módulos: las interacciones (p.ej. con Registro para notificaciones) se hacen vía servicios y emit_event.

3. Modelos de datos

3.1 Territorio y callejero

Modelo Tabla Propósito
PadronDistrito padron_hab_distrito Distrito censal (codigo INE 2 dígitos).
PadronSeccion padron_hab_seccion Sección censal (codigo 3 dígitos). Incluye geometria_geojson + centroid_lat/lon para mapas.
PadronVia padron_hab_via Calle/plaza/avenida con tipo_via, codigo_ine, seccion_id.
PadronFinca padron_hab_finca Portal (número de la calle) con numero, referencia_catastral (14 chars), coord_lat/lon.
PadronVivienda padron_hab_vivienda Subdivisión de la finca (bloque/escalera/planta/puerta) con referencia_catastral (20 chars), estado (ACTIVA/INACTIVA).

3.2 Habitantes, hojas y residencias

Modelo Tabla Propósito
PadronHabitante padron_hab_habitante Persona empadronada. Campos cifrados (documento, fecha_nacimiento, lugar_nacimiento); búsqueda exacta por doc_busqueda (SHA-256).
PadronHabitanteDocumento padron_hab_habitante_doc Documentos adjuntos al habitante (DNI escaneado, etc.).
PadronHojaPadronal padron_hab_hoja Hoja por vivienda con representante_id, estado, fechas apertura/cierre.
PadronResidencia padron_hab_residencia Relación habitante↔vivienda↔hoja con fecha_alta/fecha_baja, relacion (PROPIETARIO/INQUILINO/...), regimen_tenencia. Inmutable: los cambios se hacen cerrando y abriendo otra.

3.3 Movimientos (log inmutable con hash-chain)

Modelo Tabla Propósito
PadronMovimiento padron_hab_movimiento Cada cambio del padrón: tipo (ALTA_, BAJA_, MODIFICACION, CAMBIO_DOMICILIO, RENOVACION), ejercicio+numero correlativos por entidad, referencia (M-AAAA-NNNNNNNN), hash_anterior+hash_propio (encadenados SHA-256), enviado_ine.

3.4 Comunicación INE

Modelo Tabla Propósito
PadronFicheroIDA padron_hab_fichero_ida Fichero mensual generado: ejercicio+mes, canal (CLASICO/EIDA), estado (GENERADO/ENVIADO/DEVOLUCION_PARCIAL/ACEPTADO_TOTAL/ERROR), SHA-256, ruta storage.
PadronIncidenciaINE padron_hab_incidencia_ine Cada error detectado por el INE en la devolución: codigo_error (01/02/04/06/15/21/30), descripcion, severidad, estado (PENDIENTE/EN_GESTION/RESUELTA/DESCARTADA).

3.5 Cifras oficiales (snapshot anual)

Modelo Tabla Propósito
PadronSnapshotAnual padron_hab_snapshot_anual Foto fija a 1 enero del ejercicio: totales, edad media, metricas_json con pirámide quinquenal + top nacionalidades + distribución por distrito. Estados: BORRADOR/APROBADO/SUSTITUIDO.

3.6 Inspección y renovaciones

Modelo Tabla Propósito
PadronInspeccionCaso padron_hab_inspeccion_caso Caso detectado por una de las 8 reglas: tipo (SOBREPOBLACION, SIN_RENOVACION, NIE_NC_CADUCAR, NO_OBLIGADO_QUINQUENAL, VIVIENDA_VACIA, HABITANTE_SIN_RESIDENCIA, RESIDENCIA_VIV_INACTIVA, DOCUMENTO_DUPLICADO), severidad, datos_json con detalle.
PadronRenovacion padron_hab_renovacion Renovación programada: tipo (NIE_NC_BIANUAL/NO_OBLIGADO_QUINQUENAL), fecha_vencimiento, estado (PROGRAMADA/NOTIFICADO/RENOVADO/NO_RENOVADO/BAJA), registro_salida_id cuando se notifica.

3.7 Certificados y firma

Modelo Tabla Propósito
PadronCertificado padron_hab_certificado Volante o certificado emitido: tipo (VOLANTE/CERTIFICADO), variante (INDIVIDUAL/COLECTIVO/HISTORICO/CONVIVENCIA), PDF firmado en storage, CSV verificable, estado (EMITIDO/PENDIENTE_FIRMA/FIRMADO).
PadronCertSelloEntidad padron_hab_cert_sello_entidad Cert .p12 FNMT del sello de órgano por entidad, cifrado Fernet en BD.
PadronCertPersonal padron_hab_cert_personal Cert personal del firmante (si la entidad lo habilita).

3.8 Verificación de residencia (SVDR/SCSP)

Modelo Tabla Propósito
PadronApiKeySVDR padron_hab_apikey_svdr API key autorizada para que otra AAPP consulte nuestro padrón. Solo se guarda el hash + prefijo.
PadronConsultaSVDR padron_hab_consulta_svdr Audit log de consultas entrantes (LO 3/2018 art. 6): organismo, finalidad, documento consultado, IP, resultado.
PadronConsultaSalienteSVDR padron_hab_consulta_saliente_svdr Audit log de consultas salientes (las que hacemos al INE/PID): documento, finalidad, expediente propio, modo (MOCK/PRODUCTION), resultado, municipio devuelto.

3.9 Configuración multi-tenant

Modelo Tabla Propósito
PadronConfiguracion padron_hab_configuracion Una fila por entidad: codigo_ine_municipio, canal_ida, datos Catastro, métodos de firma habilitados, roles funcionales, parámetros SVDR saliente (modo/URL/cert).

4. Ciclo de un habitante (alta → cambio → baja)

flowchart LR
    A["Alta habitante<br/>(wizard 4 pasos)"] -->|servicio operaciones.alta_habitante| B["Hoja + Residencia + Movimiento (ALTA_*)"]
    B -->|hash-chain| H[(Movimiento N+1)]
    B -.cron mensual.-> IDA["Fichero IDA"]
    IDA --> INE["INE<br/>(portal o eIDA)"]
    INE -->|devolución| INC["Incidencias INE"]
    B -.después.-> M["Modificación / Cambio domicilio / Baja"]
    M --> H
  1. El operario abre el wizard de alta (4 pasos: tipo, datos personales, vivienda, confirmación). El servicio alta_habitante valida documento (algoritmo módulo 23), comprueba duplicados por doc_busqueda, crea PadronHabitante con datos cifrados, abre o reutiliza la PadronHoja de la vivienda y crea la PadronResidencia + el PadronMovimiento de alta con su hash encadenado al movimiento anterior.
  2. Cambios posteriores (modificación de datos, cambio de domicilio, baja por defunción / cambio residencia / inscripción indebida) nunca actualizan la residencia anterior: la cierran con fecha_baja y abren una nueva.
  3. El cron mensual padron_habitantes.ida.generar_mensual recopila los movimientos del mes y construye el TXT IDA (charset ISO-8859-15, posiciones fijas según resolución INE).
  4. En canal CLASICO el operario lo descarga, lo sube manualmente al portal intercambio.ine.es, marca como ENVIADO en la app y, cuando recibe respuesta del INE, sube el CSV de devolución → el sistema parsea, marca movimientos como aceptados y crea incidencias por cada rechazo (con guía contextual de qué hacer según el código).

5. Comunicación con el INE (IDA / eIDA)

flowchart TD
    M["Movimientos del mes<br/>enviado_ine=False"] -->|cron 1 de mes 06:00| GEN["generar_mensual()"]
    GEN --> TXT["Fichero IDA (.txt)<br/>estado=GENERADO"]
    TXT -->|canal CLASICO| MAN["Operario sube a<br/>intercambio.ine.es"]
    MAN -->|Marcar enviado| ENV["estado=ENVIADO"]
    TXT -->|canal EIDA| WS["cliente_eida.enviar()<br/>SOAP a INE"]
    WS --> ENV
    ENV -->|devolución INE| DEV["procesador_devoluciones.py"]
    DEV --> ACC["Movimientos aceptados<br/>estado=ACEPTADO_TOTAL"]
    DEV --> INC["Incidencias creadas<br/>(PENDIENTE)"]
    INC -->|operario gestiona| RES["RESUELTA / DESCARTADA"]
  • Codes de error IDA conocidos: 01 (duplicado), 02 (no encontrado), 04 (fecha incongruente), 06 (documento erróneo), 15 (domicilio inexistente), 21 (discordancia leve), 30 (movimiento previo no procesado). Cada uno tiene guía de actuación en la UI.
  • Anti-duplicado: si ya existe un IDA ACEPTADO_TOTAL del mismo mes, no se regenera; si hay BORRADOR se actualiza.

6. Inspección y renovaciones

flowchart LR
    CRON["Cron diario 04:00"] --> R["8 reglas de inspección"]
    R -->|caso nuevo| CASO["PadronInspeccionCaso<br/>(PENDIENTE)"]
    R -->|asignación geo| ASIG["geo_secciones.asignar()"]
    CRONM["Cron mensual día 1 05:00"] --> DET["renovaciones.detectar_pendientes()"]
    DET --> PROG["PadronRenovacion<br/>(PROGRAMADA)"]
    PROG -->|operario notifica| NOT["Registro de SALIDA + PDF<br/>(NOTIFICADO)"]

Detector de inspección (inspeccion.py): anti-duplicado por (entidad, tipo, sujeto) — si ya hay caso PENDIENTE/EN_REVISION, solo actualiza ultima_deteccion.

Regla Umbral default Severidad
SOBREPOBLACION >8 residentes activos MEDIA / ALTA (>1.5×)
SIN_RENOVACION >5 años sin movimientos MEDIA
NIE_NC_CADUCAR 60 días antes ALTA (≤15d) / MEDIA
NO_OBLIGADO_QUINQUENAL 60 días antes MEDIA
VIVIENDA_VACIA >30 días sin habitantes MEDIA / ALTA (>90d)
HABITANTE_SIN_RESIDENCIA inmediato ALTA
RESIDENCIA_VIV_INACTIVA inmediato ALTA
DOCUMENTO_DUPLICADO inmediato (DISTINCT hash) ALTA

Renovaciones: el cron mensual crea PROGRAMADA para NIE-NC y comunitarios cuya fecha_proxima_renovacion está entre hoy y +60 días. El operario notifica() → genera PDF con CSV verificable, crea Registro de SALIDA en el módulo Registro, archiva como documento del habitante y pasa a NOTIFICADO.

7. Cifras oficiales (snapshot anual)

snapshot_anual.calcular() agrupa los habitantes empadronados a 1 enero del ejercicio:

  • Habitantes con estado=EMPADRONADO + residencia con fecha_alta ≤ 1/1/AAAA AND (fecha_baja IS NULL OR fecha_baja > 1/1/AAAA).
  • Calcula totales por sexo, extranjeros, edad media (descifrando fecha_nacimiento en memoria).
  • Construye pirámide quinquenal por sexo (M/F).
  • Top 15 nacionalidades y distribución por distrito (cruzando residencia → vivienda → finca → vía → sección → distrito).
  • Guarda como BORRADOR; al aprobar(), marca SUPERSEDED el anterior aprobado y graba aprobado_pleno_acta con la referencia del Decreto.

Cron: padron_habitantes.snapshot.generar_anual el 2 de enero a las 03:00 (genera el BORRADOR; la aprobación es manual).

Decreto de Alcaldía, no Pleno

El art. 81 RD 1690/1986 dice "los Ayuntamientos aprobarán la revisión" sin especificar órgano. La práctica generalizada y aceptada por el INE es Decreto/Resolución de Alcaldía. El Pleno solo entra si hay alegaciones a las cifras propuestas por el INE o si cambia la división territorial.

8. Volantes y certificados

Tipo Validez legal Firma requerida Variantes
Volante Informativo, sin firma NO INDIVIDUAL / COLECTIVO / HISTORICO / CONVIVENCIA
Certificado Documento oficial SÍ (sello órgano, cert personal o AutoFirma) Las mismas 4 variantes

Flujo de firma (generador_certificados.py):

  1. PyHanko genera el PDF con cajetín de firma visible (QR + datos del firmante).
  2. Se aplica firma según el método elegido por la entidad/firmante:
  3. Sello órgano: cert .p12 FNMT cifrado en BD → firmado en servidor sin interacción.
  4. Cert personal: firmante sube su .p12.
  5. AutoFirma: el cliente Java del firmante lo firma localmente y devuelve el PDF firmado.
  6. Se añade sello de tiempo PAdES-T contra TSA (DigiCert público por defecto, configurable).
  7. Se genera un CSV verificable público (formato XX-NNNNNN-NNNN) y se registra en app.servicios.csv_verificacion.
  8. Se guarda como PadronCertificado con ruta storage y hash.

Verificación pública: pantalla /verificacion-documento/{csv} en la sede ciudadana muestra el PDF firmado + datos del firmante + validación PAdES con PyHanko (sin necesidad de Adobe Reader).

9. Verificación de residencia (SVDR/SCSP)

Dirección entrante (otras AAPP nos consultan):

flowchart LR
    AAPP["Otra AAPP<br/>(SCSP/PID)"] -->|X-API-KEY| EP["POST /svdr/consultar"]
    EP -->|svdr.validar_api_key| KEY["PadronApiKeySVDR<br/>(activa, no expirada)"]
    KEY --> Q["Consulta padrón local"]
    Q --> RES["OK_EMPADRONADO / NO_EMPADRONADO / NO_LOCALIZADO"]
    RES --> LOG["PadronConsultaSVDR<br/>(audit log)"]
    LOG --> RESP["JSON respuesta"]
  • Endpoint público POST /padron-habitantes/svdr/consultar sin token JWT, autenticado solo por X-API-KEY validada contra PadronApiKeySVDR.
  • Cada llamada queda registrada (LO 3/2018).
  • Las keys se generan en la UI con cadena en claro mostrada una sola vez; en BD solo hash SHA-256 + prefijo de 8 chars.

Dirección saliente (nosotros consultamos al INE/PID):

flowchart LR
    OP["Operario<br/>(p.ej. resolver incidencia)"] --> UI["Pantalla Consultar"]
    UI -->|POST /svdr/consultar-externo| SVC["svdr_saliente.consultar()"]
    SVC -->|modo| M{Modo}
    M -->|MOCK| MOCK["Respuesta determinista<br/>por hash del documento"]
    M -->|PRODUCTION| PID["Cliente SOAP a PID<br/>(cert FNMT)"]
    MOCK --> LOG2["PadronConsultaSalienteSVDR"]
    PID --> LOG2
  • Modo MOCK (default): respuestas deterministas para desarrollo y formación. Reglas: documento terminado en Z → NO_LOCALIZADO, X → NO_EMPADRONADO, resto → empadronado en municipio determinista por hash (con detección del habitante en BD local para simular caso "confirma vs duplicado").
  • Modo PRODUCTION: requiere convenio PID + cert FNMT + URL real. Pendiente de implementar el cliente SOAP cuando haya entorno real.
  • Integrado en Incidencias INE: si el código es 01 (duplicado), un botón ofrece "Consultar SVDR" que rellena la consulta con origen=incidencia_ine:N.

10. Importación masiva desde Catastro

flowchart TD
    CFG["PadronConfiguracion<br/>provincia + municipio Catastro"] --> F1["Fase 1: descarga vías"]
    F1 --> F1B["Fase 1: ConsultaNumero por vía<br/>→ fincas con RC14"]
    F1B --> F2["Fase 2: Consulta_DNPRC por finca<br/>→ viviendas (subdivisión)"]
    F2 --> F2B["Fase 2: Consulta_CPMRC<br/>→ coordenadas WGS84"]
    F2B --> ASIG["Asignación geo<br/>vía → sección (point-in-polygon)"]
    ASIG --> OK["Callejero completo"]
  • Cliente HTTP a ovc.catastro.meh.es (servicios públicos, sin autenticación).
  • Rate limit auto: 0,4 s entre peticiones (Catastro banea por IP a partir de ~5 req/s sostenidos; el sistema detecta 403/429 y aborta).
  • Pausa entre lotes configurable; modo "Solo Fase 2" para reimportaciones parciales (procesa solo fincas sin coords).
  • Idempotente: si una finca ya tiene coords no las recalcula.
  • Al terminar Fase 2 dispara automáticamente geo_secciones.asignar_secciones_automatico() para emparejar vías sueltas con su sección censal vía point-in-polygon sobre el polígono de la sección (importado del shapefile INE).

11. Endpoints REST

Del orden de 250 endpoints bajo /api/padron-habitantes. Resumen por área:

Área Rutas (ejemplos) Permiso
Habitantes /habitantes, /<id>, POST alta, PUT modificar, DELETE baja, /cambio-domicilio padron_habitantes:habitante:*
Hojas /hojas, /<id> padron_habitantes:hoja:ver
Movimientos /movimientos (paginado con 7 filtros) padron_habitantes:movimiento:ver
Territorio /distritos, /secciones, /vias, /fincas, /viviendas (todas con filtros y búsqueda) padron_habitantes:callejero:*, :vivienda:*
Catastro /catastro/* (importar-masivo/preparacion, importar-fincas-lote, importar-viviendas-lote, sincronizar-via, …) padron_habitantes:territorio:gestionar
Cartografía INE /cartografia/importar, /cartografia/diff padron_habitantes:territorio:gestionar
IDA / Incidencias /ida/ficheros, /ida/generar, /ida/ficheros/<id>/descargar, /marcar-enviado, /devolucion, /incidencias, /incidencias/<id>/resolver padron_habitantes:ina:ver/gestionar
Cifras oficiales /snapshots, /snapshots/generar, /<id>/aprobar, /<id>/informe padron_habitantes:cifras:ver/aprobar
Inspección /inspeccion/casos, /inspeccion/detectar, /casos/<id>/resolver padron_habitantes:inspeccion:ver/gestionar
Renovaciones /renovaciones, /<id>/notificar, /<id>/cerrar, /detectar padron_habitantes:renovacion:ver/gestionar
Volantes/certif. /certificados, POST emitir, /<id>/firmar, /<id>/descargar padron_habitantes:volante:emitir, :certificado:emitir/firmar
Verificación pública /verificacion-documento/<csv> (sin token) público
Explorador /estadisticas/selector/<dim>, /estadisticas/explorar, /exportar padron_habitantes:explorador:ver
SVDR entrante /svdr/apikeys (CRUD), /svdr/consultas, /svdr/consultar (público) padron_habitantes:svdr:admin/auditar + key
SVDR saliente /svdr/consultar-externo, /svdr/consultas-salientes padron_habitantes:svdr:admin
Dashboard /dashboard/resumen, /dashboard/top-nacionalidades, /dashboard/nacionalidades.xlsx padron_habitantes:dashboard:ver
Mapas /secciones/asignar-automatico, /secciones/estadisticas-geo, /vias/<id> padron_habitantes:territorio:ver
Configuración /configuracion, /configuracion/cert-sello padron_habitantes:admin:gestionar

12. Servicios internos

Servicio Responsabilidad
operaciones.py Alta / modificación / cambio de domicilio / baja, con creación de movimiento+hash.
validador_documentos.py Validación DNI (módulo 23), NIE y pasaporte. hash_documento() SHA-256 para búsqueda exacta sin descifrar.
inspeccion.py 8 reglas + cron diario + anti-duplicado.
renovaciones.py Detección + integración con Registro de Salida + cron mensual.
snapshot_anual.py Cálculo del snapshot, agregaciones, pirámide, top nacionalidades.
estadisticas.py Explorador interactivo (multi-select dimensión, comparativa, pirámide, franjas edad, top nacionalidades con UE/no-UE).
estadisticas_export.py PDF (WeasyPrint + SVG inline pirámide/franjas/nacionalidades) y XLSX (openpyxl con BarChart nativos).
bandeja_ida.py Generación TXT IDA + persistencia + SHA-256. Soporte canal CLASICO y EIDA.
cliente_eida.py Cliente SOAP eIDA (mock + production).
procesador_devoluciones.py Parsing CSV/TXT de respuesta INE → marca movimientos aceptados + crea incidencias.
generador_certificados.py PDF de volantes y certificados con PyHanko, cajetín visible + QR + CSV.
firma_sello.py / firma_personal.py / firma_autofirma.py 3 métodos de firma habilitables por entidad.
firma_tsa.py Sello de tiempo PAdES-T contra TSA configurable.
csv_verificacion.py Generación y validación del CSV público verificable en sede.
svdr.py API keys + endpoint público de consulta entrante.
svdr_saliente.py Cliente saliente al INE/PID (MOCK + production).
geo_secciones.py Point-in-polygon vía→sección con shapely + asignación masiva.
cartografia_ine.py Parseo del shapefile INE (pyshp), proyección UTM→WGS84 (pyproj).
catastro.py / catastro_sync.py Cliente público a OVCCallejero + OVCCoordenadas con rate-limit.
importador_masivo.py / importador_csv.py Carga inicial del callejero (Catastro o CSV legacy INE).
dashboard.py KPIs y agregaciones para el cuadro de mando del jefe de Padrón.
audit.py Helper emit_padron_event para auditoría enriquecida con meta funcional.

13. Crons MOS

Acción registrada Frecuencia Función
padron_habitantes.inspeccion.detectar Diario 04:00 Las 8 reglas + asignación geo vía→sección
padron_habitantes.renovaciones.detectar Día 1 mes 05:00 Crea PROGRAMADAS NIE-NC y comunitarios
padron_habitantes.ida.generar_mensual Día 1 mes 06:00 Genera fichero IDA del mes anterior
padron_habitantes.snapshot.generar_anual 2 enero 03:00 Snapshot oficial (BORRADOR)
padron_habitantes.cert_sello.vigilar_caducidad Diario Avisa si cert FNMT caduca en ≤30 días

14. Permisos y roles

42 permisos canónicos padron_habitantes:* agrupados por área:

Categoría Permisos (ejemplos)
Habitantes habitante:ver/crear/editar/eliminar
Vivienda / callejero vivienda:ver/gestionar, finca:ver, callejero:ver/importar, territorio:ver/gestionar
Hojas y residencias hoja:ver/gestionar, residencia:ver
Movimientos movimiento:ver
Volantes / certificados volante:emitir, certificado:emitir/firmar/ver
Comunicación INE ina:ver/gestionar, incidencia:gestionar, minhap:comunicar
Cifras oficiales cifras:ver/aprobar
Inspección / renovaciones inspeccion:ver/gestionar, renovacion:ver/gestionar
Explorador / dashboard explorador:ver, dashboard:ver
SVDR svdr:admin/auditar
Administración admin:gestionar

Rol agregador: Jefe de Padrón con los 42 permisos. Rol funcional para firma: configurable en PadronConfiguracion.rol_funcional_firma_cert_id (típicamente Alcalde o Secretario).

15. Cifrado y seguridad de datos

  • Cifrado en reposo (app/utils/encrypted_string.py, TypeDecorator Fernet):
  • documento, fecha_nacimiento, lugar_nacimiento del habitante.
  • Cert .p12 del sello de órgano (en PadronCertSelloEntidad.cert_p12_cifrado).
  • Hash de búsqueda no reversible: doc_busqueda = SHA-256 hex de TIPO:VALOR_NORMALIZADO. Permite igualdad exacta sin descifrar.
  • Hash-chain en movimientos: cada PadronMovimiento tiene hash_anterior (del anterior) y hash_propio (SHA-256 del contenido). Garantiza integridad demostrable.
  • Audit log en PadronConsultaSVDR (entrante) y PadronConsultaSalienteSVDR (saliente) — obligatorio LO 3/2018.
  • emit_event en todas las acciones críticas (alta, baja, modificación, generación IDA, aprobación snapshot, firma certificado, …) con meta funcional.

16. Mapas Leaflet (frontend)

3 fases de cartografía interactiva:

Pantalla Capa base Overlay Datos
Visor finca OSM + WMS Catastro (60%) Marker individual Coordenadas de una finca
Mapa vía OSM + WMS Catastro (40%) Markers numerados por portal Todas las fincas de la vía
Mapa de calor secciones OSM + WMS Catastro (35%) GeoJSON de polígonos coloreados Habitantes/viviendas/vías por sección
  • Buscador server-side de vías con debounce 300 ms.
  • flyToBounds con maxZoom 18 y padding 60px al elegir vía.
  • Resaltado amarillo 8 s de la sección destacada.

17. Integraciones

  • Documental: los volantes/certificados quedan archivados como PadronHabitanteDocumento del habitante.
  • Registro: la notificación de renovaciones crea un Registro de Salida vía endpoint /registro/salidas y enlaza el ID en PadronRenovacion.registro_salida_id.
  • Sede electrónica: la verificación pública del CSV de un certificado se hace en /verificacion-documento/<csv> (sin token).
  • MOS: 5 crons registrados (ver §13).
  • INE / PID: comunicación IDA mensual + consulta SVDR (entrante y saliente).
  • Catastro: callejero y coordenadas vía servicios públicos.

Errores

Catálogo servicios/errors.py con códigos PAD-* por área (PAD_001 validación, PAD_3xx habitantes, PAD_5xx IDA/incidencias, PAD_7xx SVDR, etc.).

18. Estado actual y próximos pasos

Estado al cierre de las pruebas E2E (07-08/06/2026):

  • ✅ Todas las pantallas operativas y validadas con datos demo.
  • ✅ Cron MOS funcionando (inspección, renovaciones, IDA, snapshot, caducidad cert).
  • ✅ SVDR saliente operativo en modo MOCK; pendiente cliente PRODUCTION cuando haya cert FNMT + convenio PID.
  • ⚠️ Pantalla HojasList existe en modelo, no en UI (los datos se ven por el detalle del habitante).
  • ⚠️ Importador CSV-INE existe pero no se ha probado (sin CSV de prueba).
  • ⚠️ Modo PRODUCTION de SVDR saliente: requiere implementar cliente SOAP/REST cuando haya entorno real para probar.

Para la puesta en producción consultar la guía completa en Manual de Implantación → Padrón — puesta a producción.