High-Level Design
Architecture overview, technology decisions matrix, data model, auth design, and API patterns for Royal Glow.
High-Level Design
Executive Summary
Royal Glow Salon & Spa is a premium beauty and wellness establishment in Bengaluru, India. This document describes the high-level design of the full-stack digital operations platform.
A monolithic modular monorepo on Next.js 16 + Neon + Cloudflare's edge, designed for 20k–50k users at ₹0/month, India-first (DPDP, IST, paise, GST 18%), with Lighthouse ≥95 performance and 100 accessibility/SEO.
Scale Targets
Prop
Type
Key Constraints
Prop
Type
Architecture Overview
Layered Monorepo
Presentation → API (thin) → Business Logic → Data Access → Database
apps/{web,admin} apps/{web,admin}/api packages/business packages/db Neon PostgreSQLProp
Type
Hosting Topology
Browser/PWA
│ HTTPS
▼
Cloudflare (DNS + DDoS + WAF)
│
├── Cloudflare Workers (web + admin via OpenNext adapter, edge SSR + API)
└── Cloudflare KV (service catalog cache, 5-min TTL)
│
├── Render Singapore (Payload CMS)
├── Cloud Run (@rgss/invoicing PDF render service)
├── Neon PostgreSQL (4 branches: dev/test/pprd/prod)
├── Upstash Redis + QStash (cache + queue)
├── Cloudflare R2 (images, PDFs, backups)
└── Ably (realtime WebSocket, 6 channels)Technology Decisions Matrix
| Category | Choice | Key Reason |
|---|---|---|
| Framework | Next.js 16 (App Router) | SSR + SSG + API routes + edge-ready |
| Runtime | Bun | 3x faster installs, native TypeScript |
| Database | Neon PostgreSQL 16 | Branching, serverless, all jobs via QStash |
| ORM | Drizzle ORM | Pure TypeScript, runs on CF Workers V8 |
| Auth | Better Auth | Self-hosted, Google OAuth, RBAC plugin |
| Edge Hosting | Cloudflare Workers (OpenNext) | Generous free tier, global edge |
| Origin Hosting | Render (Singapore) | Free tier, closest to India |
| Realtime | Ably | 6M messages/mo free vs Pusher's 200k/day |
| CMS | Payload CMS v3 | Self-hosted Next.js plugin, zero vendor lock-in |
| Email (transactional) | Resend | Modern DX, React Email templates |
| Email (marketing) | Brevo | Unsubscribe management, DPDP-compliant |
| Cache | Upstash Redis | Serverless, works on CF Workers |
| File Storage | Cloudflare R2 | S3-compatible, zero egress fees |
| Analytics | PostHog | 1M events/mo, feature flags, DPDP-compliant |
| Error Monitoring | Sentry | Industry standard, CF Workers support |
| Validation | Zod | TypeScript-native inference, industry standard |
| Styling | Tailwind CSS v4 | Utility-first, design tokens |
| Components | shadcn/ui + Radix | Copy-paste ownership, Radix accessibility |
Data Architecture
Database Strategy
Neon PostgreSQL 16 with Git-like branching.
Prop
Type
Data Model Overview (38 tables)
| Domain | Tables | Key Entities |
|---|---|---|
| Auth | 4 | user, session, account, verification |
| Profiles | 2 | customer_profile, staff_profile |
| Services | 3 | service_category, service, service_staff |
| Scheduling | 4 | staff_schedule, staff_time_off, holiday, waitlist |
| Bookings | 4 | booking, booking_service, booking_note, booking_history |
| Billing | 2 | invoice, invoice_item |
| SPA Memberships | 2 | spa_membership, spa_membership_tier |
| Offers | 3 | offer, offer_service, offer_redemption |
| CRM/Leads | 5 | lead, lead_note, customer_tag, customer_tag_assignment, customer_note |
| Loyalty | 2 | loyalty_account, loyalty_transaction |
| Notifications | 2 | notification, push_subscription |
| Branches | 1 | branch |
| System | 5 | daily_sales_summary, monthly_gst_summary, audit_log, system_setting, feature_flag_override |
Key Data Conventions
Prop
Type
Three-Layer Cache Hierarchy
Prop
Type
Authentication & Authorization
Auth Architecture
- Provider: Google OAuth 2.0 only (no email/password)
- Sessions: PostgreSQL
sessiontable (HttpOnly, Secure, SameSite=Lax cookies) - CSRF: Built-in via Better Auth
- Token type: Session-based (not JWT) — revocable, server-validated
Six roles in ascending privilege:
Customer → Staff → Receptionist → Manager → Owner → Developer| Role | Access |
|---|---|
| Customer | Public pages, own bookings/profile/gems |
| Staff | Own schedule, assigned booking notes, leave requests |
| Receptionist | Lowest admin role — bookings, billing, memberships, leave approvals |
| Manager | Full operational access — staff, services, reports, settings |
| Owner | Full business access including admin.theroyalglow.in/users |
| Developer | Everything + admin.theroyalglow.in/integrations, admin.theroyalglow.in/logs |
Initiate
User clicks "Sign in with Google".
Consent
Redirect to the Google consent screen (shows "Royal Glow Salon & Spa").
Callback
User grants consent and Google calls back with an auth code.
Exchange
Better Auth exchanges the code for tokens and creates/finds the user in the DB.
Session
A session is created and an HttpOnly cookie is set.
Route
Has a customer_profile? YES → homepage. NO → /onboarding.
API Design
Thin API Layer Pattern
Request → Parse → Zod Validate → Business Logic → ResponseAPI routes are thin orchestrators. No database queries in route handlers.
Standard Response Shape
// Success
{ success: true, data: T, meta?: { page, totalPages, totalCount } }
// Error
{ success: false, error: { code, message, statusCode, requestId, retryable?, details? } }API Groups
Prop
Type
Non-Functional Requirements
Prop
Type
Related Pages
Low-Level Design
State machines, sequences, indexes, and security implementation
Data Model
All 38 tables, enums, and ID formats
Architecture
Condensed architecture overview
Was this page helpful?