Skip to main content

ConsentAI architecture

Stack

There is no Redis queue, BullMQ worker, or external KV/R2/S3 store.

Runtime flow

  1. Merchant installs the embedded app and enables the theme app embed. afterAuth seeds default settings, a Free subscription, and auto-captures the Shopify Shop GID plus store domains.
  2. Admin page (/app) lets the merchant save consent copy, targeting, and styling. Saves upsert the policy text into a Shopify pcnaid_terms_policy metaobject.
  3. Storefront script reads settings from /apps/pcnaid-tnc/settings through the signed App Proxy. The React Router route verifies the HMAC signature and a 10-minute replay window before returning settings.
  4. 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.
  5. Order binding — Shopify’s authenticated orders/create webhook requires a signed-body Order GID, numeric order_number, and valid offset-bearing created_at. It correlates the normalized cart token against same-tenant, unredacted consent rows and appends a sealed order-binding record.
  6. Billing — plan changes flow through the in-app Billing API (billing.request() / billing.cancel()). Feature gates are enforced server-side.
  7. 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

Storefront traffic never calls the web server directly. Shopify signs every App Proxy request; the server verifies HMAC and timestamp before reading or writing.

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