AstroBaaS

Customers & accounts

Admin Activity Log

Free — GPL coresize Mplanned, not built

Generated from docs/plan/core/admin-activity-log/PLAN.md in the AstroBaaS repository. Nothing described below is implemented — it is the written plan for it.

Admin Activity Log records every change made by staff — product edits, order status changes, staff permission changes, settings updates — with timestamp, user, and old/new values.

The problem

Merchants don’t know who changed product prices or deleted orders; a disgruntled employee causes chaos without accountability.

What it does

  • Log every POST/PATCH/DELETE on admin endpoints (automatic via middleware)
  • Record user_id, action, entity_type, entity_id, timestamp, old values (JSON), new values (JSON)
  • Filter audit log by: date range, user, entity type, action type
  • Export audit log to CSV for compliance
  • Search audit log by entity ID
  • Retention policy: keep logs 12 months (configurable), archive older
  • Tamper-proof: append-only design, no edits/deletes
  • Permission: only Admins can view logs

What it deliberately does NOT do

Each boundary carries its reason. A boundary without a reason gets crossed by the next person who reads this.

  • Diff visualization — stored as JSON; merchants diff themselves
  • Webhook for audit events (belongs in webhook-system) — log viewer only
  • Real-time dashboard (see changes as they happen) — historical query only
  • Undo/rollback — dangerous; needs explicit approval flow
  • Archival storage (move old logs to S3) — local retention only

Data model

AuditLog: id, store_id, user_id (nullable), action, entity_type, entity_id, old_values (JSON), new_values (JSON), timestamp, ip_address. Migration: add audit_logs table with indexes on store_id, timestamp, user_id, entity_type.

API

  • GET /admin/audit-log
  • GET /admin/audit-log/{id}
  • GET /admin/audit-log/entity/{entity_type}/{entity_id}
  • POST /admin/audit-log/export
  • DELETE /admin/audit-log (retention policy)

Every route added here must also appear in src/pages/openapi.json.ts — a test fails the build if it does not.

Admin

Audit log viewer: table with timestamp, user, action, entity type, entity ID; click row for details (old/new JSON). Filters: date, user, action, entity type. Search: by entity ID. Export: CSV button. Compliance report: show changes to sensitive fields.

The seam — why this is core

Core owns: audit log table, append-only enforcement, query interface, retention policy. Paid module owns: nothing; core infrastructure.

Core owns the interface + honest audit logger; change tracking is infrastructure, not a per-country obligation or credential.

Dependencies

  • admin-user-management

Acceptance checks

Each of these must be able to fail. Before claiming this is done, break the code deliberately and watch each one go red.

  • Price change 50 to 60 EUR logged with old_values.price=50, new_values.price=60
  • Querying deleted user (id=5); audit log shows 10 entries with user_id=5, displays [deleted user]
  • Running DELETE on logs before 2024-01-01 purges old entries and logs deletion itself
  • Attempting PATCH on audit log returns 405 (immutable)
  • Exporting 100k entries takes < 30 seconds (streamed)
  • Timestamp is UTC or store timezone (consistent)

Risks

Audit log unbounded; 1M+ entries slow queries without indexes. Old values not captured. Retention delete runs on every request causes performance spikes. User ID foreign key fails if cascade delete on users. Sensitive data in logs.

Commercial context

Suggested pricefree (core)
Rival anchorShopify: included; Magento: included

The anchor is what the nearest equivalent charges on Shopify or Magento today. It is context for a pricing decision, not the decision.


Generated from the commerce plan. See docs/COMMERCE-PLAN.md for the full catalogue and ../../AI-GUIDE.md for how to work on this repository.