| # Qx-SmartLedger β Product & Architecture Roadmap |
|
|
| > Status: forward-looking, to start **after Audry validates a production-grade MVP**. This is greenfield |
| > for monetization and multi-tenancy β nothing in sections 2β9 is built yet. Dev-context only. |
|
|
| Decisions captured (product): |
| - Self-serve **online payments** for Hustler / Pro / Mogul; **Incubator is sales-led** (talk to sales). |
| - **Per-seat** pricing is a cross-cutting dimension (operators / staff). |
| - Payment rails: **Zimbabwe mobile money first (Paynow β EcoCash / OneMoney / card)** + a **pan-African |
| aggregator (Flutterwave / Paystack)** next, behind one pluggable provider interface. |
|
|
| --- |
|
|
| ## 1. Current baseline (what exists today) |
| - WhatsApp Cloud API β **Render relay** β Meta; **Gemini** multimodal (intent / vision / translate / |
| codegen / coach) + **AssemblyAI** ASR; **Firestore** + Firebase **Storage**. |
| - Data model: `users/{phone}/<subcollection>` β `transactions, stock_batches, customers, |
| price_overrides, temp_*, context`. Approval / profile doc at `users/{+mobile}` |
| (`status, currency, business_name, wa_name, distill_consent`). |
| - **Wart to fix first:** the profile doc is keyed `+mobile` but ledger subcollections are keyed `mobile` |
| (no `+`). Must be normalized before any multi-tenancy work. |
| - `distillation_examples` capture is live (`distill.py`, `scripts/export_distillation.py`). |
| - **No tiers, payments, roles, or orgs yet.** |
|
|
| ## 2. Tiers / personas |
| 1. **Hustler** (free, self-serve): one trader, one shop, core bookkeeping (text / voice / image), basic |
| reports, capped history / usage. |
| 2. **Captain / Pro** (paid, self-serve, online pay): one business, full features β PDF receipts, period |
| reports, business coach, deeper history, exports, multiple **operator seats**. |
| 3. **Mogul** (paid, self-serve, online pay): **multiple shops under one owner** β per-shop ledgers, |
| consolidated cross-shop reporting, per-shop operators, inter-shop transfers. Price = per-business base |
| + per-extra-shop + per-seat. |
| 4. **Incubator / Organisation** (sales-led, invoiced): an org tracking many independent businesses it |
| incubates β cohort dashboard, per-business progress, aggregate analytics, **consent-gated read |
| access**, program / cohort grouping, staff roles. Per-seat across the cohort. |
|
|
| ## 3. Core architecture change β accounts & multi-tenancy |
| The phone-keyed model cannot express multi-shop or orgs. Introduce explicit entities (top-level |
| collections; ledgers move off the phone key): |
| - `businesses/{business_id}` β the ledger owner (`name, currency, tier, owner_member_id, org_id?, |
| created_at`). Ledgers live at `businesses/{business_id}/{transactions, stock_batches, customers, ...}`. |
| - `members/{member_id}` β a person (`phone_hash, display_name`); identified by WhatsApp number. |
| - `memberships/{id}` β `member_id Γ business_id Γ role(owner|manager|operator|viewer) Γ status`. Drives |
| access **and** seat counting. |
| - `organisations/{org_id}` β incubator / parent (`name, admins[], subscription`); businesses reference |
| `org_id` and carry a per-business consent flag for org visibility. |
| - **Message routing:** inbound phone β resolve member β active business context (default + a |
| `switch shop` command for Mogul / operators; sticky in `context`). |
| - **Backwards-compat:** today's single user = 1 member + 1 business; a migration creates a `business_id`, |
| moves / dual-reads the subcollections, and fixes the `+mobile` vs `mobile` key. |
|
|
| ## 4. Access control & context resolution |
| - Role matrix: **owner** (all incl. billing), **manager** (txns + reports, no billing), **operator** |
| (record txns, limited reads), **viewer** (read-only β used by incubators). |
| - A phone in multiple businesses β "Which shop?" picker / `switch to <shop>`; active context stored per |
| member. |
| - Incubator access = a **viewer** membership into each incubated business, granted on the business |
| owner's opt-in consent, revocable. |
|
|
| ## 5. Payments & billing |
| - **Pluggable `PaymentProvider` interface.** Phase 1: **Paynow** (EcoCash / OneMoney / card, Zimbabwe). |
| Phase 2: **Flutterwave / Paystack** (mobile money + cards across KE / NG / GH / ZA). Provider webhooks |
| β subscription state; the existing relay is for WhatsApp only, not for payment callbacks. |
| - **Billing model:** per-business base (Hustler free / Pro / Mogul) + per-extra-shop (Mogul) + |
| **per-seat** operators. **Incubator = sales-led** org contract (manual / invoiced), per-seat across the |
| cohort. |
| - **Subscription state** on `businesses.subscription` / `organisations.subscription`: |
| `plan, status(active|trial|past_due|canceled), renews_at, seats, provider_refs`. Trials, grace, |
| dunning via WhatsApp nudges. |
| - **WhatsApp-native upgrade flow:** "upgrade" β provider checkout link or mobile-money push β webhook |
| confirms β tier flips β confirmation + payment receipt. |
| - **Feature gating:** a central `entitlements(business)` map (tier β features: receipts, report depth, |
| coach, vision, # shops, # seats, history window, exports, API). Enforce at command entry; gated |
| actions return a friendly upsell, never a hard error. |
|
|
| ## 6. Internal admin interface (ours β already exists; design its data contracts) |
| The admin is a separate app over Firestore / Storage. It will manage: |
| - Approvals & onboarding (replaces the manual `users/{+mobile}.status` flow). |
| - Businesses / orgs CRUD; tier / subscription overrides; seat management; comp / trial grants. |
| - Members & memberships; role assignment; **read-only** support impersonation. |
| - Billing ops: subscriptions view, manual incubator invoices, refunds, dunning state. |
| - Cohort / incubator management: create org, attach businesses, progress dashboards. |
| - **Training-data management:** review `distillation_examples`, verdict / label QA, redaction, export |
| runs (wraps `scripts/export_distillation.py`), consent audit. |
| - Feature flags & analytics (usage, retention, MRR, per-tier funnels). |
| - Contract: stable Firestore schemas + admin-only callable functions; the bot path never sees billing |
| secrets. |
|
|
| ## 7. Cross-cutting |
| Migration (phased, dual-read), data integrity, per-business currency, audit log, per-tier rate limits, |
| per-member data export / delete (ties to `distill_consent`), observability / metrics. |
|
|
| ## 8. Phased delivery (post-MVP) |
| - **P0 Foundation** β normalize account keys; add `business_id` + `memberships`; migrate existing users |
| 1:1; no user-visible change. |
| - **P1 Pro + payments** β Paynow rails, `entitlements` / gating, WhatsApp upgrade flow, admin |
| subscription management. |
| - **P2 Mogul** β multi-shop model, switch-shop UX, consolidated reports, per-shop seats. |
| - **P3 Incubator** β org entity, consent-based viewer access, cohort dashboards, sales-led billing; |
| add pan-African rails (Flutterwave / Paystack). |
| - **P4 Hardening** β dunning, analytics, training-data admin tooling, exports. |
|
|
| ## 9. Where it lands when built (reuse existing) |
| - New modules: `accounts.py` (entities + membership + context resolution), `billing.py` |
| (`PaymentProvider` + webhooks), `entitlements.py` (tier β feature gating). |
| - `main.py`: resolve member β business context at message entry; gate features; payment / upgrade & |
| switch-shop commands. `is_user_approved` (main.py:713) becomes a membership lookup; `_vendor_profile` |
| becomes a business-profile lookup. |
| - `utility.py`: ledger reads / writes re-pointed from `users/{mobile}` β `businesses/{business_id}` via an |
| accessor that hides the key (one change point feeds all `*_transaction` / stock / customer helpers). |
| - Unchanged: relay / `whatsapp_client.py`. `distill.py` + `scripts/export_distillation.py` feed the |
| admin's training-data module. |
|
|
| --- |
|
|
| ## 10. Cost per user & pricing model |
|
|
| > Estimates as of **mid-2026** from public pricing (sources at bottom). The two model IDs we use |
| > (`gemini-3.1-flash-lite`, `gemini-robotics-er-1.6-preview`) are priced here at their **Flash-Lite / |
| > Flash-class** equivalents β verify against the live billing page before locking pricing. All figures |
| > USD. |
|
|
| ### 10.1 Unit rates by service |
| | Service | Unit | Rate | |
| |---|---|---| |
| | Gemini Flash-Lite (text intent / translate / codegen / coach) | 1M input / 1M output tok | **$0.10 / $0.40** (batch $0.05 / $0.20) | |
| | Gemini vision (image in, ER-class) | per image (~1.1k input tok + prompt) | **~$0.0002β0.0004** | |
| | AssemblyAI Universal ASR | per minute | **$0.0025** ($0.15/hr) | |
| | Deepgram Aura TTS (voice replies, capped ~500 chars) | per 1k chars | **~$0.015** β ~$0.004β0.008/reply | |
| | WhatsApp **service reply** (inside the 24-h user window β our normal mode) | per message | **$0.00 (free)** | |
| | WhatsApp **utility template** (business-initiated, "Rest of Africa" incl. +263) | per message | **<$0.01β0.03** | |
| | Firestore | 100k reads / 100k writes | **$0.06 / $0.18** (deletes $0.02) | |
| | Firebase Storage (distillation media, receipts) | GB-month / egress GB | **~$0.026 / ~$0.12** | |
| | Render relay + app host | flat / month | ~$7β50 (amortized across all users) | |
|
|
| ### 10.2 Cost per interaction (one bookkeeping action) |
| | Modality | Extra services beyond Firestore | Est. cost | |
| |---|---|---| |
| | **Text** | Gemini translate (most msgs) + ~40% LLM intent (60% deterministic = free) | **~$0.0002β0.0004** | |
| | **Voice** | + ASR (~$0.0006 / 15-s note) + **TTS reply (~$0.004β0.008)** + text pipeline | **~$0.005β0.009** | |
| | **Image** | + Gemini vision (~$0.0003) + text pipeline | **~$0.0005** | |
| | Firestore per action (~30 reads + ~6 writes + distill writes) | β | ~$0.00003 | |
|
|
| **The reply path is mostly free on WhatsApp** because the bot is reactive (service messages inside the |
| 24-h window). The two real swing costs are **TTS for voice** and **any business-initiated templates** |
| (expiry nudges, dunning) β keep those minimal. |
|
|
| ### 10.3 Monthly cost per active user |
| | Profile | Assumptions | Est. infra cost / month | |
| |---|---|---| |
| | **Light Hustler** (text-first) | ~120 actions, mostly text, a few utility nudges | **~$0.10β0.20** | |
| | **Voice-heavy Hustler** | ~150 actions, ~50% voice **with spoken replies** | **~$0.40β0.60** (TTS dominates) | |
| | **Pro / heavy** | ~400 actions, reports + coach + codegen, 3 seats | **~$0.60β1.50** | |
| | + cumulative distillation media (images/audio kept) | grows over time | ~$0.002β0.02 / user / mo | |
| | + amortized relay/app host @ ~1k users | flat Γ· users | ~$0.01β0.03 / user | |
|
|
| **Fully-loaded: ~$0.15β0.60 / active user / month typical; up to ~$1.50 for heavy or voice-with-TTS users.** |
|
|
| ### 10.4 Suggested pricing (USD/month; charge local mobile-money equivalent) |
| | Tier | Price | Includes | Est. cost | Gross margin | |
| |---|---|---|---|---| |
| | **Hustler** | **Free** | 1 shop, ~100 actions/mo, text + voice, basic reports; PDF + coach as teasers | $0.10β0.30 | acquisition (loss-leader) | |
| | **Captain / Pro** | **$3β5** | full features, 1 shop, β€3 seats, PDF receipts + reports, coach, exports | $0.30β0.80 | **~80β90%** | |
| | **Mogul** | **$9β15 base** + **$3β5 / extra shop** + **$1β2 / extra seat** | multi-shop, consolidated reporting | scales with shops | ~80% | |
| | **Incubator** | **sales-led**: ~$2β4 / tracked business / mo + per-seat for org staff | cohort dashboards, consent-gated viewer access | low per business | high (contract) | |
|
|
| Pricing notes: |
| - **Annual plan** β 10Γ monthly (2 months free) to improve retention and cash flow. |
| - **Cap the free tier's voice/TTS and coach** usage β that is where a free user can actually cost money; |
| default voice replies to **text-first** and make spoken replies a Pro perk. |
| - Even at a **$1/mo** entry point margins stay 50β85%; $3β5 Pro is comfortably **>80%** gross. |
|
|
| ### 10.5 Cost-control levers (already partly in place) |
| - **Deterministic parsing first** (β60% of writes skip the LLM) β keep widening it. |
| - **Stay reactive** on WhatsApp (free service window); batch/limit business-initiated templates. |
| - **Gemini batch mode (β50%)** for all non-realtime work (distillation re-scoring, exports, reports). |
| - **Text-first replies**; shortest viable TTS; cheapest TTS vendor. |
| - **The distilled student model is the strategic lever**: once trained on the captured dataset |
| (`distillation_examples`), it can self-host and drive the **marginal AI cost toward ~$0**, turning |
| today's ~$0.20β0.60/user into mostly fixed compute β the main reason to capture the data now. |
|
|
| > Sources (mid-2026): Gemini API pricing (ai.google.dev/gemini-api/docs/pricing), AssemblyAI pricing |
| > (assemblyai.com), WhatsApp Business Platform pricing |
| > (developers.facebook.com/documentation/business-messaging/whatsapp/pricing), Firestore/Storage |
| > (Google Cloud pricing). Re-verify before setting public prices. |
|
|