AstroBaaS

Tax & compliance

GDPR Data Export

Free — GPL coresize Mplanned, not built

Generated from docs/plan/core/gdpr-data-export/PLAN.md in the AstroBaaS repository. Nothing described below is implemented — it is the written plan for it.

A core feature that allows customers to request and download all their personal data (profile, orders, emails, wishlist, activity logs) in a machine-readable format (JSON, CSV, CSV-ZIP), fulfilling GDPR right-of-access within 30 days. Merchants avoid fines and customers trust the shop.

The problem

A French merchant receives a GDPR right-of-access request: ‘Send me all my data.’ She manually gathers customer info from 5 different systems (orders, emails, profile, wishlist, reviews), spends 2 hours assembling it, and emails a ZIP file. She knows she’s missed some data (customer doesn’t have visibility into logs). GDPR requires response within 30 days; she’s cut it close twice.

What it does

  • Data export request: customer can self-serve request export (no staff involvement)
  • Comprehensive export: includes profile (name, email, phone, address), all orders, all emails received, wishlist, reviews, activity log
  • Format options: JSON (most complete), CSV (readable), CSV-ZIP (multiple CSVs, organized by category)
  • Audit log: every data access (staff or customer) is logged with timestamp
  • Email delivery: export is prepared and emailed to customer within 24 hours
  • Admin UI: staff can see pending/completed export requests, resend exports
  • Expiry: export link/download expires after 7 days (security; customer can request again)
  • Encryption: export file is encrypted in transit (HTTPS only)
  • Legal proof: request timestamp and completion timestamp are logged (prove 30-day compliance)

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.

  • Data from third-party integrations (GA4, email provider data)—out of scope; customer must request from them
  • Activity logs from payment gateway—out of scope (Stripe owns their logs)
  • Deletion of data (handled by right-to-be-forgotten)—separate feature
  • Data portability to another shop (we provide export, customer must port it)—out of scope
  • Anonymous export (export without customer auth)—security risk, out of scope

Data model

New: DataExportRequest(id, customerId, request_date, prepared_date, downloaded_date, status, file_hash). Extend audit log: log every export access (who accessed, when, which export). No core migration; stored in plugin/audit table.

API

  • POST /data-export/request — customer initiates data export request
  • GET /data-export/status/:requestId — return status (requested/prepared/emailed/downloaded/expired)
  • GET /data-export/:requestId/download — download export file (requires auth)
  • POST /data-export/:requestId/resend — resend export email (admin only)
  • GET /data-export/requests — list all requests (admin only)

Every route added here must also appear in src/pages/openapi.json.ts — a test fails the build if it does not.

Admin

Data export dashboard: list of export requests (pending/completed), request date, customer name, status, download link, resend button, audit log (who accessed each export)

The seam — why this is core

Core owns: data export logic (gathering profile, orders, emails, etc.), API, audit trail. Paid pack owns: exporting from third-party integrations (GA4 data export connector, Stripe order history, etc.).

Core owns the interface + honest data packager; data privacy is infrastructure, not a credential or support commitment.

Dependencies

  • customer schema (must have profile data to export)
  • order system (all orders must be exportable)
  • email system (all emails sent to customer must be logged and exportable)
  • audit log (every export access must be logged)

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 data export; status is ‘requested’ at 2025-09-02 10:00
  • Export is prepared within 24 hours; status becomes ‘prepared’, email is sent
  • Export file includes: profile (name, email, phone, address), 10 orders (with items, amounts, dates), 50 emails (newsletters, shipping confirmations), wishlist (5 items), reviews (3 reviews)
  • Downloading export file as JSON includes all data in structured format (can be parsed by code)
  • Downloading export file as CSV produces 4 CSVs: profile.csv, orders.csv, emails.csv, wishlist.csv (in ZIP)
  • Export link expires 7 days after preparation; attempting to download after expiry shows ‘link expired’
  • Audit log shows: customer ‘john@example.com’ downloaded export on 2025-09-02 10:30; admin ‘jane@acme.com’ accessed same export on 2025-09-03
  • Export file is encrypted (HTTPS transfer only, no plain HTTP); download bar shows ‘HTTPS secure’

Risks

Export file too large (10MB+) → email delivery fails. Export data incomplete (missing orders from before migration)—customer doesn’t get all data, but we claim we did. Export link leaked (shared via unencrypted email, intercepted)—privacy violation. Audit log doesn’t capture all accesses (gap = no proof of compliance). Customer forgets to download within 7 days—must allow resend/extension.

Commercial context

Suggested pricefree (core)
Rival anchorShopify: 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.