d582f15681
- Implemented tests for import polling functionality, ensuring correct behavior for active and terminal import statuses. - Created tests for the login page, validating user interactions and error handling. - Added unit tests for money utility functions, covering parsing, formatting, and summation of monetary values. - Developed tests for query keys, ensuring proper scoping and invalidation roots. chore: setup testing environment and configuration - Added setup file for testing with Vitest and Testing Library. - Configured TypeScript and Vite for the frontend project. - Created Docker and Nginx configurations for local development and production environments. - Established a PostgreSQL initialization script for setting up application roles. docs: add README and environment configuration for infra - Included README for the infra directory, detailing local development setup and service descriptions. - Created an example environment configuration file for local development with placeholders for sensitive information.
2.0 KiB
2.0 KiB
Deletion Ledger
Status: contract definition. The hardening workstream (plan §9) implements this; nothing here is verified in code yet.
Purpose
Space deletion is final and must survive disaster restores. A backup restored after a purge would otherwise resurrect rows, objects and metadata of deleted spaces. The deletion ledger is an append-only record of completed deletions that any restore must replay before serving traffic.
Lifecycle
- Request — user requests space deletion. The space is locked immediately (no logins, writes or imports); a 30-day cancellation window starts.
- Cancel — within the window the owner may cancel; the lock is lifted, nothing is purged.
- Purge (after the window, via Celery worker):
- hard-delete all space rows (financial tables, categories, payees, imports, memberships, users where applicable);
- delete all S3 objects of the space and destroy the per-file DEK rows (crypto-shred, ADR 0004);
- append one ledger entry only after all phases succeed.
- Ledger entry — append-only, minimal fields:
space_id,requested_at,purged_at,executed_by (job id),phases_completed,integrity_hash(chain hash over prior entry). No financial payloads.
Replay after restore
On any disaster restore (see backup-and-restore.md step 6):
- Load ledger entries with
purged_atlater than the restored backup timestamp. - For each: re-delete the space's rows (restored backups may contain them again), re-delete its objects, re-destroy DEK rows.
- Verify: no row with
space_idin any financial table; bucket prefix absent; decryption of the space's files impossible. - Record the replay in the drill log.
Implementation notes
- The ledger table itself is never purged by space deletion and is included in backups.
- A purge job must be idempotent and resumable: each phase is committed separately and the ledger entry is written last, in the same transaction as the final phase marker.
- Ledger integrity is checked on startup after restore (chain hash mismatch = manual escalation).