Application-level audit logging with 30-day default retention. Captures
insert/update/delete on all domain tables with field-level diffs, user
attribution, and request ID correlation. Sensitive fields masked.
Configurable retention, BullMQ cleanup job, admin UI for querying.
Granular permission system: domain.action pattern (accounts.view, pos.edit,
repairs.admin). Custom roles composed of permissions. Default system roles
(Admin, Manager, Sales Associate, Technician, Instructor, Viewer). Migration
plan from current role enum. API and frontend guard patterns.
- Doc 02: Add member_identifier table, member_number, primary_member_id,
account_number auto-generation, isMinor override, tax_exemption as
separate table, member move, updated business rules
- Doc 03: Document lookup table pattern replacing pgEnums for status and
condition, add system/custom value distinction
- Doc 22: Mark all Phase 2 items as complete, add new tables to additions
section, update audit findings, note admin frontend exists
Security fixes:
- Register route validates company exists before creating user
- Rate limiting on auth routes (10 per 15min per IP)
- Dev auth plugin guards against production use
- Main.ts throws if JWT_SECRET missing in production
Added Phase 2 audit doc (22) covering:
- Built vs planning doc comparison
- Security review with fixes applied
- Duplicate code patterns identified
- Standard POS feature gap analysis
- Music-specific feature gaps
33 tests passing.
Commission is default for most products. Simple model: employee
rate × sale price. Override table for exceptions (consignment at 0%,
category-level adjustments). Commission snapshotted at time of sale.
Covers consignment lifecycle, settlement workflow, POS integration,
accounting journal entries (commission income vs consignment payable),
reporting, and business rules. Consignment items use account entity
for consignors (not suppliers).
Replace stripe_customer_id on account with account_processor_link
table. Update account_payment_method to use processor enum +
processor_payment_method_id instead of Stripe-specific fields.
Supports multiple simultaneous processors for migration scenarios.