feat: financial data retention & aggregation system

Add CleanupExpiredFinancialRecords to enforce HMRC + Limitation Act
compliance (7-year retention, 1-year post-anonymization buffer).

- financial_aggregates table: monthly totals by payment method/type (no PII)
- CleanupExpiredFinancialRecords(): aggregates expired payments/refunds,
  deletes granular records, idempotent via ON CONFLICT DO UPDATE
- Wired into GET /api/availability alongside existing cleanup functions
- 8 tests: 7yr expiry, 1yr buffer, 9yr override, aggregation totals,
  idempotency, active user protection, both-thresholds elapsed, refunds
- testdb.go: financial_aggregates in drop-order and truncate lists
- README + Technical Manual updated
This commit is contained in:
2026-06-05 16:37:04 +01:00
parent 06efdfdac0
commit f4a6033715
8 changed files with 820 additions and 5 deletions
+2 -1
View File
@@ -56,6 +56,7 @@ Nail salon booking platform — Go 1.25 backend + SvelteKit 5 frontend + Docker.
- **Profile picture upload limit**: 15MB client-side check before crop dialog in account page
- **Portfolio image upload backend limit**: separate `portfolioBodyLimit` (20MB) applied to `/images` route, distinct from `uploadBodyLimit` (15MB) for profile pictures
- **GDPR compliance system**: Full Article 15 Subject Access Request via `/gdpr` — async Go endpoint (`GET /api/user/gdpr-export`) with 12h in-memory cache and background generation, 16-section SQL export (`export_all_user_data()`) covering profile, bookings (with override pricing), payments, refunds, saved cards, social logins, loyalty redemptions, booking discounts, edit requests, affiliate payouts, verification codes, forgiven no-shows, patch tests, referrals, notification preferences. Frontend: skeleton loading, 2s polling, styled report cards/tables, PDF export (print CSS hides navbar + verification banner), raw JSON download. Conditional rendering for empty sections, VAT breakdowns (hidden until non-zero), deposits required (hidden when 0). Account deletion (`DELETE /api/user/account`) extended with external system scrubbing — S3 profile picture deletion, Square saved card deletion — before SQL-level anonymization. `anonymize_user()` SQL function extended with child table PII scrubbing (social logins, saved cards soft-delete with PCI clearance, verification code expiry, time blocker reservation scrubbing, edit request notes nulling, notification preference deletion). `AnonymizeStaleGuestAccounts()` extended with additional field scrubbing (profile_pic_url, referral_code, notes, data_retention_consent). 25 tests covering all backend additions.
- **Financial data retention & aggregation**: Granular payment/refund records retained for `MAX(created_at + 7 years, user_anonymized_at + 1 year)` (HMRC + Limitation Act compliance). Expired records are aggregated into `financial_aggregates` (monthly totals by payment method/type, no PII) and deleted. Triggered lazily on `GET /api/availability` alongside existing cleanup functions. Idempotent — safe to run repeatedly. 8 tests covering retention edge cases, aggregation correctness, refund handling, and idempotency.
## Project Structure
@@ -131,7 +132,7 @@ cd backend && go build -o bin/backend ./main.go
# Frontend
cd frontend && npm ci && npm run build
# Tests (576/579 passing, 3 skipped)
# Tests (584/587 passing, 3 skipped)
cd backend && go test -tags "test,dev" ./...
```