Tax & compliance
Right to Be Forgotten
Generated from docs/plan/core/right-to-be-forgotten/PLAN.md in the AstroBaaS repository. Nothing described below is implemented — it is the written plan for it.
A core feature allowing customers to request complete deletion of their personal data (GDPR right-to-erasure/right-to-be-forgotten), and giving merchants tools to comply within 30 days. Shop proves deletion is complete to regulators via immutable audit logs.
The problem
A Danish customer requests: ‘Delete all my data.’ A Danish merchant has no deletion workflow. She manually deletes from multiple systems (customer profile, order records, email lists, etc.), but isn’t sure if she got everything. She has no proof of deletion date. GDPR requires deletion within 30 days; she’s nervous she’ll miss the deadline or incomplete deletion will become a fine.
What it does
- Deletion request workflow: customer can self-serve request deletion, or staff creates on their behalf
- Scope specification: merchant specifies what to delete (profile only, or profile + orders?)
- Cascading deletion: when customer is deleted, associated data is deleted or anonymized (orders, emails, wishlist, reviews)
- Anonymization option: instead of deleting orders (needed for tax/financial), anonymize customer name/email
- Retention exceptions: data retained for legal reasons (tax records, fraud prevention) are flagged in deletion request
- Deletion log: immutable record of what was deleted, when, by whom (tamper-proof for audit)
- Email notification: confirmation email sent to customer (proof deletion was processed)
- Admin UI: staff can see pending deletions, approve/execute, view deletion log
- Compliance proof: exportable deletion certificate (for regulators) showing request date, completion date, data deleted
What it deliberately does NOT do
Each boundary carries its reason. A boundary without a reason gets crossed by the next person who reads this.
- Deletion from third-party integrations (GA4, Stripe, email provider)—customer must request from them separately
- Selective deletion (delete only reviews, keep orders)—not supported; all-or-nothing or anonymize
- Backup retention (deleted data may exist in old backups for months)—must disclose this risk
- Undelete/recovery (deletion is permanent)—no recovery option
- Obfuscation vs true deletion (we don’t offer ‘soft delete’ mode)
Data model
Extend Customer: deleted_at (nullable timestamp, null = active). New: DeletionRequest(id, customerId, request_date, completion_date, deleted_records_json, deletion_method, executed_by). Both require careful schema design (deletion is permanent).
API
- POST /customers/:id/deletion-request — customer initiates deletion request
- GET /deletion-requests/:id — return request status and deleted data summary
- POST /deletion-requests/:id/execute — execute deletion (staff only)
- POST /deletion-requests/:id/cancel — cancel request before execution
- GET /deletion-requests/:id/certificate — export deletion certificate (PDF) for regulators
- GET /deletion-requests — list all deletion requests (staff only)
Every route added here must also appear in src/pages/openapi.json.ts — a test
fails the build if it does not.
Admin
Right-to-be-forgotten dashboard: list of pending deletion requests, request date, customer name, status, ‘Execute Deletion’ button (with confirmation), deletion log (all past deletions), deletion certificate generator
The seam — why this is core
Core owns: deletion request workflow, cascading deletion logic, audit trail, deletion certificate. Paid pack owns: third-party integration deletion helpers (GA4 connector, email provider connector, etc.), compliance guidance, legal documentation.
Core owns the interface + honest deletion tool; data privacy is infrastructure, not a per-country obligation or credential.
Dependencies
- customer schema (deleted_at field)
- audit log infrastructure (deletion must be immutable and audit-logged)
- order system (order anonymization logic)
Acceptance checks
Each of these must be able to fail. Before claiming this is done, break the code deliberately and watch each one go red.
- A customer requests deletion; DeletionRequest status is ‘requested’ at 2025-09-02 10:00
- Staff views deletion request and clicks ‘Execute’; status becomes ‘executing’
- Deletion completes within 5 minutes; status becomes ‘completed’, customer.deleted_at = 2025-09-02 10:05
- Deleted customer no longer appears in customer list (or marked ‘deleted’)
- Orders associated with deleted customer are anonymized (customer name → ‘Anonymized’, email → ’@.***’)
- Deletion request shows: 1 customer record deleted, 5 orders anonymized, 20 emails purged
- Deletion certificate (PDF) shows: request date 2025-09-02, completion date 2025-09-02 (same-day), data deleted list
- Attempting to re-query deleted customer returns 404 or ‘customer deleted’ (no resurrection)
Risks
Deleting customer cascade breaks other features (order lookup fails, reports crash)—must test thoroughly. Incomplete deletion: customer profile deleted but emails not deleted—privacy violation. Backup retention: old backups contain customer data for 30+ days after deletion—must clarify in policy. If deletion is done carelessly, tax authorities might reject deletion (need 7-year order retention for tax)—anonymization is safer than deletion. Audit log tampered with (deletion entry removed)—no proof of compliance.
Commercial context
| Suggested price | free (core) |
| Rival anchor | Shopify: included; Magento: included |
The anchor is what the nearest equivalent charges on Shopify or Magento today. It is context for a pricing decision, not the decision.
Generated from the commerce plan. See docs/COMMERCE-PLAN.md for the full
catalogue and ../../AI-GUIDE.md for how to work on this repository.