Privacy / GDPR Runbook
Last reviewed: 2026-04-21
Maintained by: Engineering
This document describes the current engineering behavior of privacy-related flows in Zgrid. It is not legal advice.
User-Facing Surfaces
Zgrid Appexposes:- privacy notice
- account data export
- account deletion request submission
Back Officeexposes:- deletion request queue
- deletion request detail
- request rejection
- request completion/anonymization
Account Data Export
Tenant export is available through GET /account/privacy/export.
The current export payload includes:
- account user record
- organization context
- memberships
- mobile preferences
- issues reported by the tenant
- issue comments visible to that tenant
- resident announcements visible to that tenant
- resident documents visible to that tenant
- resident invoices/payments visible to that tenant
- notifications
- latest deletion request state
The export intentionally does not include:
- token hashes
- hidden admin-only data
- cross-tenant records
- raw audit/security internals beyond what is already visible to the authenticated tenant
Account Deletion Processing
Tenant deletion is not self-serve immediate deletion. The current workflow is:
- Tenant submits a deletion request in
Zgrid App Back Officereviews the request- Admin either rejects the request or completes anonymization
When a request is completed, the API currently:
- revokes refresh tokens
- deactivates device tokens
- deletes user preferences
- deactivates resident payment methods
- revokes active email verification tokens
- revokes active password reset tokens
- deactivates active unit memberships
- anonymizes direct user identifiers
- records processing metadata on the deletion request
- records an admin audit log entry
Current anonymization behavior:
users.emailbecomes a tombstone addressusers.first_nameandusers.last_namebecomeDeleted Userusers.phoneandusers.avatar_urlare clearedusers.is_activebecomesfalseusers.deleted_atis set
Historical Data Behavior
Some operational/legal history remains after anonymization. Current expected behavior:
- invoices and payments remain for continuity, but user-facing joins should resolve to the anonymized user row
- issue comments and issue history remain, but author joins should resolve to the anonymized user row
- notifications remain unless a future retention rule explicitly removes them
- security/session records are either revoked immediately or handled through retention cleanup
This means deletion currently behaves as anonymization plus access revocation, not physical erasure of all historical rows.
Retention Rules
Current technical retention windows:
- refresh token records: 30 days after expiry or revocation
- email verification and password reset tokens: 30 days after expiry or revocation
- audit log IP address and user-agent metadata: 180 days, then redacted
Manual cleanup command:
pnpm run cleanup:privacy-metadata
This command:
- deletes old refresh token records
- deletes old email verification tokens
- deletes old password reset tokens
- redacts
ip_addressanduser_agentin old audit logs
Manual Verification Checklist
Before release, verify:
- tenant can export only their own visible data
- non-tenant roles cannot use tenant export
- duplicate deletion request stays idempotent for active requests
- reject changes request status without anonymizing the tenant
- complete revokes access and anonymizes identifiers
- deleted tenant cannot authenticate again
- logout clears local mobile cached data before another user signs in
- privacy notice is reachable in both supported app languages
Remaining Gaps
Still outside the current implementation:
- legal review of notice copy and lawful-basis wording
- processor/DPA documentation
- RoPA and breach response documentation
- automated scheduling for privacy cleanup jobs if production infra requires non-manual execution