Audit Logs

Trust comes from accountability. Every state-changing action in ABc — a price override, a refund, a role change, a payout-bank edit — gets an immutable audit entry. Finance and owners can replay history when something looks off.

What gets logged

Bookings

Create, edit, status change, manual price override, room reassignment, cancellation, no-show marking.

Payments

Capture, refund initiation, refund completion, failed retries, chargeback events.

Property & rooms

Rate edits, blackout changes, room enable/disable, photo upload/delete.

Team

Invite, accept, role change, scope change, removal, login from new device.

Sensitive identity

Payout bank change, 2FA enable/disable, email/phone change, KYC re-submission.

Channel ops

OTA connect/disconnect, credential rotation, sync failures.

Audit entry — fields

audit_log
  • idulid (sortable)
  • occurred_attimestamptz
  • actor_iduuid → users
  • actor_roleenum (snapshot)
  • actiontext (dot-notation)
  • entity_typetext
  • entity_iduuid
  • property_id→ properties
  • beforejsonb
  • afterjsonb
  • diffjsonb (computed)
  • reasontext · nullable
  • ipinet
  • user_agenttext
  • request_idtext (trace)

Sample entries

audit_log · examples
{ "action": "booking.price_override",
  "actor": "Sneha (manager)",
  "entity": "bk_ABC-24806",
  "before": { "total": 28728 },
  "after":  { "total": 25200 },
  "diff":   { "total": { "−": 3528 } },
  "reason": "Returning guest discount, owner approved over phone" }

{ "action": "payment.refund.initiated",
  "actor": "Ravi (finance)",
  "entity": "pay_xMv…",
  "after": { "refund_amount": 22230, "method": "razorpay" },
  "reason": "Guest cancellation, flexible policy, >24h before check-in" }

{ "action": "team.role_changed",
  "actor": "Rohan (owner)",
  "entity": "usr_anjali",
  "before": { "role": "front_desk" },
  "after":  { "role": "manager" } }

{ "action": "payout_bank.changed",
  "actor": "Rohan (owner)",
  "entity": "usr_rohan",
  "before": { "account_last4": "8821" },
  "after":  { "account_last4": "4412" },
  "reason": "Changed primary banking partner" }

Audit log UI

app.abc.com/audit
Audit log
TimeActorActionEntityReason
25 May 17:21 Sneha · manager booking.price_override ABC-24806 Returning guest disc.
25 May 15:08 Ravi · finance payment.refund.initiated pay_xMv9P Guest cancel · flexible
25 May 12:44 Rohan · owner team.role_changed Anjali Patel Promotion
24 May 22:01 Rohan · owner payout_bank.changed self Changed bank
24 May 19:30 system booking.auto_cancelled ABC-24769 Balance default · T+2d
24 May 18:12 Sneha · manager rate.edit Deluxe King · Dec 24–28 Season rate ₹6,500

Storage & immutability

  • Audit table is append-only — no UPDATE or DELETE permission for the application user.
  • The Postgres role used by background reconciliation is read-only.
  • A row, once written, can only be deleted by a DBA, and that DBA action is itself logged outside Postgres.
  • Each row carries the request_id from our tracing system so we can correlate logs across services.
  • Daily snapshots are exported to an immutable S3 bucket (Object Lock) — useful if Postgres is ever compromised.

Privacy & redaction

Audit logs can contain sensitive fields (old PAN last-4, bank last-4). We hash these in before/after snapshots so the audit log doesn't become a leak source. The full value lives only in the live record.

Retention

Audit entries are retained for at least 7 years — exceeding the typical Indian tax/audit window. Older entries are archived to cold storage with the same immutability guarantees.

Searching and exporting

  • Filter by actor, action, entity, property, date range.
  • One-click "show all activity by this user in the last 7 days".
  • One-click "show all changes to this booking".
  • Export filtered view as CSV / JSON — handy for legal or audit requests.