The backend and shared services powering both the Diner App and Restaurant App. This document covers authentication, payments, data architecture, real-time services, AI processing, compliance, APIs, and infrastructure.
Technical Note: JWTs use RS256 signing with 15-minute access token expiry and 7-day refresh token rotation. Refresh tokens are stored in an HTTP-only secure cookie and invalidated on logout or suspicious activity.
2. Payment Processing
Stripe vs. Finix Comparison
Component
Description
Stripe
Finix
Card tokenization
Securely store card data
Stripe.js Elements
Finix.js tokenization
Pre-authorization
Temporary holds when diner links to table
PaymentIntents with capture_method=manual
Authorizations API
Charges
Final charge at tab close
Capture PaymentIntent
Create Transfer from Authorization
Refunds
Process refunds
Refund API
Refund API
Connect payouts
Route funds to restaurants
Stripe Connect (Standard or Express)
Merchant onboarding + payouts
Processing fees
Per-transaction cost
2.9% + $0.30
Custom (typically 2.7–2.9% + $0.25–0.30)
Payment Lifecycle Flow
Split Payment Engine
Even Split
Total ÷ N people. Each person is charged their equal share as a separate transaction.
By Item
Items assigned to individuals. Each charged their items + proportional share of tax and tip.
Custom
Manual amounts per person. Validated against total to ensure full coverage before processing.
Important: All split calculations are validated server-side. The sum of all individual charges must equal the total (subtotal + tax + tip) before any charges are captured. Rounding differences are absorbed by the last payer.
3. Data Layer — MongoDB + Zod
Primary Database: MongoDB Atlas (managed, SOC2-certified, encrypted at rest AES-256).
Zod Schema Architecture
Zod schemas serve as the single source of truth for the entire data layer, generating TypeScript types, MongoDB validation rules, and OpenAPI specifications.
Example: User Schema
// Zod schemas are the single source of truth
// → Generate TypeScript types (z.infer<typeof schema>)
// → Generate MongoDB validation rules
// → Generate OpenAPI spec (via zod-to-openapi)
const UserSchema = z.object({
_id: z.string(),
phone: z.string().regex(/^\+[1-9]\d{1,14}$/),
verified: z.boolean().default(false),
dinoVerified: z.boolean().default(false),
paymentMethods: z.array(PaymentMethodSchema),
preferences: UserPreferencesSchema,
createdAt: z.date(),
updatedAt: z.date(),
});
type User = z.infer<typeof UserSchema>;
Technical Note: All collections use MongoDB Atlas's built-in schema validation generated from Zod schemas at deploy time. The zod-to-mongo-schema utility converts Zod definitions to MongoDB $jsonSchema validators, ensuring runtime data integrity matches compile-time types.
4. Real-Time Services
Technology Stack
Component
Technology
Purpose
WebSocket server
Socket.io or ws
Real-time order updates, table status, KDS updates
Push notifications
Firebase Cloud Messaging (FCM)
Order status, payment confirmations, payback reminders
Location services
QR-based check-in (MVP)
Link diner to table. Future: BLE / geofencing
WebSocket Events
Event
Direction
Payload
order:new
Diner → Restaurant
{ orderId, tableId, items[] }
order:status
Restaurant → Diner
{ orderId, status, estimatedTime }
table:status
Restaurant → All
{ tableId, status }
kds:update
Restaurant → KDS
{ orderId, items[], priority }
payment:complete
System → Both
{ paymentId, amount, status }
Technical Note: WebSocket connections are authenticated via JWT and scoped to restaurant rooms. Diners join a room when they scan the table QR code. Kitchen staff subscribe to their restaurant's KDS channel. Reconnection is handled automatically with exponential backoff.
Log each Vision/Textract call with image size + cost
Per-request LLM cost
Log input/output tokens, model used, compute cost
Per-restaurant spend
Aggregate costs by restaurant_id
Monthly totals
Dashboard aggregation with budget alerts at 80% / 100%
Budget controls
Per-restaurant monthly limit, global monthly limit
Model abstraction
Pluggable provider layer for OCR + LLM swapping
Important: All AI operations are logged with full cost attribution. The pluggable provider layer enables switching between OCR engines (Google Vision vs. AWS Textract) and LLMs (Claude vs. GPT-4) without code changes, using environment-based configuration.
MongoDB CSFLE for PII (card tokens, phone numbers, addresses)
MVP
Access control
RBAC with least-privilege: separate DB users for API, admin, analytics
MVP
Audit logging
All data access events logged: who, what, when, from where
MVP
Key rotation
Automated 90-day key rotation schedule
MVP
Penetration testing
Annual third-party pen test
Post-MVP
Data retention
Defined retention periods per data type, automated purging
MVP
Incident response
Documented procedures for security incidents
MVP
RBAC Roles
Role
Access Level
api_service
Read/write to operational collections (orders, payments, sessions)
admin_service
Full access to all collections
analytics_readonly
Read-only access to aggregated data, no PII
restaurant_owner
Read/write own restaurant data only
kitchen_staff
Read orders for own restaurant, update order status
Technical Note: RBAC enforcement happens at two layers: MongoDB database-level users with scoped privileges, and application-level middleware that validates JWT role claims against endpoint requirements. All role assignments and changes are audit-logged.
7. API & Documentation
REST API: Express.js or Fastify with OpenAPI 3.1 spec as the source of truth. All endpoints validated at runtime using Zod middleware.
POST /auth/verify-phone POST /auth/verify-code POST /auth/refresh
Public / JWT
Users
GET /users/me PUT /users/me POST /users/me/payment-methods
JWT
Restaurants
CRUD /restaurants GET /restaurants/nearby
JWT / Public
Menus
CRUD /restaurants/:id/menus POST /menus/ai-upload
JWT (restaurant)
Orders
POST /orders GET /orders/:id PUT /orders/:id/status
JWT
Payments
POST /payments/pre-auth POST /payments/charge POST /payments/split
JWT
Tables
GET /restaurants/:id/tables PUT /tables/:id/status
JWT (restaurant)
KDS
GET /restaurants/:id/kds PUT /kds/:orderId/status
JWT (kitchen)
Analytics
GET /restaurants/:id/analytics/daily GET /analytics/menu
JWT (owner)
AI
POST /ai/parse-menu GET /ai/costs
JWT (admin)
Technical Note: All API responses follow a consistent envelope: { success: boolean, data?: T, error?: { code, message } }. Rate limiting is enforced per-user (100 req/min for authenticated, 20 req/min for public endpoints) using Redis-backed sliding window counters.
8. POS Integration Layer POST-MVP
Component
Description
MVP Status
Toast API adapter
Menu sync, order injection, payment reconciliation
Post-MVP
Clover API adapter
Menu sync, order injection, payment reconciliation
Post-MVP
Square API adapter
Menu sync, order injection, payment reconciliation
Post-MVP
Menu sync service
Bi-directional menu sync with POS
Post-MVP
Note: MVP operates in standalone mode. POS integration is Phase 2. The adapter pattern is designed now so the integration layer can be plugged in without architectural changes.
9. Infrastructure & Deployment
Component
Technology
Justification
API Server
Node.js (Express or Fastify)
Team familiarity, TypeScript native
Database
MongoDB Atlas (M10+ for production)
SOC2 certified, managed, flexible schema
Cache
Redis (ElastiCache or Upstash)
Session cache, rate limiting
File Storage
AWS S3 or GCP Cloud Storage
Menu images, receipts, uploads
CDN
CloudFront or Cloudflare
Static assets, image delivery
Hosting
Railway (MVP) → AWS/GCP (production)
Fast iteration for MVP
CI/CD
GitHub Actions
Automated testing + deployment
Monitoring
Datadog or Sentry
Error tracking, APM, alerts
Architecture Overview
Technical Note: MVP uses a monolithic Node.js server deployed on Railway for rapid iteration. The codebase is structured with clear service boundaries (auth, payments, orders, AI) so individual services can be extracted into microservices when scaling demands it post-MVP.
10. MVP Scope Boundaries
IN Scope (MVP)
✓Phone + SMS verification (Twilio)
✓Card tokenization via Stripe (primary) or Finix (secondary) — 2.9% + $0.30
✓Pre-authorization holds and auto-settlement
✓QR code table check-in
✓MongoDB Atlas with Zod schemas (single source of truth)