ConsentAI architecture
Stack
There is no Redis queue, BullMQ worker, or external KV/R2/S3 store.
Runtime flow
-
Merchant installs the embedded app and enables the theme app embed.
afterAuthseeds default settings, a Free subscription, and auto-captures the Shopify Shop GID plus store domains. -
Admin page (
/app) lets the merchant save consent copy, targeting, and styling. Saves upsert the policy text into a Shopifypcnaid_terms_policymetaobject. -
Storefront script reads settings from
/apps/pcnaid-tnc/settingsthrough the signed App Proxy. The React Router route verifies the HMAC signature and a 10-minute replay window before returning settings. -
Consent capture — standard, dynamic, and accelerated checkout targets are blocked until the shopper checks the consent box. The storefront script posts to
/apps/pcnaid-tnc/consent, rate-limited per shop. The proxy action strips Shopify’s?key=cart-token suffix, hashes the IP with per-shop HMAC-SHA256, and stores the immutable evidence. -
Order binding — Shopify’s authenticated
orders/createwebhook requires a signed-body Order GID, numericorder_number, and valid offset-bearingcreated_at. It correlates the normalized cart token against same-tenant, unredacted consent rows and appends a sealed order-binding record. -
Billing — plan changes flow through the in-app Billing API (
billing.request()/billing.cancel()). Feature gates are enforced server-side. -
Privacy webhooks — All three Shopify mandatory compliance webhooks (
customers/data_request,customers/redact,shop/redact) perform real data retention, redaction, and deletion. The three compliance routes share a common handler and run under a per-shop lock so they never process the same shop concurrently.
Flow diagram
Tenant isolation
Tenant separation is enforced by both the application (every query includes the authenticated/signed shop) and PostgreSQL row-level security. Row-level security is forced on every tenant table. Missing or blank tenant context fails closed.Evidence integrity
Consent rows and order bindings are independently sealed at write time with HMAC-SHA256 digests over immutable evidence fields, including the shop domain recorded at write time. The CSV export recomputes every seal and refuses the whole export on a mismatch.See also
- Quickstart — scopes, extensions, and orientation
- API overview — documented interfaces
- Merchant guides — store-facing workflow