Audit log & the event bus
Ticketra is a modular monolith. Three mechanisms keep its modules coordinated and accountable: an in-process event bus, an append-only audit log, and Server-Sent Events for the browser.
In-process event bus
Domain modules (cases, observables, auth, audit, integrations, …) don't call each other over HTTP. They publish and subscribe to typed events on an in-process module bus.
When something significant happens, the originating module emits an event; interested modules react. This keeps cross-module coupling explicit and testable, and avoids the latency and failure modes of internal network calls.
Append-only audit log
Every significant operation records an audit event: who did it, what they did, to what, the outcome, and contextual metadata (IP, request id).
- The audit log is append-only — entries are never updated or deleted by application code.
- Audit failures are logged, never silently swallowed — a failure to record is itself surfaced.
- Retention is configurable per your policy.
This gives you a defensible record for incident review and compliance. The log is queryable from the Audit Log page (requires the audit:read permission).
Real-time delivery (SSE)
Browser clients receive live updates over Server-Sent Events, not WebSockets. The SSE manager bridges module-bus events to connected clients.
Key properties:
- Authenticated by the same httpOnly cookie as REST — no token in the URL.
- Tenant-isolated — broadcasts are filtered by tenant before delivery.
- Minimal payloads — events carry only IDs; the client refetches over REST with full permission checks. No sensitive data travels in the event itself.
- Bounded — per-user and global connection caps, an 8-hour session TTL, and immediate disconnect when an admin revokes a session.
This is what powers live case updates and the presence indicators that show who else is viewing a case.
Why it's built this way
For a self-hosted product that has to run anywhere — from a single analyst's box to a large SOC — an in-process bus plus SSE gives real-time collaboration and a complete audit trail without the operational weight of message brokers or a WebSocket tier, consistent with the modular-monolith philosophy.