Architecture Decision Log
Purpose
A single chronological record of every major architecture decision, why it was made, what alternatives were considered, and where the full detail lives. This doesn't replace the detailed docs — it's the index that answers "why is it this way" without searching through 100+ pages.
Format
Each entry: Decision — Alternatives considered — Reasoning — Status — Full detail link.
Backend language: FastAPI (Python)
Alternatives considered: Node.js via Next.js API routes (original choice)
Reasoning: Founder preference for Python/FastAPI over the original Node-unified approach. Real trade-off accepted: two languages, two deploy paths, CORS between services, instead of one unified app.
Status: Confirmed. Detail: 02. Backend Architecture
Application structure: Modular monolith, not microservices
Alternatives considered: Full microservices (separate Payments/Campaigns/Notifications services)
Reasoning: Team size (solo founder) doesn't justify microservices' organizational benefit; financial-chain transaction consistency is simpler within one service boundary. Built with clean internal module boundaries so extraction is possible later without a rewrite.
Status: Confirmed. Revisit trigger: a specific module demonstrably needs independent scaling/failure isolation under real load. Detail: 02. System Architecture, 02. Backend Architecture
Database: Supabase (MVP) → Neon (production/scale)
Alternatives considered: Self-managed Postgres, RDS
Reasoning: Supabase for MVP ease (pgvector + built-in pooling out of the box); Neon confirmed as the actual production target for database branching (pairs with Environment Strategy/Git Strategy) and serverless scale-to-zero. Both vanilla Postgres — migration is a data move, not a rearchitecture.
Status: Confirmed, staged. Revisit trigger: Supabase pricing/connection limits become a real bottleneck. Detail: 06. Hosting Strategy
Auth: Clerk → Ory Kratos
Alternatives considered: Clerk (original), Better Auth (rejected — TypeScript-only, incompatible with FastAPI), Authentik (rejected — built for enterprise internal SSO, not consumer CIAM)
Reasoning: Cost-at-scale and vendor lock-in were real long-term concerns; Kratos is language-agnostic (pure REST API, no FastAPI friction) and purpose-built for consumer identity. Ory Network (managed) for MVP, self-hosted later — same staged pattern as the database.
Status: Confirmed, staged. Detail: 04. Authentication
Checkout: SellVia-hosted only for MVP
Alternatives considered: External-site checkout (redirect + webhook/pixel tracking, Shopify-style)
Reasoning: Dual-mode roughly doubles MVP engineering surface and reintroduces attribution ambiguity (cookie blocking, webhook reliability, self-reported sales) the product's trust positioning is built to eliminate.
Status: Confirmed for MVP. Deferred: external-site tracking is a named v2 item. Detail: 01. Money Flow
Payments processor: Stripe Connect (superseded 2026-08-10 — see reversal below)
Alternatives considered: Lemon Squeezy / Paddle (Merchant of Record model — rejected at the time)
Reasoning (original, 2026-08-03): MoR providers assume a single seller; structurally incompatible with the three-way Merchant/Creator/Platform split this business model requires. Stripe Connect's application_fee_amount + transfer_data natively supports the split.
Status: Superseded. Detail: 01. Commission Engine, 05. Payment Flow
Tax handling: Stripe Tax (superseded 2026-08-10 — see reversal below)
Alternatives considered: Merchant of Record (rejected, see above), no tooling (rejected — insufficient for multi-jurisdiction VAT/sales tax)
Reasoning (original, 2026-08-03): Plugs into existing Stripe Connect setup without disrupting the split architecture. Marketplace-facilitator-law liability question remains separately open pending real legal review.
Status: Superseded. Detail: 05. Tax Considerations
Pricing model: flat 2% fee, no subscription
Alternatives considered: $49/mo subscription tier (original idea, dropped)
Reasoning: Simpler to explain ("we only make money when you do"), no billing infrastructure needed, consistent with the platform's "$0 owed until something sells" positioning.
Status: Confirmed. Detail: 05. Platform Business Model & Pricing
Currency support: USD/EUR/GBP only, PKR dropped
Reasoning: Paddle doesn't support direct PKR payouts to connected accounts; would have required a separate local payout partner. Revisit only with real demand.
Status: Confirmed. Detail: 01. Business Rules
Data consistency: Event sourcing (financial chain only) + last-write-wins (everything else)
Alternatives considered: Universal event sourcing (rejected — over-engineering for low-stakes data), CRDTs/Operational Transformation (rejected — no concurrent-editing feature exists in the product to justify them)
Reasoning: Event sourcing's audit/replay value is highest specifically for money; applying it everywhere adds complexity without payoff. LWW is sufficient for single-owner-edited data like Campaigns.
Status: Confirmed. Detail: 03. Event Sourcing (Financial Chain), 03. Database Design
Git: Monorepo, short-lived service-prefixed feature branches
Alternatives considered: Two separate repos (frontend/backend), long-lived per-service branches (both rejected)
Reasoning: Cross-cutting changes (new endpoint + the frontend calling it) stay atomic in one PR. Long-lived branches increase risk via drift, contrary to the actual goal of minimizing risk — short branches + path-scoped CI is the safer pattern.
Status: Confirmed. Detail: 06. Git Repository Strategy
Risk mitigation for financial-chain changes: Feature flags, not just branch strategy
Reasoning: Branch naming affects code review, not production exposure. A feature flag can be killed in seconds without a redeploy — the actual highest-leverage risk reduction for payments-critical changes.
Status: Confirmed, mandatory for any Sales/Commissions/Payouts/Refunds change. Detail: 06. Feature Flags Strategy
Status page: separate domain, separate infrastructure (reversed from earlier "not needed" stance)
Reasoning: A status page hosted on the same infrastructure it reports on fails exactly when it's needed most. Managed tool (Instatus/Better Uptime-style), not self-hosted — same "use managed services for undifferentiated infra" pattern as Paddle/Clerk/Supabase.
Status: Confirmed, explicit reversal of an earlier deferral. Detail: 10. Status Page & Incident Communication
AI features: API-based only, no custom training; fraud detection stays rules-based
Reasoning: No training data exists yet for fraud ML; a wrong ML call on real earnings is a worse failure than an over-cautious rule. All AI features (matching, screening, copy-assist) are embeddings/LLM API calls, not custom models.
Status: Confirmed for MVP. Detail: 02. AI Services
Open Questions
None — this log is descriptive, not decision-making. Add a new entry whenever a future prompt resolves or reverses an architectural choice.
Update (2026-08-07): MAJOR REVERSAL — Checkout Model
Checkout: External-site tracking (REVERSES the SellVia-hosted-only decision above)
Alternatives considered: SellVia-hosted checkout (original MVP decision, now reversed)
Reasoning: Founder decided to switch to the affiliate-network model (customer buys on merchant's own site, SellVia tracks via redirect + merchant-reported sales) rather than processing payment directly. This reopens the exact trust/attribution-reliability trade-offs the original hosted-checkout decision was built to avoid (cookie blocking, merchant under-reporting risk, no direct payment witness) — a deliberate, informed trade the founder chose to make.
New problem this created: since SellVia never touches the payment, it needed a new money-collection mechanism. Resolved: periodic billing (merchant's card on file charged on a recurring cycle for accumulated commissions + platform fee), with creator payouts sequenced after successful billing (bill-first-then-pay, lower risk than fronting the money).
Status: Confirmed 2026-08-07, supersedes the earlier "SellVia Checkout only for MVP" entry above. Detail: 01. Money Flow, 01. Commission Engine, 01. State Machines, 05. Payment Flow — all rewritten same date.
Still open: merchant integration mechanism (webhook spec vs. platform-specific like Shopify first), billing cycle length, card-failure retry policy, sale-report acceptance criteria.
Update (2026-08-10): Payments processor reversed — Paddle replaces Stripe
Payments processor: Paddle (REVERSES the Stripe Connect / Stripe Tax decisions above)
Alternatives considered: Stripe Connect (original choice, now reversed), staying split (Paddle for merchant billing only + Stripe Connect for creator payouts — rejected in favor of one processor)
Reasoning: Founder decision to consolidate on Paddle. Under the current external-site-tracking model (reversed 2026-08-07), Stripe was already doing two jobs, not the original one it was chosen for: (1) periodically billing the merchant's card on file for accumulated commissions + platform fee, and (2) paying out individual creators. Paddle covers job (1) natively and well — it's a Merchant of Record, built exactly for billing/subscribing a customer, and Paddle Tax replaces Stripe Tax for the same multi-jurisdiction VAT/sales-tax handling this doc's original Tax entry called for.
The open gap this creates: job (2), paying out many independent third-party creators with their own KYC/tax-form collection, is what Stripe Connect specifically solved and what the original 2026-08-03 entry above correctly identified MoR providers as not built for. Paddle's marketplace/payout product ("Paddle for Platforms") is the closest fit, but it has not been evaluated against Commission Engine's payout requirements ($50 threshold, bill-first-then-pay sequencing, per-creator bank payout) — this is real, unresolved risk this reversal introduces, not a solved problem. Flagging explicitly rather than assuming parity with what Stripe Connect provided.
Status: Confirmed 2026-08-10, supersedes the "Payments processor: Stripe Connect" and "Tax handling: Stripe Tax" entries above. Detail: 01. Commission Engine, 01. Money Flow, 05. Payment Flow, 05. Wallet Design, 05. Payout Process, 05. Tax Considerations — all updated same date.
Open question this reversal creates: does Paddle for Platforms actually support per-creator payout the way this doc's Payout Process/Wallet Design assume Stripe Connect did — needs real evaluation before this is build-ready, not just a documentation find-and-replace.
Update (2026-08-23): MAJOR REVISION — Pakistan-Only Market, Paddle Removed, Shopify-Only Integration, Offer Absorbs Campaign
Four founder decisions, all effective immediately, superseding the entries above where they conflict.
Market scope: Pakistan-only for MVP (REVERSES "USD/EUR/GBP only, PKR dropped")
Alternatives considered: Continuing global USD/EUR/GBP scope (original MVP decision, now reversed)
Reasoning: Founder decision to launch to the Pakistani market exclusively — every merchant onboarded for MVP is a Pakistani business. This resolves the still-open "beachhead niche" question from Product Roadmap/Product Vision by geography rather than product category, and removes the entire reason PKR was dropped in the first place (Paddle's lack of direct PKR payout support no longer matters if Paddle isn't used at all — see next entry).
Status: Confirmed 2026-08-23. Detail: 01. Product Vision, 01. MVP Scope, 01. Business Rules.
Payments processor: Paddle removed, no processor for MVP — local bank transfer (working default) (REVERSES the 2026-08-10 Paddle entry)
Alternatives considered: Keeping Paddle (rejected — doesn't support PKR payouts natively, and is the wrong tool for a single-country, non-MoR-dependent model); a local gateway (JazzCash/EasyPaisa/Safepay) API integration (candidate for later, not chosen for MVP)
Reasoning: Founder decision: "instead of paddle or anything." With the market narrowed to Pakistan, the three-way MoR/split problem Paddle and Stripe Connect were both solving mostly disappears — there's one country, one currency, and (per the next entry) one sales channel. Working default, needs founder confirmation before build: merchant billing and creator payout both happen via direct bank transfer (IBFT/RAAST), admin-initiated and admin-verified, with no third-party payment processor in the loop for MVP. This is the simplest mechanism that requires zero external integration and fits "any merchant from here."
Status: Working default, not yet build-confirmed. Open: exact rail (manual IBFT vs. RAAST-instant vs. a local gateway API), and who reconciles it (Admin manually vs. an automated feed) — flagged in MVP Scope's Still-Open Items. Detail: 05. Payment Flow, 05. Payout Process, 05. Wallet Design, 05. Platform Business Model & Pricing (all updated 2026-08-23).
Merchant integration: Shopify-only via native webhook (REVERSES the 2026-08-07 "universal onboarding snippet" resolution)
Alternatives considered: Universal JS snippet across any platform (the prior resolution, now reversed for MVP scope reasons, not because it was technically wrong); discount-code-only fallback alone (insufficient without a primary signal)
Reasoning: Founder decision: "for now we are just going with shopify only." Since MVP explicitly does not need to support arbitrary platforms, the snippet's main advantage (works everywhere, no per-platform engineering) stops mattering, and Shopify's native webhook (already identified in Payment Flow's own 2026-08-07 update as "the obvious first candidate" for a platform-specific upgrade) becomes the primary mechanism instead of a deferred nice-to-have. More reliable than the snippet (server-side, not dependent on the customer's browser/cookies/ad-blocker), at the cost of only working for Shopify merchants — an acceptable trade now that all MVP merchants are pre-scoped to a platform anyway.
Status: Confirmed 2026-08-23. Snippet + discount-code-fallback approach is retired for MVP, not deleted from history — becomes the relevant mechanism again only if/when SellVia supports non-Shopify merchants. Detail: 05. Payment Flow (updated 2026-08-23).
Domain model: Campaign entity removed, merged into Offer
Alternatives considered: Keeping Offer and Campaign as two entities (the original model — Offer = product, Campaign = a commission-bearing listing of that product); one-campaign-per-offer as a compromise (considered, rejected as still two entities for no real benefit)
Reasoning: Founder decision: "offer is offer, it is not turning into any campaign at all." This resolves Domain Model's own open question ("does Offer need its own entity separate from Campaign?") in favor of the simpler answer — there is no Campaign entity. An Offer carries its commission rate and lifecycle status (draft/live/paused/ended) directly. Applications, AffiliateLinks, and Sales attach to an Offer, not to a Campaign-wrapping-an-Offer.
Status: Confirmed 2026-08-23. Detail: 01. Domain Model, 01. Business Rules, 01. State Machines, 01. Commission Engine, 01. Product Glossary (all updated 2026-08-23).
Not yet updated to match: the three frontend Scratch docs (FEATURE_LIST.md, SCREEN_INVENTORY.md, SITE_MAP.md) still describe the Campaign-based model throughout — flagged with a banner pointing here rather than fully rewritten, given the scope of ~50 screens referencing "Campaign." Treat "Campaign" in those two docs as "Offer" until they're rewritten.
(FEATURE_LIST.md was fully rewritten 2026-08-23, same day — see that doc directly. SCREEN_INVENTORY.md and SITE_MAP.md still carry banners rather than full rewrites.)
Update (2026-08-23, later same day): Processor Confirmed — Swich Replaces the Manual-Bank-Transfer Working Default
Payments processor: Swich (RESOLVES the "no processor, manual bank transfer" working default above)
Alternatives considered: Payoneer (researched, rejected — built for cross-border flows, doesn't natively hold/move domestic PKR, and its billing-side product (Checkout) requires a Hong Kong entity + $20k/month minimum volume, disqualifying for MVP); plain manual bank transfer, admin-verified (the prior working default, now upgraded); AbhiPay (researched, inconclusive — site access blocked research, appears to be an acquiring/checkout product without confirmed bulk-payout capability); AssanPay (viable for the billing leg alone, but no confirmed payout/disbursement product, so it would've needed pairing with a second vendor anyway).
Reasoning: Founder decision: Swich (swichnow.io), a Pakistani payments infrastructure company, PCI-DSS v4.0.1 certified. Chosen because it covers both legs SellVia needs under one vendor:
- Merchant billing: Swich's recurring billing / invoice-link product — SellVia generates a payment request for each BillingCycle's total, merchant pays via card/bank transfer/JazzCash/EasyPaisa through Swich's checkout, webhook confirms → cycle marked
charged. - Creator payout: Swich's payout/disbursement API — bulk disbursement across bank transfer (1LINK), JazzCash, EasyPaisa, and Raast, explicitly marketed for exactly this use case ("commission payouts" named directly in Swich's own materials).
One vendor, one integration, one reconciliation surface — the reasoning that ruled out needing to pair AssanPay (billing) with a separate Raast-licensed fintech (payouts).
Genuine, real distinction from Paddle, not a detail to gloss over: Swich is a payment processor/gateway — not a Merchant of Record. Paddle (the original MVP processor) absorbed tax/compliance obligations as the legal seller of record; Swich does not. This means SellVia itself remains legally responsible for its own tax obligations (see 05. Tax Considerations, updated same date) — this was already true under the "no processor, bank transfer" default, and remains true with Swich. Nothing about choosing Swich reduces this responsibility the way choosing Paddle once did.
Status: Confirmed 2026-08-23. Not yet done: actual signup/integration with Swich — pricing, onboarding/KYC requirements for a 10–25-merchant Private Beta volume, and Swich's exact API field shapes are unconfirmed pending a real vendor conversation. Every schema/field name introduced in the docs below is a working draft, not a verified Swich API contract. Detail: 01. Money Flow, 01. Commission Engine, 01. State Machines, 05. Payment Flow, 05. Payout Process, 05. Wallet Design, 05. Platform Business Model & Pricing, 05. Tax Considerations, 03. Table Specifications (all updated same date).
References
- Backend Architecture· Technical Architecture
- System Architecture· Technical Architecture
- Hosting Strategy· Infrastructure & DevOps
- Authentication· Security
- Money Flow· Business Logic
- Commission Engine· Business Logic
- Tax Considerations· Payments
- Platform Business Model & Pricing· Payments
- Business Rules· Business Logic
- Event Sourcing (Financial Chain)· Database
- Git Repository Strategy· Infrastructure & DevOps
- Feature Flags Strategy· Infrastructure & DevOps
- Status Page & Incident Communication· Operations
- AI Services· Technical Architecture
- Payout Process· Payments
- Product Vision· Product Foundation
- Payment Flow· Payments
- Domain Model· Business Logic
- Product Glossary· Product Foundation
Referenced by
- Automated Monthly P&L· Analytics
- Unit Economics (Revenue vs Cost per User)· Analytics
- Endpoint Specifications· API
- Webhooks· API
- Business Rules· Business Logic
- Commission Engine· Business Logic
- Money Flow· Business Logic
- User Flows· Business Logic
- Constraints· Database
- ER Diagram· Database
- Table Specifications· Database
- Business Edge Cases· Edge Cases
- Payment Edge Cases· Edge Cases
- User Edge Cases· Edge Cases
- Environment Setup Guide· Infrastructure & DevOps
- Environment Strategy· Infrastructure & DevOps
- Monitoring· Infrastructure & DevOps
- WAF Configuration· Infrastructure & DevOps
- Customer Support Flows· Operations
- Chargebacks· Payments
- Financial Ledger· Payments
- Payment Flow· Payments
- Payout Process· Payments
- Platform Business Model & Pricing· Payments
- Reconciliation· Payments
- Refund Handling· Payments
- Tax Considerations· Payments
- Wallet Design· Payments
- MVP Scope· Product Foundation
- Product Glossary· Product Foundation
- Product Vision· Product Foundation
- CORS, CSP & Security Headers· Security
- Webhook Security· Security
- Backend Architecture· Technical Architecture
- Frontend Architecture· Technical Architecture