System architecture
How the pieces connect.
The big picture
Customers (retail) Resellers (B2B)
β β
βΌ βΌ
Shopify / Amazon / eBay eSIM Hub Portal (WIP)
β β
β webhooks β
βΌ βΌ
βββββββββββ OMS (Next.js) ββββββββββββ
β β
βΌ βΌ
Supabase Supplier APIs
(products, (Redteago,
orders, eSIM Go, etc.)
customers) β
βΌ
eSIM / SIM delivered
to customerData flow: retail order
- Customer places order on Shopify / Amazon / eBay
- Order webhook delivers to OMS
- OMS looks up SKU in Supabase
productstable - OMS runs routing logic β picks an active variant
- OMS calls that variantβs supplier API to provision
- Supplier returns QR code / activation details
- OMS stores fulfillment record and emails customer
- Customer activates, traffic flows over carrier network
Data flow: B2B order (future, once eSIM Hub launches)
- Reseller logs into eSIM Hub
- Reseller browses catalog (reads Supabase
products) - Reseller adds SKUs + quantity to cart
- Portal looks up effective price (customer-specific β tier)
- Reseller confirms order, payment confirmation TBD
- Portal creates order in eSIM Hub DB, provisions via supplier
- Reseller can track all orders in Portal dashboard
Shared state between OMS and eSIM Hub
The product catalog (products, product_variants, suppliers, product_price_tiers, customer_specific_prices) is shared between OMS and eSIM Hub. Both systems read from the same Supabase project.
Order tables are separate:
- OMS owns retail orders (from Shopify / Amazon / eBay)
- eSIM Hub owns wholesale orders
A reporting layer (TBD) will union both for unified financial views.
Chatbot integration
The Chatbot (Cloudflare Workers) reads from two places:
- Knowledge base chunks (Supabase
kb_chunks) β for general Q&A, articles, policies productstable β for live product info (price, coverage, data amount)
The chatbot never caches product data. Price is always a live query β stale prices in a chatbot are a customer-trust disaster.
Competitor monitoring
Runs as a scheduled Cloudflare Worker, writes results to Cloudflare D1. Separate from the main stack because itβs read-only and can fail without affecting operations.
Known architectural debt
- OMS and eSIM Hub are on separate Supabase projects as of now. Product catalog should be in one shared project or synced.
- No shared reporting / analytics layer yet
- Shopify β OMS sync is webhook-based (fragile); a reconciliation job should run hourly
- Supplier API calls have no retry / dead-letter queue
- No environment separation (staging vs prod) for OMS
These are all candidates for ADRs once weβre ready to tackle them.