Zippi maintains three distinct observability planes — audit trail (immutable record of what changed and who changed it), operational log (what happened during the operation), and technical logs (why something failed). This page covers the audit trail and structured logging configuration. Never mix these planes: audit events are stored in the database and must not rotate; technical logs are ephemeral and should not be used for compliance.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/CRISTIANCAMACH34/Zippi/llms.txt
Use this file to discover all available pages before exploring further.
What Is Audited
The following action categories are always recorded with full context:| Category | Examples |
|---|---|
| Authentication events | Admin login, logout, failed login, session revocation |
| Admin user management | Create admin, update role, change scope, deactivate account |
| Order state transitions | Every FSM step with before state, after state, and reason |
| Price and cost changes | Before/after values for product price, cost, taxes |
| Cashier operations | Register open, register close, shift change |
| Scope resolutions | scope_filters applied, scope normalization |
| RBAC changes | Role assignment, permission grant/revoke |
Audit Record Shape
EachEventoAdministrador row captures:
actor_tipo—"admin","system", or"environment"(never a raw email)tipo_evento— machine-readable action key (e.g.admin.login,order.state_changed)descripcion— human-readable summary, safe for displaypayload_json— structured JSON withbefore,after, andreasonwhere applicablefecha_evento— UTC timestamp, indexed for range queries
append_admin_event function is used inside an existing session (atomic), while record_admin_event opens its own session for fire-and-forget recording:
Accessing Audit Events
Access to audit endpoints requires elevated permissions. These are not available to operational roles such as
cashier or delivery_driver.page, page_size, tipo_evento, id_admin_actor, date_from, date_to.
Export as CSV
PII Policy in Logs
Audit records store actor id and role, not email addresses. Access logs similarly omit raw email. This is enforced at the application level:actor_email is stored only in EventoAdministrador for admin-management events where the email is the identity being managed, and it is never written to rotating technical logs.
Rules:
- Never log passwords, tokens, JWTs, or secrets — not even partially.
- Phone numbers and full addresses are not written to technical logs; only resource IDs are used.
- For before/after diffs of sensitive fields (prices, costs), the values are retained in
payload_jsonwithin the audit table (which is protected byaudit.readpermission) but are never emitted to the log stream.
Structured Logging Configuration
Zippi uses Python’s standardlogging module, configured via app/config/logging.py. The log format (plain text vs JSON) is controlled by the application’s logging initializer; the two variables that affect output behaviour from .env are:
JsonFormatter class attaches request_id and trace_id fields automatically when they are present on the log record. These are set by the request middleware and propagated through the call stack.
Log Levels
| Level | When to use |
|---|---|
DEBUG | Development detail; disabled in production by default |
INFO | Operational milestones: order accepted, session started, payment confirmed |
WARNING | Recoverable anomaly: retry triggered, unexpected input normalized |
ERROR | Unhandled exception requiring attention |
CRITICAL | Data integrity risk or service-wide failure |
Retention and Compliance
- Audit events (
eventos_administrador) are permanent. They are never truncated, rotated, or deleted. Corrections are appended as new events — existing records are immutable. - Technical logs (file or stdout) rotate according to your log management setup (logrotate, CloudWatch, Datadog, etc.) and are not the source of truth for compliance purposes.
- For regulated deployments, export audit events periodically via
GET /api/v1/auth/audit-events/exportand store the CSV in immutable object storage (e.g. S3 with Object Lock).