Files
jobtrackingapp/docs/verification/sec-009-account-lifecycle.md
T
cesnimda 1ec9dd037e
CI and Deploy / test (pull_request) Successful in 5m13s
CI and Deploy / deploy (pull_request) Has been skipped
feat(export): add readable account archive
2026-08-15 18:36:40 +02:00

4.5 KiB

SEC-009 account export and deletion lifecycle

Updated: 2026-08-15

Status: IN PROGRESS. Generated-output ownership and the readable export are implemented. The disabled deletion lifecycle remains to be implemented.

Owner inventory boundary

The authoritative inventory must include Identity-safe account/profile fields and roles; companies, opportunities, applications and all workspace children; correspondence/events/attachments; Career Profile and versions/children; CV variants/versions/artifacts/extraction runs; AI notes/interactions/operations/notifications; email drafts/send metadata; provider connection metadata; rules; sessions/trusted-device metadata; and owned files. It must exclude password/security hashes, TOTP/recovery/token hashes, OAuth tokens, IMAP passwords, data-protection keys and global settings.

Checkpoint 1 — owner-scoped generated files

  • AppPaths.GetOwnerStorageKey provides one opaque SHA-256 owner directory key.
  • CV PDF exports now write under CvExports/<owner-key>/<yyyyMMdd>/<uuid>.pdf. The friendly renderer filename remains the download name, while the stored UUID prevents collisions and unsafe path influence.
  • Daily exports now write under exports/<owner-key>/daily_export_<yyyyMMdd>.json with the existing atomic temporary-file move.
  • The PDF exporter receives the authenticated/public-variant owner explicitly from every controller, including anonymous public download after slug ownership resolution.
  • Retention prunes both legacy top-level date directories and new owner/date directories. Unknown folders remain untouched.

No existing generated file is moved or guessed. Legacy shared-date outputs stay a separately reviewed rollout concern because they cannot be attributed safely.

Checkpoint 2 — complete readable export

  • Authenticated POST /api/export/account requires the current local session to have been created within the last 15 minutes and is limited to two requests per user per hour.
  • One service owns both the authoritative row inventory and file inventory. It queries with explicit owner predicates and IgnoreQueryFilters, so soft-deleted applications remain portable and an absent/requestless tenant scope cannot silently empty the export.
  • The ZIP contains readable account, company, opportunity, application, correspondence, event, attachment, Career, CV, workspace, AI operation, notification, settings/provider and security-metadata JSON categories.
  • Owned attachment, CV upload, avatar, generated-CV and daily-export bytes are included only after managed-root/reparse-point checks. Missing or unsafe files produce manifest warnings rather than cross-root reads.
  • manifest.json records schema version, generated time, category/item counts, byte sizes and SHA-256 checksums for every included entry. README.txt explains formats, exclusions and retention limits.
  • Password/security/concurrency hashes, TOTP secrets, recovery/trusted-device hashes, session IDs, provider access/refresh tokens, IMAP passwords, operation leases, email payload hashes, global settings and data-protection keys are never serialized.
  • The Settings Backup tab presents the readable export separately from the application-key-encrypted operational backup and explains recent sign-in without weakening the API rule.
  • Temporary ZIPs live under an opaque owner root and are opened with delete-on-close when returned by the controller.

Verification

  • Owner-storage focused CV/export/controller/background tests: 77/77.
  • Readable-export focused backend/API tests: 11/11, including real SQLite, two-owner isolation, file inclusion, every checksum and secret-redaction sentinels.
  • Full backend: 650/650.
  • Frontend export/Settings tests: 4/4; full frontend 58 suites/234 tests.
  • Backend build: pass, zero warnings/errors.
  • Optimized frontend build/TypeScript: pass.
  • Chromium: fresh Free account receives a real ZIP response with a PK signature and readable-export success state.
  • git diff --check: pass aside from line-ending notices.

Remaining repository work

  1. Reuse the completed owner inventory in the deletion coordinator.
  2. Add the additive deletion state/request/file schema and disabled coordinator.
  3. Add pending-account authentication/mutation gates, session/queue cancellation, provider cleanup and idempotent file quarantine/database purge.
  4. Add separate tombstone storage/replay and settings/admin UX while keeping production activation disabled.

Production retention, legal hold and restored-backup decisions remain recorded in BLOCKERS.md.