FrawlFrawl Handbook
Architecture Decision Records

ADR-0011 — Frawl affiliate platform

Approved architecture and integrity boundaries for Frawl.

ADR-0011 — Frawl affiliate platform

Status: Implementation of the owner-approved plan, 2026-09-22; runtime adaptation documented below. Supersedes the template's product/runtime/locale assumptions in ADR-0002, ADR-0009 and ADR-0010.

Decision

Use Next.js 16, React and Node on Vercel for the merchant application, and Cloudflare Workers for tracking. Share type-safe domain contracts across both. PostgreSQL 17 on Neon is the financial source of truth; Prisma owns the schema and SQL migrations add RLS, partitions, append-only enforcement and balanced-entry constraints.

Organization is the tenant. Product rows and foreign keys carry organization and environment. Runtime connections assume a role without BYPASSRLS. Narrow SECURITY DEFINER functions expose only the minimum bootstrap lookup required to route provider events, API keys and scheduled work. Identity tables are a separate authorization boundary rather than being granted a fictional tenant context.

Data flow

flowchart LR
  SDK[Consent-aware SDK] --> Edge[Tracking Worker]
  Edge --> Queue[Cloudflare Queue]
  Queue --> Ingress[Signed durable batch ingress]
  Ingress --> DB[(PostgreSQL)]
  Merchant[Merchant backend] --> Claim[Signed referral claim]
  Claim --> DB
  PSP[Provider webhook] --> Verify[Signature and trusted retrieval]
  Verify --> Inbox[Durable inbox]
  Inbox --> Engine[Attribution, fraud and commission]
  Engine --> DB
  DB --> Outbox[Transactional outbox]
  Outbox --> Jobs[Retry and reconciliation]
  DB --> UI[Merchant and affiliate portals]

The Worker queue currently forwards signed batches to the Node control plane, which commits batched inserts. It does not open a PostgreSQL connection for every click. The database exports createWorkerDatabase for a future direct consumer; if Hyperdrive is used, query caching must be disabled for authorization and financial reads. This adapts the proposed direct Hyperdrive consumer so the initial release shares one durable ingestion and financial processing implementation in Node. The deployed latency and backlog gates remain mandatory before this path is accepted for production.

Integrity contracts

AreaContract
MoneyBigint minor units, explicit currency, immutable balanced ledger
IdempotencyProvider delivery key plus canonical payment/adjustment financial key
AttributionServer-stamped touches, first/last policy, bounded window, pinned subscription association
Race handlingPending attribution, durable inbox, transaction retries and tenant locks
RefundsCumulative delta capped at original commission; exported reservations remain held
PayoutsSeparate prepare/approve/confirm grants; immutable export fingerprint and payment references
BillingInternal subscription/cycle/attempt IDs; fixed Moyasar given_id across uncertain outcomes
IdentityVerified SSO trust, source-specific SCIM subjects, explicit group role projection
Browser privacyConsent before persistent identity, no covert fingerprinting, no ITP bypass promise

Boundaries and tradeoffs

A merchant's PSP payment, a Frawl subscription payment, and an affiliate external payout never share a payment model or webhook secret. Affiliates are not organization members by default. Manual payout approval is intentional; automated bank transfers are outside the approved release.

Queue and webhook delivery is at least once; all consumers must be idempotent. Ledger state, audit and outbox entries commit together. No migration or closure cascades through financial history. English is default; all user-facing flows also support Arabic and logical RTL properties.

A single primary region makes financial consistency tractable. Edge ingress minimizes the visitor's blocking work, while write batching separates app requests from click ingestion. Local benchmark numbers do not prove the 1,000 requests/second deployed target.

Commercial assumptions

Starter $49, Growth $149, Enterprise $499 monthly, annual billing at ten monthly payments; prices and limits are versioned. Twenty Starter, five Growth and one Enterprise account would produce $2,224/month, or SAR 8,340 at the illustrative 3.75 rate, before fees and operating costs. Confidence: low. Channel: Frawl subscriptions. This is a scenario, not a forecast.

References

On this page