Modelo de datos¶
Persistencia local y desplegable¶
SQLite contiene dos tablas en el bootstrap:
analysis_reports: id, actor, created_at, engine, resource, riesgo, resultado y report JSON.audit_events: id, actor, action, resource, outcome, correlation_id y created_at.
El JSON conserva el contrato completo del análisis mientras el modelo todavía evoluciona. Cada reporte y resumen expone contract_version; los reportes ya almacenados sin este campo se leen como versión 1.0 mediante el valor por defecto del modelo. Por ello REPORT-02 no requiere reescribir datos ni modificar el esquema SQLite inicial.
El historial paginado filtra por las columnas indexables ya existentes (engine, resource, actor_id, risk y outcome) y obtiene la versión desde el JSON del reporte. La lista heredada se conserva para compatibilidad; la página versionada se publica en /api/v1/analyses/history.
La apertura de SQLite ejecuta la migración versionada 001, compatible con tablas previas: añade project_id y correlation_id cuando faltan, registra la versión en schema_migrations y crea los índices del historial/auditoría. Las escrituras se serializan con un lock del proceso y hacen rollback explícito ante error.
PostgreSQL implementa el mismo puerto ReportStore en infrastructure/store.py. DATABASE_URL_REF selecciona el proveedor mediante una referencia env:NOMBRE; una referencia vacía conserva DATABASE_PATH y SQLite para demo. La migración backend/migrations/001_initial.sql crea analysis_reports con JSONB, audit_events, schema_migrations e índices por proyecto/fecha, motor/recurso, actor/fecha, riesgo/resultado y acción. Cada operación PostgreSQL usa una conexión transaccional independiente, por lo que las escrituras concurrentes no comparten estado mutable.
Antes de cada escritura o consulta se elimina lo anterior a REPORT_RETENTION_DAYS para reportes y AUDIT_RETENTION_DAYS para auditoría (90 días por defecto). Los campos persistidos se someten a una redacción defensiva de credenciales, tokens y contraseñas. La integración limpia de PostgreSQL se ejecuta en tests/test_postgres_integration.py y en el job CI postgres-integration.
Límites¶
No se almacenan credenciales de conexión, documentos completos de una fuente real ni secretos. La URL PostgreSQL solo se resuelve en memoria desde una referencia de entorno. OPS-03 añade backup/restore lógico cifrado, verificación contra datos sintéticos, rollback y retención externa; el procedimiento no ejecuta respaldos automáticamente desde la API.