System Architecture — Team Document
v1.0 · AUG 2026
Architecture philosophy: proven, widely-deployed technology, professionally operated, sized for the real market (Utah local commerce) with a pre-planned path to 100× scale. No speculative complexity: every component below exists because a requirement demands it — and every one has millions of production deployments, deep documentation, and a large hiring pool behind it.
Client Layer
Edge Layer — Cloudflare
Application Layer — Laravel 11 (PHP 8.3) on hardened cloud VPS
Data Layer
Integration Layer
Operations Layer
| Choice | Why it survives scrutiny |
|---|---|
| Laravel 11 / PHP 8.3 | The most widely deployed web framework family on earth; batteries included (auth, queues, scheduler, migrations, Stripe library); enormous hiring pool — no key-person risk. Modern PHP 8 benchmarks within range of Node/Python for this workload. |
| MySQL 8 | Boring in the best way: 25+ years in production everywhere. Our schema is already deployed on it — transactions, row-locks for redemption caps, and a straight upgrade path to managed AWS RDS. |
| Redis | Industry-standard cache/queue; keeps the RIBBIT moment fast and notification work off the request path. |
| Cloudflare edge | DDoS, WAF, rate limiting, and global caching before traffic touches our server — enterprise-grade shielding at startup cost. |
| Stripe / Twilio | Card data and carrier compliance are the two scariest liabilities — we place them with the two companies best at exactly those, keeping us in the lightest PCI scope (SAQ-A: card data never touches our servers). |
| Cloud VPS now, AWS path later | Right-sized for launch; the path up (below) is planned, tested, and boring — no re-architecture required at any step. |
Honest capacity math: Utah's whole population is ~3.5M. A successful first year — tens of thousands of consumers, hundreds of businesses — generates request volumes a single well-tuned 4-vCPU server handles with a large margin (redemptions are short transactions; discovery is cache-friendly; static assets never touch us at all thanks to the CDN). We are deliberately not building Facebook's infrastructure to serve Saratoga Springs — but the road up is mapped:
| Stage | Trigger | Move | Downtime |
|---|---|---|---|
| 1. Launch | — | Hardened cloud VPS: app + MySQL + Redis, Cloudflare in front | — |
| 2. Vertical | Sustained CPU/RAM pressure | Resize the VPS (minutes, reversible) | ~ minutes, off-peak |
| 3. Split data | DB contention | Move MySQL to managed database (AWS RDS / DO Managed) — automated backups, failover | Near-zero (replica promote) |
| 4. Horizontal | App saturation | 2+ app servers behind a load balancer; sessions already in Redis so this is config, not code | Zero |
| 5. Beyond Utah | Multi-state expansion | Read replicas per region · queue workers scaled independently · same codebase | Zero |
The architecture above requires zero rewrites at any stage — each step is an operational move, not an engineering project. That is the point of choosing boring, horizontally-friendly components on day one.
We use cloud infrastructure where it earns its keep (edge shielding, managed services on the scale path, S3 backups) and skip complexity that only pays at 100× our realistic load. Microservices solve organizational scaling problems for 200-engineer teams; for a focused product they add failure modes and cost. Our monolith is modular internally and splits cleanly later if ever needed.
Two languages, the standard split: JavaScript in the client — the PWA's service worker, geolocation, camera scanning, push notifications, and all interactivity — and PHP (Laravel framework) on the server — the API, auth, redemption engine, and billing. Structured data lives in MySQL (SQL). Nothing exotic: this is the same division of labor running most of the transactional web.
PHP 8 with Laravel runs a massive share of the transactional web. It is fast, typed, actively developed, and has one of the deepest talent pools in software — which is a continuity guarantee for a small company. The framework ships production-grade auth, queues, and billing integration we would otherwise build by hand.
Cloudflare absorbs the traffic spike at the edge; the five-stage scaling path (above) is pre-planned and rewrite-free. Stage 2 is a resize measured in minutes. We would be delighted to have this problem and we know exactly which knob to turn first.
We minimize what there is to steal: no card numbers (Stripe holds those), location only at redemption moments, four fields of personal data. Defense in depth — edge WAF, hardened server, least-privilege DB, encrypted backups — plus an incident plan. The cheapest breach is the data you never collected.
Everything is mainstream: any Laravel shop in Utah can pick up this codebase. Documentation lives with the code (this page, the functional spec, the data layer doc), the schema uses framework conventions, and there is no exotic infrastructure requiring specialist knowledge.
At launch scale, yes, mitigated by monitoring (60-second checks), hourly offsite backups, and a documented restore that has actually been rehearsed — worst case is measured in minutes-to-hours of recovery, appropriate for this stage. Stage 3–4 of the scaling path adds managed-database failover and multi-server redundancy when the business justifies it.
Two independent factors — the customer's verified GPS presence and a physical scan of the business's own counter placard — validated server-side, plus a live anti-screenshot verification screen and the business's 48-hour void window. Fraud requires being physically present at the counter with staff watching, and the business still holds the undo button.
See the decision record in the functional spec (§6): integration multiplies development, certification, maintenance, and support cost across every POS platform forever, delays launch past the season, excludes cash-only merchants — and buys little, because the placard handshake plus the void window already verifies real visits. It remains a data-driven Phase 2 option if merchants ask.