Saltar al contenido principal

Auditoría

El log de auditoría (audit_log) registra toda mutación del sistema: quién la hizo, sobre qué entidad, con qué acción, y el estado antes y después del cambio. Es append-only (inmutable) y forma parte del Core Value de TankOS —la auditoría completa— junto con los cálculos custody correctos y los tickets sin huecos: si todo funciona pero no se puede rastrear quién cambió qué, el sistema no sirve para el cliente. El visor de auditoría vive en /admin/audit. Esta página está orientada al auditor (administrador) y al supervisor: cómo investigar quién cambió qué, cuándo y de qué valor a qué valor.

Quién puede ver y quién puede exportar

Ver la auditoría es OR (admin o supervisor); exportarla es admin-only

El acceso al visor usa semántica OR, no AND: GET /admin/audit está protegido con @AnyAuthority('admin:system', 'lab:approve'), así que lo ve el administrador O el supervisor. El export en CSV, en cambio, es exclusivo del administrador (admin:system, POST /admin/audit/export): el supervisor ve el botón "Exportar CSV" deshabilitado (con tooltip), y solo el administrador lo puede usar.

Esto es least-privilege deliberado (D-03): el administrador no tiene autoridades operativas —no afora, no aprueba, no emite tickets—, pero posee la auditoría y su export. El supervisor, que sí es un actor operativo, puede investigar el log (su rol de "segundo par de ojos") pero no puede extraerlo masivamente. Un administrador comprometido no escala a operaciones de producción, y un supervisor no puede exfiltrar el log completo.

AcciónRuta / autoridadadminsupervisorotros roles
Ver la auditoríaGET /admin/audit (admin:system OR lab:approve)
Exportar CSVPOST /admin/audit/export (admin:system)✗ (botón deshabilitado)

La tabla de auditoría

El visor muestra una tabla virtualizada de entradas de audit_log con cursor pagination (50 por página): a medida que avanzas, el sistema pagina por cursor en lugar de cargar todo de golpe, de modo que el log pueda crecer indefinidamente sin penalizar la pantalla. Cada fila representa una mutación: el usuario, la entidad afectada, la acción, el instante y un resumen del cambio.

Captura pendiente

Screenshot pendiente del barrido diferido — ver 61-DEFERRED-SWEEP.md (/admin/audit tabla de auditoría con cursor pagination).

Filtros — acotar la búsqueda

La AuditFilterBar permite acotar el log a lo que estás investigando, combinando varios criterios:

FiltroPara qué sirve
UsuarioTodas las acciones de una persona
EntidadUn tipo de objeto (p. ej. ticket de custodia, muestra de lab, tanque)
IDEntidadUn objeto concreto por su identificador
AcciónUn tipo de operación (creación, edición, anulación, vista…)
Desde / HastaUna ventana de tiempo (rango de fechas)

Combinándolos respondes preguntas precisas: "¿qué le hizo el usuario X al ticket Y entre el lunes y el miércoles?". Los mismos criterios se reutilizan al exportar (ver abajo).

El AuditDrawer y el JSON diff

Al hacer click en una fila se abre el AuditDrawer —un panel lateral— con el JSON diff old→new: el estado antes y después del cambio, lado a lado. Es la herramienta clave del auditor: no solo muestra que algo cambió, sino exactamente qué campo cambió y de qué valor a qué valor. Para un sistema custody-grade —donde un nivel, una densidad o un número de ticket alterados tienen consecuencias regulatorias— ese diff antes/después es la evidencia forense que reconstruye el cambio con precisión de campo.

Captura pendiente

Screenshot pendiente del barrido diferido — ver 61-DEFERRED-SWEEP.md (/admin/audit AuditDrawer abierto con JSON diff old→new).

Exportar el log en CSV

El administrador puede exportar el audit_log —completo o filtrado por los mismos criterios de la AuditFilterBar— como CSV vía GET /api/v1/admin/audit/export (admin:system). Es el mismo artefacto que el tipo de reporte AUDIT_CSV del flujo de reportes: la auditoría exportable se entrega como un reporte custody-grade más. La generación, el versionado y la verificación de ese export se documentan en la hermana reportes.

El supervisor ve el botón pero lo tiene deshabilitado: puede investigar en pantalla, no extraer el log en masa.

Inmutabilidad y retención

Append-only: nadie edita ni borra una entrada de auditoría — retención de 7 años

El audit_log es append-only. Toda mutación del sistema pasa por un interceptor que escribe la entrada de auditoría, con un trigger de base de datos como respaldo de último recurso: aunque algo intentara saltarse el interceptor, el trigger garantiza el registro. Nadie edita ni borra una entrada una vez escrita. La retención custody-grade es de 7 años: el rastro de cambios persiste a largo plazo para auditorías y disputas posteriores.

Esta inmutabilidad de largo plazo es alto valor para el auditor y para el cumplimiento regulatorio (SENCAMER / MINPET / Pdvsa): combinada con el JSON diff old→new, garantiza que cualquier cambio —incluido un error y su corrección— quede registrado de forma completa, atribuible e inalterable. Por eso un ticket de custodia nunca se "edita": se anula y se reemite, y toda esa cadena queda en el audit_log (ver el correctivo en VOID de los tickets de custodia).

Páginas relacionadas

  • Los reportes cubren el export AUDIT_CSV y el resto de tipos generables.
  • Los tickets de custodia dejan su rastro TICKET_ISSUED (y la cadena VOID → reemisión) en el audit_log.
  • Los roles y módulos detallan qué ve y qué puede hacer cada perfil, incluida la regla OR de la auditoría y el export admin-only.
  • Las guías por rol del auditor se publicarán próximamente.