Skip to content

The mobile deletion endpoint already physically deletes the owner, relies on foreign-key cascades for holdings, mutation history, sessions, password hashes and other account-owned rows, and unlinks the private avatar after commit. It now also deletes hashed-address password-login attempts, which do not have an owner foreign key. The attempt row is locked before the owner, matching the password-login and legacy deletion paths. No migration is needed.

A disposable PostgreSQL 16 integration test uses the real email request/verify routes after deletion, with an in-memory mailbox. Reusing the same address creates a different user ID, empty collection/history and no old name, avatar or password. Old root/access/refresh credentials fail. Retrying the old deletion receipt does not erase the fresh identity. An unrelated owner's holding survives.

Validation: API 1,342 passed / 9 skipped; optional embedded SQL deletion suite 17 passed; PostgreSQL 16 collection/erasure suite 39 passed; ingest 554 passed; API check-JS passed. The missing password-attempt cleanup had an observed Red before the fix. Full Docker E2E was not run because the local Linux Docker daemon is unavailable. No real account, provider email, VPS operation or deployment.

This is not a global GDPR compliance certification. Seven-day deletion retry receipts contain credential/operation hashes and temporarily a cleanup filename, not an email or collection. They are not an identity-restoration registry. Backups, external provider logs, other devices' offline copies and OS caches require their own retention controls and were not purged or certified here.

Backend PR: https://github.com/snag-tcg/tcg-collector-backend/pull/528

Mobile companion: https://github.com/snag-tcg/poc-tcg-collector/pull/792