packages/features/booking-audit/README.md
The Booking Audit System tracks all actions and changes related to bookings in Cal.com. The architecture is built around two core tables (AuditActor and BookingAudit) that work together to maintain a complete, immutable audit trail.
AuditActor Table:
User (via userUuid) and Attendee (via attendeeId) without foreign key constraintsBookingAudit Table:
bookingUid stored as plain string (no foreign key) to preserve audit trail after booking deletiononDelete: Restrict prevents actor deletion if audit records existtimestamp field represents business event time (may differ from createdAt if processed asynchronously)operationId required field for correlating audit logs from a single user action across different audit types (BookingAudit, UserAudit, etc.)data field stores action-specific contextual databookingUid, actorId, timestamp, and operationIdProtecting the Audit Trail:
AuditActor records with associated BookingAudit recordsUser is deleted, their AuditActor record persists with userUuid set to nullThe booking audit system uses two complementary fields:
source identifies how the action was initiated:
actor identifies who or what performed the action:
This separation enables clear compliance trails, easier debugging, better analytics, and security by distinguishing user-initiated vs automated actions.
The system tracks various booking actions including:
Most audit actions track changes using a consistent structure:
{ old: T | null, new: T }old: Previous value (null if field didn't exist before)new: New value after the changeException: The CREATED action captures initial booking state at creation using a flat object with initial values.
The audit system uses per-action versioning. Each action maintains its own schema version independently.
Benefits:
Storage Structure:
Version stored separately from audit data: { version, data: {} }
AuditActor (1) ──────< (many) BookingAudit
↑
│ (soft reference, no FK)
├──────────── User (via userUuid)
│ (soft reference, no FK)
└──────────── Attendee (via attendeeId)
Relationship Details:
onDelete: RestrictAuditActor Table:
email, userUuid, attendeeId for fast lookupspseudonymizedAt for compliance cleanup jobsBookingAudit Table:
bookingUid (primary query pattern)actorId (secondary query pattern)timestamp (time-based sorting and filtering)operationId (correlating multi-booking operations)SYSTEM Actor:
Audit records are append-only. Once created, they are never modified or deleted. This ensures complete historical accuracy and a tamper-proof audit trail.
Actor information is preserved even after source records are deleted. AuditActor records persist with anonymized identity fields. The audit trail remains complete and queryable even after user/attendee deletion.
The JSON data field provides schema flexibility for action-specific context without database schema changes. Backward compatible with versioning.
Every action is fully traceable with who (actor), what (action), when (timestamp), and contextual data.
Database constraints ensure data quality through foreign keys, onDelete: Restrict protection, unique constraints, and strategic indexes.
The audit system records actual state, not expected state. It captures what actually happened without enforcing business rules:
Benefits:
GDPR & HIPAA Compliance:
userUuid, email, phone, name set to nullZero PII in Queue: The audit system works with third-party queue providers without exposing PII:
userUuid is queuedattendeeId is queuedactorId is queuedBenefits:
BookingEventHandlerService is the primary entry point for tracking booking changes. It:
Queue Payload Structure:
bookingUid: String identifier for the bookingactor: ID-only actor object (userUuid, attendeeId, or actorId)organizationId: Number (for feature flag checks)action: Enum value (e.g., "CREATED", "CANCELLED")operationId: Required string for correlating related audit logsdata: Action-specific datatimestamp: Number (milliseconds since epoch)source: Action source (API_V1, API_V2, WEBAPP, WEBHOOK, SYSTEM, UNKNOWN)BookingAuditTaskConsumer processes audit records:
The operationId field correlates audit logs that result from a single user action affecting multiple bookings or across different audit types (BookingAudit, UserAudit, etc.).
Benefits:
The Booking Audit System provides a robust, scalable architecture for tracking all booking-related actions:
This architecture supports compliance requirements, debugging, analytics, and provides transparency for users and administrators.