BrewHouse
Order-ahead, pay & earn rewards — a full-stack React Native coffee ordering app
Replace the in-line queue with order-ahead pickup and a loyalty program that drives repeat visits.
A full-stack mobile ordering platform that replaces the in-line queue with order-ahead pickup. The React Native (Expo) client lets customers browse a categorized menu, deep-customize each drink (size, milk, shots, syrups, temperature), drop items into a persistent cart, pay, and track order status in real time. A TypeScript Express/Prisma backend exposes a versioned REST API that owns the menu catalog, a server-authoritative pricing engine, the order-lifecycle state machine, and a tamper-proof loyalty ledger. Server cache lives in TanStack Query while the in-progress cart lives in a Zustand store persisted to AsyncStorage, and a shared types package keeps the API and client models in lockstep end-to-end.
Features built in
Architecture & State
- Feature-sliced folders: menu, cart, orders, rewards, auth — each self-contained
- TanStack Query owns server cache (menu, history); Zustand owns ephemeral cart
- Cart store persisted to AsyncStorage with schema-versioned migrations
- Shared types package consumed by both API and app to prevent contract drift
- Expo Router file-based routes with typed params and protected route groups
Menu, Customization & Cart
- Categorized menu (espresso, brewed, cold, food) hydrated from the catalog API
- Modifier sheet: size, milk, extra shots, syrups, temperature with price deltas
- Optimistic running total computed client-side from the same modifier rules
- Add-to-cart with quantity, notes, and per-line modifier summary
- Cart badge and subtotal update reactively across the tab bar
Ordering & Pricing
- Server recomputes canonical price at checkout from the catalog — client total never trusted
- Order lifecycle state machine: placed → accepted → preparing → ready → completed
- Live status screen polls order state with a websocket upgrade path
- Pickup time estimate and store selection at checkout
- Order history with reorder-in-one-tap from any past order
Auth & Security
- JWT access + refresh tokens with server-side refresh rotation
- Tokens stored in expo-secure-store (Keychain / Keystore), never AsyncStorage
- Axios interceptor refreshes on 401 and transparently replays the original call
- Zod-validated forms via React Hook Form for sign-up and login
- Protected Expo Router groups redirect unauthenticated users to the auth flow
Loyalty & Rewards
- Stars credited per completed order, reconciled on the server ledger
- Tier multipliers (e.g. Gold earns faster) applied backend-side
- Redeemable rewards surfaced with progress toward the next free drink
- Reward redemption validated against the ledger to prevent double-spend
- Profile screen shows balance, tier, and lifetime stars
Backend & Quality
- Express REST API with versioned routes and centralized error middleware
- Prisma schema models catalog, modifiers, orders, and loyalty ledger
- Seed scripts populate the menu and modifier matrix for local dev
- Jest + Supertest cover the pricing and order-placement endpoints
- Request validation and typed DTOs guard every mutation
- A single-location specialty cafe launching order-ahead pickup
- A multi-store coffee chain adding mobile ordering and digital loyalty
- A juice bar or bakery needing modifier-heavy product customization
- A ghost kitchen or QSR wanting a branded app without building auth and pricing from scratch
From idea to live in 4 steps
Enquiry
Tell me what you want to build using the form below — platform, features, budget, and timeline.
Quote & Scope
Within 24 hours you get a fixed quote, a clear scope, and a delivery plan — no surprises.
Design & Build
I design and build in weekly milestones with live previews so you watch it come together.
Deploy & Support
I ship it live — web, App Store, Play Store — and stick around for support and iteration.
Common questions
Does it work on both iOS and Android?
Yes — it's a single Expo React Native codebase that builds for both, with no platform-specific forks for core flows.
Can I plug in real payments?
The checkout flow is structured around a payment step with a clear seam to drop in Stripe, Square, or any PSP; the template ships with the order and pricing plumbing it needs.
Is the pricing safe from client tampering?
Yes. The client shows an optimistic total for UX, but the backend recomputes the canonical price from the catalog at checkout, so the client can never dictate what it pays.
How is data stored?
PostgreSQL via Prisma. The schema models the catalog, modifiers, orders, and the loyalty ledger, with seed scripts to get a working menu instantly.
Can I customize the menu and modifiers?
The menu and modifier matrix are data-driven through the catalog, so you change products, sizes, and add-ons in the database/seed without touching app code.
What's included for auth?
Full JWT auth with refresh rotation, secure token storage via expo-secure-store, an Axios refresh interceptor, and protected route groups.
Is it tested?
The pricing and order-placement endpoints are covered with Jest and Supertest, and a shared TypeScript types package keeps the API and app contracts aligned.