SellVia Docs — menu
DocsUIFEATURE_LIST

FEATURE_LIST

UI/FEATURE_LIST.md
frontendUpdated Aug 23, 2026

28 open questions in this doc

  • L7How to read this document: SellVia's docs record decisions chronologically, with later "Update" sections superseding earlier text in the same file. This list reflects the latest resolved state as of the most recent updates (through 2026-08-23), not the origina…
  • L60Edge cases: Application-rejected notification content unspecified (open question — Needs clarification); real-time vs. digest cadence for "sale made" unspecified (Needs clarification); exact merchant "milestone reached" thresholds undefined (Needs clarificatio…
  • L91Creator↔Offer matching | Ranks offer discovery results by embedding similarity on top of existing category/commission filters | Creator discovery/browse screen | Post-MVP per some docs, but described as an "initial AI level" item elsewhere — Needs clarificatio…
  • L94Disclosure nudge | Fixed, legally-reviewed FTC-style disclosure template shown at link-generation time | Creator "Get Link" moment | Deliberately templated, NOT LLM-generated (legal text) — Pakistan-specific disclosure norms not yet reviewed, Needs clarificati…
  • L107Expected frontend behavior: Nav: logo left, links center/right ("How It Works," "For Businesses," "For Creators"), single "Join Waitlist" CTA — no dropdowns, no mega menus. Zeroed-metric device persists into early product messaging. Copy should reflect Pakista…
See all 28 on the clarifications screen →

SellVia — Frontend Feature List

Purpose

Every product feature the frontend needs to support, derived exclusively from the documentation in /Docs. Grouped by product area. Each feature lists: description, user goal, main actions, expected frontend behavior, important states, relevant screens (see SCREEN_INVENTORY.md), backend/API dependencies, permissions, edge cases, and source docs.

How to read this document: SellVia's docs record decisions chronologically, with later "Update" sections superseding earlier text in the same file. This list reflects the latest resolved state as of the most recent updates (through 2026-08-23), not the original/superseded framing. Where a doc contains stale, unresolved, or contradictory statements, this is marked "Needs clarification" rather than guessed at. See SITE_MAP.md and SCREEN_INVENTORY.md for the navigation and screen-level counterparts to this list.

Critical context for every feature below (updated 2026-08-23):

  1. Market: Pakistan-only, PKR only. Every Merchant is a Pakistani business. No USD/EUR/GBP for MVP.
  2. Payment processor: Swich (swichnow.io), confirmed 2026-08-23. Merchant billing runs through Swich's recurring billing/invoice-link product; creator payout runs through Swich's disbursement API (bank, JazzCash, EasyPaisa, Raast). There is no embedded Paddle Checkout anywhere in the frontend, and no manual admin-run bank-transfer workflow either — both legs are Swich-integrated, webhook-confirmed. Swich is a payment processor, not a Merchant of Record — SellVia keeps its own tax responsibility (see Payments/Tax Considerations). Swich's exact API shapes/pricing/onboarding requirements are unconfirmed pending real integration — every Swich-specific field/flow below is a working draft.
  3. Merchant integration: Shopify only, via native webhook. Every MVP merchant connects a Shopify store (OAuth/app-install); Shopify's orders/paid webhook reports sales, not a copy-paste JS snippet. The customer still buys on the merchant's own (Shopify) checkout — SellVia has never hosted checkout for this model, unrelated to this change.
  4. No separate Campaign entity. "Offer is offer, it is not turning into any campaign at all." An Offer carries its commission rate and lifecycle status (draft/live/paused/ended) directly — one creation flow, not a two-step Offer-then-Campaign wrap. Applications, AffiliateLinks, and Sales attach to an Offer.

Full reasoning for all four: Technical Architecture/Architecture Decision Log, Product Foundation/MVP Scope. Auth provider is Ory Kratos (switched from Clerk 2026-08-04) — unaffected by this revision.


0. Cross-Cutting Platform Features

These apply across every module rather than belonging to one screen.

0.1 Unified Authentication (Sign Up / Log In / Session)

  • Description: Single sign-up form; user selects Merchant or Creator role (a user may hold both roles on one account). Auth handled by Ory Kratos.
  • User goal: Get into the product with minimal friction, on the correct role-specific path.
  • Main user actions: Register (email/password, optionally social login — provider TBD), verify email, log in, log out, log out of all other devices, reset password.
  • Expected frontend behavior: Ory Kratos SDK/components drive the sign-in/sign-up/session UI. Role selection branches the post-signup flow (Merchant onboarding vs. Creator onboarding). Session is server-validated (not a cached JWT) — sensitive actions re-verify live.
  • Important states: loading (session check), unauthenticated, authenticated (role-resolved), email-unverified (gated), error (invalid credentials, account locked), MFA-challenge (if enabled).
  • Relevant screens: Login, Register, Forgot/Reset Password, Verify Email, MFA setup/challenge.
  • API/backend dependencies: Ory Kratos REST API (session issuance, verification, password reset, email verification); backend resolves role(s) from Kratos identity traits, never trusts a client-supplied role.
  • Permissions/roles: N/A (pre-role-gating layer); role is attached to session after auth.
  • Edge cases: Session expires at 14-day ceiling forcing re-login; 5 concurrent sessions per account (Admin may need a higher cap — unresolved); instant revocation on password change, Admin suspension, or IP-anomaly ban escalation.
  • Source: Security/Authentication, Security/Session Management, API/API Authentication, Business Logic/User Roles.

0.2 Dual-Role Context Switching

  • Description: A single account can be both Merchant and Creator. Each role has its own separate profile, data, and nav.
  • User goal: Operate as either "hat" without the two experiences bleeding together.
  • Main user actions: Switch active context (Merchant ↔ Creator).
  • Expected frontend behavior: Explicit role switcher (mechanism not yet designed in docs) rather than a merged nav — Merchant nav (Offers/Applications/Sales/Payouts) and Creator nav (Discover/My Links/Earnings) never combine into one menu.
  • Important states: active-context indicator; empty state if the user hasn't set up the other role yet.
  • Relevant screens: Present in the global app shell/header of both dashboards.
  • API/backend dependencies: Role(s) resolved server-side per request; a Merchant-context request never leaks Creator-context data and vice versa (tested explicitly per Cross-Tenant Isolation Testing).
  • Permissions/roles: Merchant, Creator (same user, two contexts).
  • Edge cases: Self-dealing block — a dual-role user's CreatorProfile can never apply to an Offer owned by their own MerchantProfile (hard-blocked server-side, not just hidden in UI).
  • Source: Business Logic/User Roles, UX/Navigation, Edge Cases/User Edge Cases, Business Logic/Business Rules.

0.3 Notifications

  • Description: In-app + email notifications for key lifecycle events, kept quiet/informational (no gamification, per design philosophy).
  • User goal: Know when something requiring attention or worth celebrating has happened, without checking manually.
  • Main user actions: View notification feed, mark as read, click through to the relevant screen.
  • Expected frontend behavior: Real-time or near-real-time delivery for high-trust moments (e.g., application approved → link issued) — this is one of the product's "trust moments" and should not feel delayed/black-box. Quiet visual treatment (no confetti/badges).
  • Important states: unread/read, empty ("no notifications yet"), loading.
  • Relevant screens: Notification center/feed (shared component across Merchant/Creator/Admin shells).
  • API/backend dependencies: notifications table; triggers per Notification Logic; async job completion also notifies (job_completed).
  • Permissions/roles: Scoped to the recipient user_id only.
  • Edge cases: Application-rejected notification content unspecified (open question — Needs clarification); real-time vs. digest cadence for "sale made" unspecified (Needs clarification); exact merchant "milestone reached" thresholds undefined (Needs clarification).
  • Source: Business Logic/Notification Logic, Technical Architecture/Async Job Pattern & Idempotency, UX/Interaction Patterns.

0.4 Empty / Loading / Error States (Design System Requirement)

  • Description: A calm, intentional empty-state pattern reused throughout the product, echoing the public site's own "0 creators, 0 sales, ₨0" zeroed-dashboard honesty device.
  • User goal: Never mistake "nothing here yet" for "something is broken."
  • Expected frontend behavior: Empty states read as expected/calm, not broken (e.g., "link generated, zero clicks yet"). Loading states are simple fades/skeletons, never playful spinner copy (restrained-animation design rule). Errors are specific and actionable ("You've already applied to this offer," never "Something went wrong").
  • Relevant screens: Every list/table view across the app (offers, applications, sales, payouts, links).
  • API/backend dependencies: Structured error shape { "error": { "code", "message", "status" } } from every endpoint; two-layer error handling (safe message to user, full detail to private log) — no raw stack traces ever reach the UI.
  • Source: UX/Components, UX/Copy Guidelines, API/Error Responses, Infrastructure/Error Handling & Logging Pipeline.

0.5 Accessibility (Binding, Not Aspirational)

  • Description: Full keyboard navigation, screen-reader compatibility, and verified WCAG AA color contrast across the entire product — explicitly called out as enforced pre-launch gates, not nice-to-haves.
  • Expected frontend behavior: Logical tab order; visible focus rings (lime accent, consistent with the design system's "active state" use of lime); all custom interactive components (offer discovery filters, the "Get Link" component, status badges with actions) independently verified for keyboard operability — shadcn/ui defaults aren't assumed sufficient; all form fields have real associated labels (no placeholder-only labels); aria-describedby/aria-invalid on validation errors; all meaningful images have alt text (including product images — schema currently lacks an alt-text field, flagged as a gap); icon-only controls get aria-label; async status changes use aria-live.
  • Contrast status — RESOLVED 2026-08-23: Lime (#BFFF13) and Gray 01 (#A1A1AA) both verified compliant against black (17.5:1 and 8.2:1). Gray 02 was the actual failure at 4.35:1 — corrected to #787882 (4.82:1). See UX/Accessibility for the full computed table. No longer an open risk.
  • Source: UX/Accessibility, Security/Security Checklist.

0.6 Machine-Readability of Public Content (SEO / AI-Agent Legibility)

  • Description: Public Offer pages carry schema.org Product/Offer JSON-LD; semantic HTML landmarks; OpenAPI spec auto-generated from the backend; llms.txt at the marketing site root; deliberate robots.txt allowing known AI crawlers on public pages only.
  • User goal (indirect): Let AI shopping agents, search AI answers, and link-preview tools understand SellVia's public offers correctly.
  • Expected frontend behavior: Every public Offer detail page renders JSON-LD with accurate price/currency (PKR)/availability. Standard OG/Twitter-card/canonical-URL meta tags on all public pages, generated from the base page template.
  • What does NOT get this treatment: Authenticated dashboards, any tenant-private data — same boundary as accessibility, but for machines instead of humans.
  • Source: UX/AI Agent & Machine Readability.

0.7 AI-Assisted Features

FeatureWhat it doesUser-facing surfaceNotes
Creator↔Offer matchingRanks offer discovery results by embedding similarity on top of existing category/commission filtersCreator discovery/browse screenPost-MVP per some docs, but described as an "initial AI level" item elsewhere — Needs clarification on MVP vs. post-MVP timing
Application screening assistOne LLM-generated plain-language fit summary per application, cached, shown to the reviewing MerchantMerchant application review screenNever shown to any other Merchant (tenant-private)
Offer copy assistMerchant provides product name + price (PKR); LLM drafts an editable offer descriptionMerchant offer creation formDraft is editable, not final
Disclosure nudgeFixed, legally-reviewed FTC-style disclosure template shown at link-generation timeCreator "Get Link" momentDeliberately templated, NOT LLM-generated (legal text) — Pakistan-specific disclosure norms not yet reviewed, Needs clarification

1. Public Marketing & Discovery

1.1 Marketing Site (wesellvia.com)

  • Description: The existing live public site — hero, concept walkthrough, roadmap-stage visibility, FAQ, waitlist form. Deliberately shows zeroed real metrics ("0 creators approved, 0 sales, ₨0 tracked revenue") as a radical-transparency positioning device, not a placeholder.
  • User goal: Understand what SellVia is, see it's early/honest, and join the waitlist.
  • Main user actions: Read hero/roadmap/FAQ, submit waitlist form (business or creator, "why do you want to join").
  • Expected frontend behavior: Nav: logo left, links center/right ("How It Works," "For Businesses," "For Creators"), single "Join Waitlist" CTA — no dropdowns, no mega menus. Zeroed-metric device persists into early product messaging. Copy should reflect Pakistan-only scope once product messaging catches up to the 2026-08-23 revision — Needs clarification on whether the current live site copy needs an update pass.
  • Important states: waitlist form submitted (confirmation), roadmap stage indicator ("you are literally here" — currently Stage 02: Validation).
  • Relevant screens: Public Home / Landing.
  • API/backend dependencies: Waitlist signup endpoint (implied, not explicitly specified in Endpoint Specifications — Needs clarification).
  • Permissions/roles: Public, unauthenticated.
  • Edge cases: None documented beyond standard form validation.
  • Source: Product Foundation/Product Vision, Product Foundation/Product Roadmap, UX/Design System, UX/Navigation.

1.2 Public Offer Discovery / Browse

  • Description: Browsable, filterable list of live offers — the entry point for creators (and, per the AI-agent doc, for machine consumption of public product data).
  • User goal: Find an offer/product worth promoting.
  • Main user actions: Filter by category (digital/physical), commission-rate range, niche; sort by newest, highest commission, most applications (popularity proxy).
  • Expected frontend behavior: No dedicated search engine for MVP — structured DB filtering/sorting only. Public, no auth required to view. All prices/commissions shown in PKR.
  • Important states: loading, empty ("no live offers match these filters"), error.
  • Relevant screens: Public/Creator Offer Discovery list, Public Offer detail page.
  • API/backend dependencies: GET /offers (public, filterable) — renamed from GET /campaigns 2026-08-23.
  • Permissions/roles: Public read; apply action requires Creator auth.
  • Edge cases: Post-MVP AI-assisted semantic matching layers on top of this same filtering, doesn't replace it.
  • Source: Technical Architecture/Search Strategy, API/Endpoint Specifications, Business Logic/User Flows.

1.3 Public Offer Detail Page

  • Description: The public page for a single offer/product — name, price (PKR), commission rate, merchant, schema.org markup.
  • User goal (creator): Decide whether to apply. User goal (buyer via a shared link): Land here or get redirected onward to the merchant's Shopify product page.
  • Main user actions: View details; (creator, authenticated) apply.
  • Expected frontend behavior: Carries Product/Offer JSON-LD. This page is informational/discovery, not a checkout entry point — a shared AffiliateLink resolves through GET /go/:slug, which redirects to the merchant's own Shopify store, not to this page's checkout (there is none).
  • Important states: loading, not-found/ended offer.
  • Relevant screens: Public Offer detail.
  • API/backend dependencies: GET /affiliate-links/:slug (public), GET /go/:slug (public redirect + click logging).
  • Permissions/roles: Public.
  • Edge cases: Offer ended — clicks after end date attribute nothing; clicks before end date still honored within the 30-day window.
  • Source: UX/AI Agent & Machine Readability, API/Endpoint Specifications, Business Logic/State Machines.

2. Onboarding & Account Setup

2.1 Role Selection & Signup Branching

  • Description: After the unified signup form, the flow branches based on chosen role(s).
  • User goal: Get to the correct next step (Offer creation vs. offer browsing) without extra clicks.
  • Main user actions: Choose Merchant, Creator, or both.
  • Expected frontend behavior: Minimal-field, low-friction form; contextual hiding of irrelevant fields per role (a digital-goods Merchant never sees a shipping field).
  • Relevant screens: Register, Role Selection (may be same screen).
  • Edge cases: No follower-count floor for Creator eligibility (merit/fit-based, decided).
  • Source: Business Logic/User Flows, Business Logic/User Roles, UX/Interaction Patterns.

2.2 Merchant Onboarding: Swich Billing Connect

  • Description: Merchant connects Swich as their billing method before any offer can go live — replaces the Paddle card-on-file step (Paddle removed) and the interim plain-bank-details-form default (superseded same-day by the Swich decision).
  • User goal: Get set up so periodic billing cycles have a working way to actually charge them.
  • Main user actions: Complete Swich's own onboarding/checkout-connect flow (likely an embedded widget or redirect, exact mechanism unconfirmed pending real Swich integration docs).
  • Expected frontend behavior: Gate: an Offer cannot go draft → live until this is complete. Whether this is an embedded Swich widget (like the old Paddle Checkout iframe) or a redirect flow is Needs clarification — Swich's actual integration pattern isn't confirmed yet.
  • Important states: not started, connected, payment-failed (Swich-reported reason + prompt to update payment method).
  • Relevant screens: Merchant Billing Setup / Settings.
  • API/backend dependencies: merchant_profiles.swich_customer_id (new 2026-08-23, replacing both paddle_customer_id and the interim bank_account_* fields).
  • Permissions/roles: Merchant only, own account.
  • Edge cases: Needs clarification — the exact retry/escalation policy for a failed billing-cycle charge (the old "3 failed Paddle billing attempts over 3 days" rule needs re-mapping against Swich's own failure-webhook behavior, not yet done). Flagged in MVP Scope's Still-Open Items.
  • Source: Product Foundation/MVP Scope, Business Logic/State Machines, Database/Table Specifications, Payments/Money Flow, Payments/Payment Flow.

2.3 Merchant Onboarding: Shopify Store Connect

  • Description: Merchant connects their Shopify store via OAuth/app-install — this is what reports sales back to SellVia. Replaces the universal tracking-snippet install entirely (Shopify-only for MVP).
  • User goal: Get attribution working so sales are tracked and commissions calculated.
  • Main user actions: Click "Connect Shopify Store," authorize the SellVia app in their Shopify admin, confirm the webhook is active.
  • Expected frontend behavior: Offer cannot go draft → live until SellVia verifies the Shopify webhook is registered and active. Also: creating a unique discount code in the merchant's Shopify discount system during offer setup (fallback attribution signal, unchanged in concept from before). This is a simpler frontend step than the old snippet flow — no code to copy-paste, just an OAuth redirect and a confirmation state.
  • Important states: not connected, connecting (mid-OAuth), connected/verified, connection-failed (with troubleshooting copy — e.g. wrong store, permissions declined).
  • Relevant screens: Merchant Offer Setup (Shopify connect step), possibly a dedicated onboarding screen.
  • API/backend dependencies: Shopify OAuth flow; POST /webhooks/shopify-sales (renamed from POST /webhooks/merchant-sales 2026-08-23).
  • Permissions/roles: Merchant only, own offers.
  • Edge cases: Exact Shopify app-install path (public Shopify App Store listing vs. a private/custom app SellVia distributes directly) is explicitly undesignedNeeds clarification, flagged in MVP Scope's Still-Open Items.
  • Source: Payments/Payment Flow, Payments/Money Flow, Business Logic/State Machines, Technical Architecture/Frontend Architecture.

2.4 Creator Onboarding: Swich Payout Setup

  • Description: Creator registers as a Swich payout recipient (payee) to receive commission — replaces Paddle seller onboarding entirely, and supersedes the interim plain-bank-details-form default from earlier the same day.
  • User goal: Be able to actually get paid once commissions accrue.
  • Main user actions: Complete Swich's payee-registration flow — select payout method (bank account, JazzCash, or EasyPaisa) and provide the corresponding details.
  • Expected frontend behavior: A Creator approved for an offer but with incomplete Swich payee registration must not get an active AffiliateLink yet — block link activation entirely rather than accruing unpayable commission (unchanged principle from the Paddle-era design). Offering a choice of payout method (not just bank account) is new relative to the interim default, and is a real UX improvement — most Pakistani creators are more likely to have JazzCash/EasyPaisa than a bank IBAN handy.
  • Important states: not started, complete, incomplete-blocking-link.
  • Relevant screens: Creator Payout Setup / Settings.
  • API/backend dependencies: creator_profiles.swich_payee_id, creator_profiles.payout_method (new 2026-08-23, replacing paddle_seller_id and the interim bank_account_* fields).
  • Permissions/roles: Creator only, own account.
  • Edge cases: Onboarding-incomplete gate is resolved as hard-block (unchanged). Whether any Pakistani-tax-equivalent form (an FBR-relevant declaration, if any) is collected here is Needs clarification — Swich, like the bank-transfer default before it, is not confirmed to auto-collect this the way Paddle's onboarding did (Swich is a processor, not a Merchant of Record — see Payments/Tax Considerations).
  • Source: Edge Cases/User Edge Cases, Technical Architecture/Backend Architecture, Payments/Tax Considerations, Payments/Payout Process.

3. Merchant Module

3.1 Offer Creation & Management (merged with the former "Campaign" concept)

  • Description: A Merchant's product listing and its commission-bearing, applicable listing, in one entity — name, price (PKR), category (digital/physical), commission rate, lifecycle status. There is no separate step to "wrap" a product in a campaign; setting the commission rate and publishing are part of the same creation flow.
  • User goal: List a product with a commission attached and get it in front of creators, in one pass.
  • Main user actions: Create Offer (name, price, category, commission rate), edit Offer, publish (draft → live), pause, resume, end, archive/soft-delete.
  • Expected frontend behavior: Minimal required fields; category selection hides irrelevant fields (e.g., no shipping field for digital). No multi-page wizard, and — since Offer absorbed Campaign — one fewer step than the original two-entity design (create Offer, then separately create a Campaign around it). draft → live blocked until both gates pass: bank settlement setup complete (§2.2) AND Shopify store connected & verified (§2.3). Editing commission rate mid-flight does not require re-consent from already-approved creators (they keep their locked rate, per approval-time locking); new applicants see the new rate.
  • Important states: draft, live, paused, ended; empty ("no offers yet"); loading; error; success (created); each gate's pass/fail state visible before publish is attempted.
  • Relevant screens: Offers list, Create/Edit Offer, Offer detail.
  • API/backend dependencies: GET /offers, POST /offers, PATCH /offers/:id, PATCH /offers/:id/status (all renamed from /campaigns/... 2026-08-23).
  • Permissions/roles: Merchant (own offers only); Admin (any, for moderation/vetting override).
  • Edge cases: Paused offers keep honoring in-flight attribution within the 30-day window, accept no new applications; ended offers stop attributing new clicks immediately but honor pre-end clicks within the window; high-commission/high-risk offers require Admin vetting before going live (thresholds undefined — Needs clarification); product image auto-fetch from a URL is a deferred v2 convenience — manual upload only for MVP.
  • Source: Business Logic/Domain Model, Business Logic/State Machines, Business Logic/Business Rules, Database/Table Specifications, Technical Architecture/File Storage, Operations/Admin Panel.

3.2 (Retired — merged into §3.1, 2026-08-23)

The former "Offer Management" and "Campaign Creation & Management" were two separate sections describing a two-entity model. As of the 2026-08-23 revision there is one entity (Offer) and one section (§3.1) — this number is intentionally left as a pointer rather than reused, so cross-references elsewhere in the docs that still say "§3.2" resolve here.

3.3 Application Review

  • Description: Merchant reviews creator applications to their offers and approves/rejects.
  • User goal: Choose the right creators for the offer.
  • Main user actions: View applicant's audience/niche/engagement data (+ AI-generated fit summary), approve, reject.
  • Expected frontend behavior: Approval immediately surfaces the generated AffiliateLink to the Creator (real-time-feeling, not delayed-email-only) — described as one of the product's core "trust moments."
  • Important states: pending, approved, rejected; empty ("no applications yet"); pending-count indicator.
  • Relevant screens: Applications list (per offer), Application review card/detail.
  • API/backend dependencies: POST /offers/:id/applications (creator-initiated), GET /offers/:id/applications, PATCH /applications/:id (approve/reject, triggers AffiliateLink creation) — all renamed from /campaigns/... 2026-08-23.
  • Permissions/roles: Merchant (own offers only); Admin (moderation override).
  • Edge cases: Rejected applicants cannot resurrect the old application, only submit a new one; whether merchants see aggregate creator performance platform-wide or only the applicant's own submitted stats is unresolved (Needs clarification); self-dealing applications blocked server-side before reaching this queue.
  • Source: Business Logic/State Machines, Business Logic/Permission Matrix, UX/Components, Business Logic/Business Rules.

3.4 Sales Visibility

  • Description: Merchant's view of sales reported and attributed to their offers.
  • User goal: See what's selling and confirm commissions are calculating correctly.
  • Main user actions: View sale list, filter/sort, view acceptance status.
  • Expected frontend behavior: Shows acceptance_status (accepted/rejected). Amounts in PKR. Never served from cache — always live.
  • Important states: accepted, rejected (flagged for Admin review, not silently dropped), empty, loading.
  • Relevant screens: Sales list (Merchant), Sale detail/receipt.
  • API/backend dependencies: GET /sales (scoped to own).
  • Permissions/roles: Merchant (own only); Admin (any).
  • Edge cases: A merchant under-reporting sales is a fraud vector the external-tracking model introduced — flagged/reconciled at the platform level, not something the merchant UI directly exposes.
  • Source: API/Endpoint Specifications, Security/Fraud Prevention, Technical Architecture/Caching Strategy.

3.5 Billing (Periodic Merchant Billing — Swich)

  • Description: Merchant's billing-cycle history and Swich billing-method management — a Swich-generated invoice/payment-link per cycle, webhook-confirmed, not a Paddle charge and not a manual admin-tracked bank transfer.
  • User goal: Understand what's owed and confirm payment goes through smoothly each cycle.
  • Main user actions: View billing cycle history/totals, complete payment through Swich when a cycle closes, update billing method.
  • Expected frontend behavior: Monthly billing cycles (unchanged cadence). On a cycle closing, SellVia's backend generates a Swich invoice/payment request for the total owed; the merchant completes it through Swich's checkout (card, bank transfer, JazzCash, or EasyPaisa); a Swich webhook confirms it and the cycle flips to charged automatically — no admin manually checking a bank statement. Retry/escalation policy for a failed charge is not yet fully designed (see §2.2's edge case) — the old "3 failed billing attempts → auto-pause" rule needs re-mapping against Swich's own failure-webhook behavior, which isn't confirmed yet.
  • Important states: open, pending_charge, charged, failed (with a way to see why, from Swich's reported reason, and what to do).
  • Relevant screens: Billing Cycles / Billing History, Billing Settings.
  • API/backend dependencies: GET /billing-cycles (scoped to own, now surfacing swich_invoice_id/swich_payment_reference).
  • Permissions/roles: Merchant (own only).
  • Edge cases: Failed billing accumulates rather than losing sales; creator commission for that cycle stays unpaid until resolved (bill-first-then-pay, unchanged principle).
  • Source: Payments/Payment Flow, Payments/Money Flow, Business Logic/State Machines, Database/Table Specifications.

3.6 Refund Credit Request

  • Description: Merchant requests a billing credit for a sale that was already tracked/billed/paid out, when their own customer got a refund on the merchant's Shopify store.
  • User goal: Not be billed for a sale that was refunded to the end customer.
  • Main user actions: Submit a credit request for a specific sale, optionally partial.
  • Expected frontend behavior: Capped at 5 credits/calendar month; proportional credit for partial refunds; beyond the cap, no further credit (clear messaging why). Amounts in PKR.
  • Important states: credits-remaining-this-month counter, submitted, applied-to-next-cycle, cap-reached (disabled state with explanation).
  • Relevant screens: Sale detail (Merchant) → Request Refund Credit action; possibly a dedicated Refund Requests list.
  • API/backend dependencies: No explicit endpoint named in Endpoint Specifications — Needs clarification ("UI/API for how a merchant actually submits a credit request — not yet designed").
  • Permissions/roles: Merchant (own sales only).
  • Edge cases: Creator commission is never clawed back regardless — SellVia absorbs the cost within the cap.
  • Source: Payments/Refund Handling, Payments/Money Flow.

3.7 Merchant Profile / Business Settings

  • Description: Business name, category, and account-level settings.
  • User goal: Keep business info accurate.
  • Main user actions: Edit business name/profile fields.
  • Relevant screens: Merchant Settings / Business Profile.
  • API/backend dependencies: merchant_profiles table (last-write-wins conflict resolution, not event-sourced).
  • Permissions/roles: Merchant, own profile only.
  • Source: Business Logic/Domain Model, Database/Database Design.

4. Creator Module

4.1 Offer Discovery (Authenticated)

  • Description: Same underlying discovery/filter system as the public browse page, in-app for logged-in creators applying.
  • User goal: Find offers that fit their audience/niche.
  • Main user actions: Filter (category, commission range, niche), sort, apply.
  • Expected frontend behavior: Post-MVP: AI similarity ranking layered on top of filters (timing unresolved — Needs clarification).
  • Important states: loading, empty, already-applied indicator per offer.
  • Relevant screens: Creator Discovery/Browse.
  • API/backend dependencies: GET /offers (public endpoint, same as marketing-site browse, called in an authenticated context here).
  • Permissions/roles: Creator (apply action); public (browse).
  • Source: Business Logic/User Flows, Technical Architecture/Search Strategy.

4.2 Application Submission

  • Description: Creator applies to a specific offer, with audience info attached.
  • User goal: Get approved to promote a product.
  • Main user actions: Submit application (audience snippet — niche, audience size, engagement rate).
  • Expected frontend behavior: One application per (offer, creator) pair — duplicate attempt returns a clear 409 error, not a generic failure. Rate-limited per Creator account to prevent spam-applying.
  • Important states: submitting, submitted/pending, error (duplicate, self-dealing block, rate-limited).
  • Relevant screens: Offer detail (Apply action), My Applications list.
  • API/backend dependencies: POST /offers/:id/applications (renamed from /campaigns/:id/applications 2026-08-23).
  • Permissions/roles: Creator only.
  • Edge cases: Self-dealing block (own offer, if dual-role); audience/niche data is self-reported and currently unverifiable (open fraud-implication question).
  • Source: Business Logic/Business Rules, Database/Constraints, Security/Rate Limiting, Edge Cases/Creator Edge Cases.

4.3 My Applications

  • Description: Creator's view of their own application statuses.
  • User goal: Track where each application stands.
  • Expected frontend behavior: pending / approved / rejected states clearly shown; whether/how a rejection reason is communicated is unresolved (Needs clarification).
  • Relevant screens: My Applications list.
  • API/backend dependencies: Scoped read of applications (no dedicated endpoint explicitly named beyond the offer-scoped one — Needs clarification on a creator-facing "my applications across all offers" endpoint).
  • Permissions/roles: Creator, own only.
  • Source: Business Logic/State Machines, Business Logic/Notification Logic.
  • Description: The unique trackable link (+ discount code) issued on approval.
  • User goal: Get and share the promotional link/code.
  • Main user actions: Copy link, copy discount code, share.
  • Expected frontend behavior: The "Get Link" moment should feel like a small, clear payoff, given how central it is to the product's trust story. Disclosure-nudge template shown at this moment (fixed legal text, not AI-generated). Only one link per approved application (no regenerating to obscure attribution).
  • Important states: link generated/zero clicks yet (calm empty state, not "broken"), active, offer-ended (link stops attributing new activity).
  • Relevant screens: My Links list, Link detail (click/cart/purchase timeline).
  • API/backend dependencies: GET /affiliate-links/:slug (public resolution endpoint); link data scoped to the owning creator for the dashboard view.
  • Permissions/roles: Creator, own links only.
  • Source: UX/Components, Business Logic/Domain Model, Business Logic/Business Rules, Payments/Payment Flow.

4.5 Earnings / Wallet

  • Description: Running balance of accrued-but-not-yet-paid-out commission, plus payout history.
  • User goal: Know how much they've earned and when they'll get paid.
  • Main user actions: View balance, view progress toward the payout threshold, view payout history.
  • Expected frontend behavior: Balance only includes commissions whose BillingCycle has reached charged — pre-billing commission is "owed" but not yet in the spendable/displayed wallet balance. Never cached — always live, computed directly from SellVia's own ledger — wallet_balance_cents is authoritative, not synced from Swich's account balance (Swich is the execution rail that moves the money once a payout is due; it doesn't hold SellVia's ledger). All figures in PKR only — the multi-currency conversion-display concern from the earlier USD/EUR/GBP design no longer applies.
  • Important states: accruing (below threshold), threshold-crossed (payout pending), processing, paid, failed-retrying.
  • Relevant screens: Earnings/Wallet dashboard, Payout history detail.
  • API/backend dependencies: GET /payouts (scoped to own); creator_profiles.wallet_balance_cents.
  • Permissions/roles: Creator, own only.
  • Edge cases: No client-facing "trigger payout" action (fully automatic/threshold-based, though "automatic" now means an admin-actioned bank transfer rather than a processor API call — see §3.5); one-time manual below-threshold payout allowed only on account closure (proposed default); a refund after a creator has already been paid is a real, accepted platform loss, never clawed back from the creator. The $50 payout threshold needs re-specifying in PKR — not yet done, flagged as an open item.
  • Source: Payments/Wallet Design, Payments/Payout Process, Business Logic/State Machines, Edge Cases/Payment Edge Cases.

4.6 Creator Profile Settings

  • Description: Niche, audience size, engagement rate, and payout account status.
  • User goal: Keep profile accurate so merchants can evaluate fit.
  • Main user actions: Edit niche/audience info.
  • Relevant screens: Creator Settings / Profile.
  • API/backend dependencies: creator_profiles table.
  • Permissions/roles: Creator, own profile only.
  • Edge cases: Whether engagement_rate is self-reported vs. platform-calculated is an open fraud-relevant question — Needs clarification before deciding if this field is editable or read-only/derived.
  • Source: Business Logic/Domain Model, Edge Cases/Creator Edge Cases.

5. Admin Module

All Admin screens live under a fully separate /admin/* namespace, never exposed in regular Merchant/Creator navigation. Single flat Admin role for MVP (no tiering).

5.1 Moderation Queue

  • Description: Flagged sales/applications/accounts from rules-based fraud detection, awaiting human review.
  • User goal (Admin): Resolve flags — clear false positives, act on real fraud.
  • Main user actions: Review flag reason (velocity, self-referral, conversion outlier, device fingerprinting, merchant under-reporting pattern), clear or act (suspend, reverse a sale, ban).
  • Expected frontend behavior: Every action logged to the Audit Log (who, what, outcome).
  • Important states: flagged/unreviewed, cleared, actioned.
  • Relevant screens: Moderation Queue, Flagged Item detail.
  • API/backend dependencies: GET /admin/flagged.
  • Permissions/roles: Admin only.
  • Source: Operations/Moderation, Security/Fraud Prevention, Business Logic/Permission Matrix.

5.2 Offer Vetting

  • Description: High-commission or high-risk offers awaiting approval before going live.
  • User goal: Approve/reject before a risky offer reaches creators.
  • Main user actions: Approve, reject.
  • Relevant screens: Offer Vetting Queue.
  • API/backend dependencies: POST /admin/offers/:id/vet (renamed from /admin/campaigns/:id/vet 2026-08-23).
  • Permissions/roles: Admin only.
  • Edge cases: Exact vetting trigger thresholds undefined — Needs clarification.
  • Source: Operations/Admin Panel, Business Logic/Business Rules.

5.3 User Management

  • Description: View/suspend Merchant or Creator accounts; view a user's history for support/moderation purposes only.
  • Main user actions: View user detail, suspend/ban.
  • Expected frontend behavior: Suspension instantly revokes the user's sessions.
  • Relevant screens: User Management list, User detail.
  • API/backend dependencies: POST /admin/users/:id/suspend.
  • Permissions/roles: Admin only.
  • Edge cases: No formal appeals process designed yet (handled case-by-case via support) — Needs clarification.
  • Source: Operations/Admin Panel, Operations/Moderation, Security/Session Management.

5.4 Refund / Dispute Handling

  • Description: Manual refund-credit review. Chargeback-evidence submission (originally scoped for Paddle disputes) needs re-scoping against Swich — Swich is a payment processor with its own dispute-handling process for card transactions specifically, but whether it covers bank-transfer/JazzCash/EasyPaisa-settled amounts the same way a card chargeback would is unconfirmed.
  • Main user actions: Approve/deny refund credit requests.
  • Important states: SellVia absorbs a merchant's first 5 lost disputes (lifetime counter) — this rule was written for a Paddle-chargeback world; whether it still applies as-is under Swich is Needs clarification.
  • Relevant screens: Refund/Dispute Handling queue.
  • API/backend dependencies: Not explicitly named in Endpoint Specifications — Needs clarification.
  • Permissions/roles: Admin only.
  • Edge cases: Who submits any dispute evidence, and to whom (SellVia vs. Swich vs. Swich-on-SellVia's-behalf), is unresolved — Needs clarification.
  • Source: Payments/Chargebacks, Payments/Refund Handling, Operations/Admin Panel.

5.5 Reconciliation Review

  • Description: Surfaces mismatches between internal records and Swich's own transaction records, for manual investigation. (Previously scoped against Paddle's records; the interim bank-transfer default would have had no processor API to reconcile against at all — Swich restores that.)
  • Main user actions: Review flagged mismatch, investigate, resolve.
  • Important caveat: Reconciliation can verify the billing/payout legs against Swich's transaction records (once that integration exists), but it can no longer independently confirm the underlying sale happened as reported — that trust still rests entirely on Fraud Prevention's Shopify-webhook-reporting checks, unchanged from the external-tracking model generally.
  • Relevant screens: Reconciliation Review queue.
  • API/backend dependencies: Endpoint not explicitly named — Needs clarification; likely a scheduled job comparing SellVia's ledger against Swich's transaction-list API once that's integrated.
  • Permissions/roles: Admin only.
  • Source: Payments/Reconciliation, Operations/Admin Panel.

5.6 Waitlist → Beta Invitation Management

  • Description: Manages the Private Beta cohort (currently capped 10–25, manually curated for the first cohort, fully automatic/signup-order after). Now implicitly scoped to Pakistani applicants only, since the market is Pakistan-only for MVP.
  • Main user actions: Review waitlist, curate/invite first cohort, monitor automatic invitations thereafter.
  • Relevant screens: Waitlist Management.
  • Permissions/roles: Admin only.
  • Edge cases: Beachhead niche/vertical within Pakistan (beyond the geography resolution itself) still undecided — Needs clarification.
  • Source: Product Foundation/Product Roadmap, Operations/Admin Panel.

5.7 At-Risk New Users View

  • Description: Accounts that hit the 48-hour churn threshold without completing their core activation action (Merchant: publish first offer; Creator: submit first application).
  • User goal: Give the founder/Admin visibility into who's stalling, distinct from the fraud queue.
  • Relevant screens: At-Risk Users view (within Admin Panel).
  • API/backend dependencies: activation_nudges table.
  • Permissions/roles: Admin only.
  • Source: Analytics/Activation, Aha Moment & Churn Signals, Operations/Admin Panel.

5.8 Founder AI Command Console

  • Description: Founder-only natural-language interface over the entire Admin surface — every tool wraps an existing, already-permission-checked Admin API endpoint; never raw DB access.
  • User goal: Query/act on admin data without navigating multiple screens.
  • Main user actions: Ask a question (read, executes directly), issue a write command (requires explicit confirmation, every time, no exceptions), request a product-change spec (drafted only, never auto-executed/deployed).
  • Expected frontend behavior: Fail-closed on ambiguity — asks for clarification rather than guessing. Every AI-console action logged with initiated_via: ai_console.
  • Important states: answering, awaiting-confirmation (for write actions), executed, clarification-needed.
  • Relevant screens: AI Command Console (chat-style interface).
  • Permissions/roles: Admin/Founder only.
  • Edge cases: Whether this ships MVP or post-MVP is an explicit open call — Needs clarification.
  • Source: Operations/Founder AI Command Console, Operations/Live Production Access for Support (Command Console), Database/Audit Log Design.

5.9 Support Tooling (Console-Assisted)

5.10 Admin Analytics (Marketplace Health, P&L, Unit Economics)

  • Description: Founder/Admin dashboards for marketplace health, funnels, time-to-payout, monthly P&L, unit economics, AI/token cost. All monetary figures in PKR.
  • Main user actions: View KPI trends, review the automated monthly P&L report, review per-feature AI cost.
  • Important states: finalized vs. draft P&L report (recommend a "finalized" flag so historical reports don't silently change).
  • Relevant screens: Admin/Founder Dashboard (marketplace health + funnels), Monthly P&L report, Unit Economics view.
  • API/backend dependencies: monthly_pnl_reports, ai_usage_events, infra_costs tables; get_pnl(month) console tool. monthly_pnl_reports.paddle_fees_cents is renamed swich_fees_cents — Swich's own transaction fees (rate unconfirmed pending real signup) are a real cost line, unlike the near-zero cost the interim bank-transfer default would have had.
  • Permissions/roles: Admin only.
  • Source: Analytics/Dashboards, Analytics/KPIs, Analytics/Automated Monthly P&L, Analytics/Unit Economics (Revenue vs Cost per User), Analytics/AI Token Usage Tracking.

6. Shared Dashboard Analytics (Merchant & Creator)

6.1 Merchant Analytics

  • Description: Per-merchant offer performance: clicks, conversion, sales, spend; exportable reports. All figures in PKR.
  • Expected frontend behavior: Simple charts, no data-viz flourishes ("clarity over excitement"); heavy/slow exports run as async jobs (notification on completion, not a spinner).
  • Relevant screens: Merchant Dashboard home, Offer performance detail, Export flow.
  • API/backend dependencies: POST /jobs/export, GET /jobs/:id.
  • Permissions/roles: Merchant, own data only.
  • Source: Analytics/Dashboards, Technical Architecture/Async Job Pattern & Idempotency.

6.2 Creator Analytics

  • Description: Per-creator link performance: impressions/clicks/sales, earnings trend toward the payout threshold.
  • Relevant screens: Creator Dashboard home.
  • Permissions/roles: Creator, own data only.
  • Source: Analytics/Dashboards.

7. Customer Support (User-Facing)

7.1 Support Contact

  • Description: In-app support link/contact form for logged-in Merchants/Creators; email support otherwise.
  • User goal: Get help when something's wrong (payout delay, rejected application, suspected double charge, disputed clawback).
  • Expected frontend behavior: Clear, specific error/status copy so common cases (e.g., normal Swich settlement/payout processing window) don't look like failures. Exact expected window under Swich is Needs clarification — the original "2–7 day" figure assumed Paddle's own rail and hasn't been re-confirmed against Swich's.
  • Relevant screens: Support/Help contact form or link (likely footer/nav-level, not a full dashboard section).
  • Permissions/roles: Any authenticated user.
  • Edge cases: No formal SLA — founder-handled through Private Beta.
  • Source: Operations/Customer Support Flows, Operations/Support Tiers.

7.2 Account Deletion Request

  • Description: User-initiated account deletion with a 14-day cancellable grace period.
  • User goal: Delete their account/data.
  • Main user actions: Request deletion, cancel within grace period.
  • Expected frontend behavior: Clear confirmation step naming what happens (PII anonymized, financial-chain skeleton retained, sessions revoked, product images removed immediately with placeholders shown on any referencing offer).
  • Important states: requested/counting-down, cancelled, processing, completed.
  • Relevant screens: Account Settings → Delete Account flow.
  • API/backend dependencies: Async deletion job (Async Job Pattern).
  • Permissions/roles: Any authenticated user, own account only.
  • Source: Security/Data Retention Policy Engine.

7.3 Data Disclosure Notices

  • Description: Plain-language notices at the point of data collection (signup, before bank details are collected, before AI-matching use of profile data) — not buried in a ToS.
  • Expected frontend behavior: Short, contextual, timed notices woven into the relevant flow (signup form, bank-details step, profile-completion step for creators).
  • Relevant screens: Embedded in Signup, Bank Details Setup, Creator Profile Settings — not a standalone screen.
  • Source: Security/Data Inventory & Disclosure.

Feature-Level "Needs Clarification" Summary

For quick reference, every open item flagged above:

  1. Admin role's full formal scope (used broadly throughout but never explicitly ratified).
  2. Waitlist signup endpoint not explicitly specified.
  3. Exact retry/escalation policy for a failed Swich billing-cycle charge (§2.2/§3.5) — the old Paddle "3 failed attempts" rule needs re-mapping against Swich's own failure-webhook shape, not yet confirmed.
  4. Exact Shopify app-install path — public App Store listing vs. private/custom app (§2.3).
  5. Application-rejection notification content/whether a reason is shown.
  6. Real-time vs. digest cadence for "sale made" / merchant notifications.
  7. Exact merchant "milestone reached" thresholds.
  8. Whether merchants see platform-wide aggregate creator performance or only per-applicant stats.
  9. High-commission/high-risk offer vetting thresholds.
  10. UI/API for merchant refund-credit request submission.
  11. Whether the Paddle-era "SellVia absorbs first 5 lost disputes" rule still applies as-is under Swich, and who submits any dispute evidence to whom (§5.4).
  12. Formal account-suspension appeals process.
  13. Timing of AI-based creator↔offer matching (MVP vs. post-MVP).
  14. Whether engagement_rate is self-reported or platform-calculated.
  15. Whether Founder AI Command Console ships MVP or post-MVP.
  16. Whether support-ticket-context tooling needs dedicated UI or lives inside User Management/AI Console.
  17. The $50 payout threshold needs re-specifying in PKR (§4.5).
  18. Swich's exact API shapes, pricing, and MVP-scale onboarding requirements — nothing here is confirmed, it's all a working draft pending a real signup/integration conversation (§2.2, §2.4, §3.5, §5.10 — every Swich mention across this doc).
  19. Expected Swich settlement/payout window to communicate in support copy (§7.1).
  20. Whether an FBR-relevant tax form/declaration needs collecting at Creator onboarding (§2.4) — Swich, like the interim bank-transfer default before it, is not a Merchant of Record and doesn't auto-collect this.
  21. Beachhead niche/vertical within Pakistan (geography itself is resolved; category focus within it is not).

Resolved since the last revision (2026-08-07), no longer open:

  • Whether Offer needs its own entity vs. one-campaign-per-offer — resolved: no Campaign entity at all.
  • Merchant Paddle requirement post-reversal — moot, Paddle removed.
  • Exact UX for the tracking-snippet install step — resolved: Shopify OAuth/webhook connect, not a snippet.
  • Lime-as-text WCAG AA contrast — resolved: verified compliant, and Gray 02 (the actual failure) corrected.
  • Payment processor — resolved same day: Swich, replacing the brief interim manual-bank-transfer default.

Still outstanding, unrelated to the 2026-08-23 revision:

  • Alt-text field missing from product image schema.

Cross-References

  • Screens implementing these features: SCREEN_INVENTORY.md
  • Navigation/routes these features live at: SITE_MAP.md

References