Full-stack case study
OneGate
The single gateway for B2B sourcing and shipping — overseas clients submit requests, agents quote suppliers and freight, and orders flow from sample to bulk fulfillment.
- Role
- Full-Stack Developer — solo
- Duration
- 6 weeks — ongoing
- Year
- 2026
- Stack
- React · TypeScript · Express.js · MongoDB · Redis
- Live
- onegate.llc

01 / The Problem
An import agency running on chats and spreadsheets.
Clients who want goods sourced abroad or freight shipped dealt with the agency through scattered chats: staff quoted suppliers, samples and freight by hand, payments arrived as bank-transfer proofs in message threads, and nobody had one view of where an order stood across sourcing, sample and bulk phases.
Target users
B2B importers and e-commerce sellers — Arabic and English speaking — plus the agency's own sourcing agents, shipping agents, managers and admins.
02 / The Solution
One platform, one gateway.
A role-gated platform where clients submit sourcing or shipping requests and follow them through quoting, sample runs, bulk pricing and delivery — with payment proofs uploaded, verified by admins, and invoiced as PDFs. Five distinct order flows share one guarded lifecycle engine, and every business event notifies the right roles in real time.
Why this stack
- MongoDB — one nested, shape-shifting order document per flow
- Redis — email queue, shared rate limits and SSE pub/sub
- Same-origin via Caddy — first-party session cookies, zero CORS
- Node cluster — multi-process serving on a single VPS
03 / Features
What the platform does.
Auth & Six Roles
Sessions, Google OAuth and brute-force limits across six scoped roles
Multi-Flow Orders
Five order flows through guarded phase and status state machines
Manual Payments
Proof uploads verified by admins, with client-side PDF invoices
Realtime Notifications
Redis pub/sub fanned out to SSE streams on every worker
Six Role Dashboards
50+ routed pages with analytics, English/Arabic and full RTL
Direct-to-R2 Uploads
Presigned PUT URLs with strict content-type allowlists
04 / Technical Challenges
The hard parts — and how they fell.
Five order flows, one state machine
The same order can be a full sourcing → sample → bulk journey, a direct bulk buy, or a ship-only freight job — and clients, two agent types and admins all mutate it. One illegal transition corrupts real money flows.
How I solved it
One document carries flowType, activePhase and per-phase status enums; every transition is a dedicated service function that re-validates ownership, flow, phase and status before writing. Confirmed quotes materialize per-unit rates into the bulk sub-document so fixed pricing rides the existing payment machinery, and human-readable order numbers allocate race-free via an atomic counter upsert.
Realtime across a process cluster
The API runs as up to four forked workers plus a separate email worker. An SSE connection lives on exactly one process, but the event that must reach it can originate on any other.
How I solved it
Notifications persist to MongoDB, then publish through Redis pub/sub; every worker holds a dedicated subscriber connection and its own registry of open streams, forwarding only matching events. Heartbeat comments keep proxies from killing idle streams, and notify is fire-and-forget so a Redis outage can never break the business action.
Staying correct under horizontal scaling
Forking workers silently breaks anything with per-process state — rate-limit counters, client-IP detection behind the proxy, and fair distribution of incoming work.
How I solved it
API rate limits store counters in Redis so the cap holds across all workers — and fail open if Redis is down; trust proxy is pinned to exactly one hop. Incoming orders auto-assign to the least-loaded agent via an aggregation with shuffled ties, which also redistributes work when an agent leaves.
05 / Architecture
How the system fits together.
REACT 19 SPA
six role panels · PWA · EN/AR RTL
EXPRESS 5 API
better-auth · Zod · Node cluster
MONGODB
orders · payments · notifications
CLOUDFLARE R2
presigned direct uploads
REDIS
queue · rate limits · pub/sub
SMTP + BULLMQ
email worker with retries
External services
06 / Screenshots
The product, up close.


07 / Results
What it moved in the real world.
The agency's whole brokerage workflow — quoting, sample runs, bulk pricing, payment verification — now runs through one login instead of spreadsheets and chat threads. Six roles see exactly their queue, every status change notifies the people it affects in real time, and the platform ships continuously through a CI pipeline that runs a full-stack end-to-end suite before every deploy.
08 / Tech Stack
Built with.
Frameworks
- React 19
- Express 5
- Node.js
- Vite
Libraries
- better-auth
- React Query
- BullMQ
- Zod
- Tailwind CSS
- Recharts
Infrastructure
- MongoDB
- Redis
- Docker
- Caddy
- Cloudflare R2
- GitHub Actions CI/CD
09 / My Contribution
What I built, specifically.
- Built the order-lifecycle engine: five flow types with phase/status state machines, per-role transition guards, quote materialization and atomic order numbering.
- Built cluster-safe realtime notifications: Redis pub/sub into per-worker SSE registries with heartbeats, TTL-pruned persistence and the notification bell UI.
- Set up production infrastructure end-to-end: Node cluster entrypoint with graceful shutdown, Docker compose overlays, Caddy same-origin TLS, and the CI → registry → SSH deploy pipeline gated on a Playwright e2e suite.
- Developed six role-gated frontend panels (~50 routed pages) with English/Arabic RTL i18n, PWA packaging, analytics charts and client-side PDF quotations and invoices.
- Built load-balanced agent auto-assignment: aggregation-based least-loaded selection with tie shuffling and redistribution when agents leave; configured and hardened the better-auth layer (account linking, per-route limits).