Complete map of all 104 pages and API routes in the Royal Glow platform.
The platform spans two Next.js apps: the customer site @rgss/web (theroyalglow.in) and the admin portal @rgss/admin (admin.theroyalglow.in). Together they cover ~104 pages plus the API layer.
The customer site uses Next.js App Router route groups (folders in parentheses) to share a layout without affecting the URL. The admin portal is a separate app served from admin.theroyalglow.in at root paths — the subdomain provides the admin namespace, so there is no /admin prefix. Legacy theroyalglow.in/admin/* paths 301-redirect to the subdomain. Staff self-service lives at /me/* within the admin app. Admin routes are RBAC-gated; everything else is public or customer-authenticated.
The admin portal (@rgss/admin, admin.theroyalglow.in) is a standalone app: admin pages at root paths under a sidebar + RBAC layout (receptionist+), and staff self-service pages at /me/* (staff+).
Meta/Instagram ad landing page — 3-field form, no nav
/privacy
Privacy Policy
DPDP Act 2023
/terms
Terms of Service
—
/refund-policy
Refund & Cancellation Policy
—
All admin routes are served from admin.theroyalglow.in at root paths (no /admin prefix) and require authentication with minimum role receptionist. The paths below are relative to admin.theroyalglow.in.
Redirect to the Payload CMS service collection — the catalogue is authored in the CMS, not the admin portal
/offers
Manager
Offer creation and management
/staff
Manager
Staff list and profiles
/schedule
Manager
Weekly staff availability grid
/reports
Manager
Revenue, bookings, staff performance
/settings
Manager
System settings
/branches
Owner
Branch management
/users
Owner
User management and role assignment
/integrations
Developer
Integration configuration
/logs
Developer
Audit logs
Staff self-service pages live at /me/* within the admin app (admin.theroyalglow.in).
Route
Min. Role
Page
/me/schedule
Staff
Own weekly schedule
/me/leave
Staff
Submit and view own leave requests
Customer API routes (below) are served from theroyalglow.in/api/* by @rgss/web. Admin API routes are served from admin.theroyalglow.in/api/* by @rgss/admin — there is no /api/admin/ segment.
Served from admin.theroyalglow.in/api/*. There is no /api/admin/ segment — the subdomain is the namespace. Paths below are relative to admin.theroyalglow.in.
Endpoint
Method
Min. Role
Description
/api/bookings
GET, POST
Receptionist
List / create booking
/api/bookings/new
POST
Receptionist
Walk-in booking creation
/api/bookings/[id]
PATCH
Receptionist
Approve, reject, assign staff
/api/bookings/[id]/complete
POST
Receptionist
Mark completed + invoice + gems
/api/bookings/[id]/noshow
POST
Receptionist
Mark no-show
/api/customers
GET
Receptionist
Customer list with search/filter
/api/customers/[id]
GET
Receptionist
Customer detail
/api/customers/[id]/notes
POST
Receptionist
Add CRM note
/api/customers/[id]/tags
POST
Receptionist
Add tag
/api/customers/[id]/tags/[tagId]
DELETE
Receptionist
Remove tag
/api/leads
GET, POST
Receptionist
Lead list / create manual lead
/api/leads/[id]
PATCH
Receptionist
Update lead status
/api/leads/[id]/notes
POST
Receptionist
Add lead note
/api/billing
GET
Receptionist
Invoice list
/api/billing/[id]
GET
Receptionist
Invoice detail
/api/memberships
GET, POST
Receptionist
List / create membership
/api/memberships/[id]
GET
Receptionist
Membership detail
/api/memberships/[id]/sessions
POST
Receptionist
Record session
/api/memberships/[id]/cancel
POST
Manager
Cancel membership
/api/membership-tiers
GET
Receptionist
SPA membership tiers
/api/leave
GET, POST
Receptionist
Leave queue / submit leave
/api/leave/[id]
PATCH
Receptionist
Approve / reject leave
/api/me/leave
GET, POST
Staff
Own leave list / submit
/api/me/leave/[id]
PATCH
Staff
Update own leave
/api/me/schedule
GET
Staff
Own schedule
/api/schedule
GET
Receptionist
Staff schedule for date
/api/waitlist
GET, POST
Receptionist
Waitlist list / add
/api/waitlist/[id]
PATCH, DELETE
Receptionist
Update / remove waitlist entry
/api/tags
GET
Receptionist
Available CRM tags
/api/notifications
GET, PATCH
Receptionist
Notifications list + mark read
/api/offers
GET, POST
Manager
List / create offer
/api/offers/[id]
PATCH, DELETE
Manager
Update / delete offer
/api/services
GET, POST
Manager
Service list / create
/api/services/all
GET
Manager
All services (incl. inactive)
/api/services/[id]
PATCH, DELETE
Manager
Update / delete service
/api/service-categories
GET, POST
Manager
Category list / create
/api/service-categories/[id]
PATCH, DELETE
Manager
Update / delete category
/api/staff
GET, POST
Manager
Staff list / create
/api/staff/all
GET
Manager
All staff
/api/staff/[id]
GET, PATCH
Manager
Staff detail / update
/api/staff/[id]/services
GET, PATCH
Manager
Staff service assignments
/api/reports
GET
Manager
Reports data
/api/branches
GET
Manager
Branch list
/api/branches/[id]
PATCH
Owner
Update branch
/api/settings
GET, PATCH
Manager
System settings
/api/users
GET
Owner
User list / role management
/api/integrations
GET
Developer
Integration configuration
/api/logs
GET
Developer
Audit logs
/api/health
GET
—
Admin health check
/api/ably/token
POST
Receptionist
Scoped Ably JWT (Token Auth)
QStash signature required. Hosted in @rgss/admin and served from admin.theroyalglow.in/api/jobs/*. 19 jobs total: 14 QStash scheduled + 4 QStash triggered + 1 GitHub Actions cron.
pprd DB sync — resets the pprd Neon branch from prod and strips PII. Runs in GitHub Actions, not as an HTTP route.
An internal /api/jobs/invoice-pdf route also exists: it hands invoice rendering to the @rgss/invoicing Cloud Run PDF service. It is a support route, not one of the 19 scheduled/triggered business jobs.
{"docsConfig":{"theme":"aspen","$schema":"https://mintlify.com/docs.json","name":"Royal Glow Salon \u0026 Spa","description":"Product, engineering, operations, and API documentation for the Royal Glow Salon \u0026 Spa platform — the digital operations system behind a premium beauty and wellness business in Bengaluru.","colors":{"primary":"#7D5C12","light":"#F4E09B","dark":"#7D5C12"},"logo":{"light":"https://mintcdn.com/royal-glow-salon-and-spa/dS3ivn1eYYDGMU1q/logo/brand.png?fit=max\u0026auto=format\u0026n=dS3ivn1eYYDGMU1q\u0026q=85\u0026s=9850260e71bb5f24f582245caa612a92","dark":"https://mintcdn.com/royal-glow-salon-and-spa/dS3ivn1eYYDGMU1q/logo/brand.png?fit=max\u0026auto=format\u0026n=dS3ivn1eYYDGMU1q\u0026q=85\u0026s=9850260e71bb5f24f582245caa612a92","href":"https://theroyalglow.in"},"favicon":"https://mintcdn.com/royal-glow-salon-and-spa/dS3ivn1eYYDGMU1q/favicon.png?fit=max\u0026auto=format\u0026n=dS3ivn1eYYDGMU1q\u0026q=85\u0026s=f7b817d1fd2cbdf016f7c736130321d4","appearance":{"default":"light","strict":false},"background":{"color":{"light":"#FFFFFF","dark":"#1A0F0A"}},"navbar":{"links":[{"icon":"github","href":"https://github.com/royalglowsalonspa/theroyalglow-webapp","label":"GitHub"}],"primary":{"type":"button","label":"Book Now","href":"https://theroyalglow.in/?book=1"}},"footer":{"socials":{"website":"https://theroyalglow.in","github":"https://github.com/royalglowsalonspa/theroyalglow-webapp"},"links":[{"header":"Documentation","items":[{"label":"Overview","href":"/content/docs/index"},{"label":"Product","href":"/content/docs/product/index"},{"label":"Features","href":"/content/docs/features/index"},{"label":"FAQ","href":"/content/docs/faq"}]},{"header":"Engineering","items":[{"label":"Getting started","href":"/content/docs/getting-started"},{"label":"Architecture","href":"/content/docs/architecture"},{"label":"System design","href":"/content/docs/system-design/index"},{"label":"Operations","href":"/content/docs/operations"}]},{"header":"API reference","items":[{"label":"Overview","href":"/content/docs/api-reference/index"},{"label":"Services","href":"/content/docs/api-reference/services"},{"label":"Bookings","href":"/content/docs/api-reference/bookings"},{"label":"Background jobs","href":"/content/docs/api-reference/jobs"}]},{"header":"Royal Glow","items":[{"label":"Main site","href":"https://theroyalglow.in"},{"label":"Admin portal","href":"https://admin.theroyalglow.in"},{"label":"Status page","href":"https://status.theroyalglow.in"},{"label":"GitHub","href":"https://github.com/royalglowsalonspa/theroyalglow-webapp"}]}]},"search":{"prompt":"Search Royal Glow documentation"},"seo":{"metatags":{"og:site_name":"Royal Glow Salon \u0026 Spa Documentation","twitter:card":"summary_large_image"},"organization":{"id":"https://theroyalglow.in/#organization","name":"Royal Glow Salon \u0026 Spa","url":"https://theroyalglow.in","sameAs":["https://github.com/royalglowsalonspa"]},"indexing":"navigable"},"icons":{"library":"lucide"},"styling":{"eyebrows":"breadcrumbs","codeblocks":{"theme":{"light":"gruvbox-light-medium","dark":"gruvbox-dark-medium"}},"latex":true},"contextual":{"options":["copy","view","chatgpt","claude","cursor","mcp"],"display":"header"},"thumbnails":{"appearance":"dark","fonts":{"family":"Plus Jakarta Sans"}},"interaction":{"drilldown":false},"metadata":{"timestamp":true},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"royal-glow-salon-and-spa","hasAudioNarration":false,"actualSubdomain":"royal-glow-salon-and-spa","customDomains":["docs.theroyalglow.in"],"gitSource":{"type":"github","owner":"royalglowsalonspa","repo":"theroyalglow-webapp","deployBranch":"prod","contentDirectory":"docs","isPrivate":false,"mountPath":"","label":""},"chroma":{"latestBuiltDeploymentHistoryId":"6addf05d97966bd2c9ffd5e9","collectionId":"372ca85f-9792-430d-8e4b-b064b5e0e2cd","liveDeploymentHistoryId":"6addf05d97966bd2c9ffd5e9","schemaVersion":"v3"},"feedback":{"thumbs":true,"edits":true,"issues":true,"agentFeedback":true},"entitlements":{"AI_CHAT":{"status":"DISABLED"}},"buildId":"6addf05d97966bd2c9ffd5e9","clientVersion":"0.0.3990","searchFilterCounts":[{"language":"default","tag":"Engineering","count":35},{"language":"default","tag":"API reference","count":22},{"language":"default","tag":"Documentation","count":20},{"language":"default","tag":"Features","count":12},{"language":"default","tag":"Delivery workflow","count":8},{"language":"default","tag":"Platform","count":6},{"language":"default","tag":"Overview","count":4},{"language":"default","tag":"Operations","count":4},{"language":"default","tag":"Quality \u0026 security","count":4},{"language":"default","tag":"Product","count":4}],"searchSettings":{"showContentSnippets":true,"isFiltersEnabled":true,"maxResults":10}},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-v7-file-tree","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"pause-universal-search-reconcile","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"per-site-search-delta","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-private-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-nav-generations","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-agent-model-picker","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"privacy":{"consentBanner":{"enabled":true}},"isAtlas":false,"googleFontsInlined":false},"customCss":[{"filePath":"style.css","content":":root{--rg-royal-gold:#f4e09b;--rg-deep-gold:#c8a961;--rg-accessible-gold:#7d5c12;--rg-warm-stone:#d4c5a9;--rg-warm-cream:#fff8e7;--rg-golden-mist:#fff3d4;--rg-canvas:#ffffff;--rg-cocoa:#1a0f0a;--rg-chocolate:#2d1810;--rg-warm-gray:#3d2e1f;--rg-dusty-gray:#8c8c8c;--rg-outline:#cccccc;--rg-cloud:#f4f5f9;--rg-success:#3f7d5c;--rg-error:#b5482e;--rg-radius:4px;--rg-radius-card:6px;--rg-radius-lg:10px;--rg-radius-pill:9999px;--rg-shadow-hover:0 16px 34px -24px rgba(26, 15, 10, 0.28);--rg-shadow-elevated:0 20px 44px -28px rgba(26, 15, 10, 0.4);--rg-surface:var(--rg-canvas);--rg-surface-raised:#fffbf3;--rg-border:rgba(26, 15, 10, 0.1);--rg-border-strong:rgba(26, 15, 10, 0.18);--rg-accent:var(--rg-accessible-gold);--rg-accent-soft:rgba(200, 169, 97, 0.12);--rg-ink:var(--rg-cocoa);--rg-ink-muted:var(--rg-warm-gray);--rg-eyebrow-size:11px;--rg-eyebrow-tracking:1.6px}.dark{color-scheme:dark;--rg-surface:var(--rg-cocoa);--rg-surface-raised:#21140e;--rg-border:rgba(244, 224, 155, 0.12);--rg-border-strong:rgba(244, 224, 155, 0.22);--rg-accent:var(--rg-royal-gold);--rg-accent-soft:rgba(244, 224, 155, 0.1);--rg-ink:var(--rg-warm-cream);--rg-ink-muted:var(--rg-warm-stone);--rg-shadow-hover:0 16px 34px -24px rgba(0, 0, 0, 0.8);--rg-shadow-elevated:0 20px 44px -28px rgba(0, 0, 0, 0.9)}#background-color,#body-content,#content-area,#footer,#sidebar,#sidebar-content,#table-of-contents,body,footer,html{background-color:var(--rg-surface)}#sidebar,#table-of-contents,sidebar-nav-group-divider{border-color:var(--rg-border)}img.nav-logo{width:2.75rem!important;height:2.75rem!important;max-width:none!important;object-fit:contain}#navbar{border-bottom:1px solid var(--rg-border);background:var(--rg-surface);backdrop-filter:none;box-shadow:0 1px 0 rgba(26,15,10,.02)}.dark #navbar{box-shadow:0 1px 0 rgba(244,224,155,.03)}.nav-tabs-item,nav-tabs-item,navbar-link{font-size:13px;font-weight:650;letter-spacing:0;text-transform:none}#topbar-cta-button{border-radius:var(--rg-radius-pill);box-shadow:none;font-size:13px;font-weight:700;letter-spacing:0}sidebar-group-header{color:var(--rg-ink-muted)}#footer a:hover,.nav-tabs-item[data-active],advanced-footer a:hover,sidebar-group-icon,tab-icon{color:var(--rg-accent)}#sidebar-content li[data-active]{position:relative;background:var(--rg-accent-soft);border-radius:var(--rg-radius)}#sidebar-content li[data-active]::before{content:\"\";position:absolute;inset-inline-start:0;top:50%;translate:0 -50%;height:62%;width:2px;border-radius:var(--rg-radius-pill);background:var(--rg-accent)}.mdx-content thead th,eyebrow,mdx-content thead th,sidebar-group-header{font-size:var(--rg-eyebrow-size);font-weight:700;text-transform:uppercase}eyebrow,sidebar-group-header{letter-spacing:var(--rg-eyebrow-tracking)}eyebrow{color:var(--rg-accent)}toc-item[data-active-deepest]{color:var(--rg-accent);font-weight:600}.mdx-content table,mdx-content table{width:100%;border-collapse:separate;border-spacing:0;border:1px solid var(--rg-border);border-radius:var(--rg-radius-card);overflow:hidden;font-size:14px}.mdx-content thead th,mdx-content thead th{background:var(--rg-surface-raised);letter-spacing:1px;color:var(--rg-ink-muted);text-align:start;padding:10px 14px;white-space:nowrap}.mdx-content tbody td,mdx-content tbody td{padding:11px 14px;border-top:1px solid var(--rg-border);vertical-align:top}.mdx-content tbody tr:hover,mdx-content tbody tr:hover{background:var(--rg-accent-soft)}.mdx-content tbody td:first-child,mdx-content tbody td:first-child{font-weight:600;color:var(--rg-ink);white-space:nowrap}.mdx-content table code,mdx-content table code{font-size:12.5px;padding:1px 5px;border-radius:var(--rg-radius);background:var(--rg-accent-soft);border:1px solid var(--rg-border)}#footer,card,footer{background:var(--rg-surface)}[data-component-part=card-icon],card{border:1px solid var(--rg-border);border-radius:var(--rg-radius-card)}card{transition:border-color 160ms ease,box-shadow 160ms ease,translate 160ms ease}card:hover{translate:0 -2px}[data-component-part=card-icon]{color:var(--rg-accent);background:var(--rg-accent-soft);padding:7px}[data-component-part=card-title]{font-weight:700;letter-spacing:-.01em}[data-component-part=card-content]{color:var(--rg-ink-muted)}callout{border-inline-start-width:3px}code-block{overflow:hidden}callout,code-block,code-group,tabs,tree{border-radius:var(--rg-radius-card)}accordion,pagination-next,pagination-prev{border-radius:var(--rg-radius-card);transition:border-color 140ms ease}accordion:hover{border-color:var(--rg-border-strong)}accordion-group accordion+accordion{margin-top:8px}steps{--rg-step-rail:var(--rg-border)}step{padding-bottom:4px}tree{padding:12px 14px;font-size:13.5px}tree-folder{font-weight:600}pagination-next,pagination-prev{transition:border-color 140ms ease,box-shadow 140ms ease}card:hover,pagination-next:hover,pagination-prev:hover{border-color:var(--rg-border-strong);box-shadow:var(--rg-shadow-hover)}#footer,footer{border-top:1px solid var(--rg-border)}advanced-footer{padding-block:48px 32px}#footer h3,#footer h4,advanced-footer h3,advanced-footer h4{letter-spacing:var(--rg-eyebrow-tracking);color:var(--rg-ink)}#footer a,advanced-footer a{color:var(--rg-ink-muted);text-decoration-color:transparent;transition:color 140ms ease}.dark .rg-hero,.rg-hero,tree{background:var(--rg-surface-raised)}.rg-hero,accordion,code-block,pagination-next,pagination-prev,tree{border:1px solid var(--rg-border)}.rg-hero{position:relative;overflow:hidden;border-radius:var(--rg-radius-lg);padding:40px 32px;margin-bottom:8px;box-shadow:inset 0 1px 0 rgba(255,255,255,.35)}.dark .rg-hero{box-shadow:inset 0 1px 0 rgba(244,224,155,.04)}#footer h3,#footer h4,.rg-facts li,.rg-hero-eyebrow,advanced-footer h3,advanced-footer h4{font-size:var(--rg-eyebrow-size);font-weight:700;text-transform:uppercase}.rg-hero-eyebrow{display:inline-block;letter-spacing:var(--rg-eyebrow-tracking);color:var(--rg-accent);margin-bottom:10px}.rg-hero .rg-hero-title,.rg-hero h1{font-size:clamp(28px,4vw,40px);font-weight:800;line-height:1.1;letter-spacing:-.02em;color:var(--rg-ink);margin:0 0 10px}.rg-hero-lead{font-size:16px;line-height:1.6;color:var(--rg-ink-muted);max-width:62ch;margin:0}.rg-facts{display:flex;flex-wrap:wrap;gap:8px;margin:16px 0 0;padding:0;list-style:none}.rg-facts li{letter-spacing:1px;color:var(--rg-ink-muted);background:var(--rg-surface);border:1px solid var(--rg-border);border-radius:var(--rg-radius-pill);padding:5px 12px}:where(a, button, summary, [tabindex]):focus-visible{outline:2px solid var(--rg-accent);outline-offset:2px;border-radius:var(--rg-radius)}@media (prefers-reduced-motion:reduce){*,::after,::before{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important;scroll-behavior:auto!important}card:hover,pagination-next:hover,pagination-prev:hover{translate:none;box-shadow:none}}@media print{#footer,#navbar,#sidebar-content,feedback-toolbar,footer,pagination-next,pagination-prev,toc{display:none!important}.mdx-content table,mdx-content table{border-color:#999}}"}],"page":{"pagePath":"content/docs/pages-and-routes","slug":"/content/docs/pages-and-routes","pageMetadata":{"title":"Pages \u0026 Routes","description":"Complete map of all 104 pages and API routes in the Royal Glow platform.","icon":"route","href":"/content/docs/pages-and-routes"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Complete map of all 104 pages and API routes in the Royal Glow platform.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={code:`code`,p:`p`,strong:`strong`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,..._provideComponents(),...props.components},{Card,Columns,Heading,Info,Tab,Table,Tabs}=_components;if(!Card)_missingMdxReference(`Card`,true);if(!Columns)_missingMdxReference(`Columns`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Info)_missingMdxReference(`Info`,true);if(!Tab)_missingMdxReference(`Tab`,true);if(!Table)_missingMdxReference(`Table`,true);if(!Tabs)_missingMdxReference(`Tabs`,true);return _jsxs(_Fragment,{children:[_jsxs(_components.p,{children:[`The platform spans two Next.js apps: the customer site `,_jsx(_components.code,{children:`@rgss/web`}),` (`,_jsx(_components.code,{children:`theroyalglow.in`}),`) and the admin portal `,_jsx(_components.code,{children:`@rgss/admin`}),` (`,_jsx(_components.code,{children:`admin.theroyalglow.in`}),`). Together they cover ~104 pages plus the API layer.`]}),`\n`,_jsx(Info,{children:_jsxs(_components.p,{children:[`The customer site uses Next.js App Router `,_jsx(_components.strong,{children:`route groups`}),` (folders in parentheses) to share a layout without affecting the URL. The admin portal is a `,_jsx(_components.strong,{children:`separate app`}),` served from `,_jsx(_components.code,{children:`admin.theroyalglow.in`}),` at root paths — the subdomain provides the admin namespace, so there is no `,_jsx(_components.code,{children:`/admin`}),` prefix. Legacy `,_jsx(_components.code,{children:`theroyalglow.in/admin/*`}),` paths 301-redirect to the subdomain. Staff self-service lives at `,_jsx(_components.code,{children:`/me/*`}),` within the admin app. Admin routes are RBAC-gated; everything else is public or customer-authenticated.`]})}),`\n`,_jsxs(Heading,{level:`2`,id:`route-groups-@rgss/web-—-theroyalglow-in`,children:[`Route Groups (`,_jsx(_components.code,{children:`@rgss/web`}),` — `,_jsx(_components.code,{children:`theroyalglow.in`}),`)`]}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Group`}),_jsx(_components.th,{children:`URL Pattern`}),_jsx(_components.th,{children:`Layout`}),_jsx(_components.th,{children:`Auth`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`(customer)`})}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`/`}),`, `,_jsx(_components.code,{children:`/services`}),`, `,_jsx(_components.code,{children:`/bookings`}),`, etc.`]}),_jsx(_components.td,{children:`Header + footer + nav`}),_jsx(_components.td,{children:`Optional`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`(auth)`})}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`/sign-in`}),`, `,_jsx(_components.code,{children:`/onboarding`})]}),_jsx(_components.td,{children:`Minimal centered card`}),_jsx(_components.td,{children:`—`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`(landing)`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`/book`})}),_jsx(_components.td,{children:`No nav — conversion-optimised`}),_jsx(_components.td,{children:`—`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`(legal)`})}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`/privacy`}),`, `,_jsx(_components.code,{children:`/terms`}),`, `,_jsx(_components.code,{children:`/refund-policy`})]}),_jsx(_components.td,{children:`Minimal`}),_jsx(_components.td,{children:`—`})]})]})]}),`\n`,_jsxs(_components.p,{children:[`The admin portal (`,_jsx(_components.code,{children:`@rgss/admin`}),`, `,_jsx(_components.code,{children:`admin.theroyalglow.in`}),`) is a standalone app: admin pages at root paths under a sidebar + RBAC layout (`,_jsx(_components.code,{children:`receptionist+`}),`), and staff self-service pages at `,_jsx(_components.code,{children:`/me/*`}),` (`,_jsx(_components.code,{children:`staff+`}),`).`]}),`\n`,_jsx(Heading,{level:`2`,id:`page-\u0026-api-map`,children:`Page \u0026 API Map`}),`\n`,_jsx(_components.p,{children:`Select an area of the platform.`}),`\n`,_jsxs(Tabs,{children:[_jsxs(Tab,{title:`Customer`,id:`customer`,\"data-child-heading-ids\":`[\"public-no-auth-required\",\"authenticated-customer\",\"auth-pages\",\"landing-%26-legal-ssg\"]`,children:[_jsx(Heading,{level:`3`,id:`public-no-auth-required`,children:`Public (No Auth Required)`}),_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Route`}),_jsx(_components.th,{children:`Page`}),_jsx(_components.th,{children:`Rendering`}),_jsx(_components.th,{children:`Notes`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{\"data-numeric\":`true`,children:_jsx(_components.code,{children:`/`})}),_jsx(_components.td,{children:`Homepage`}),_jsx(_components.td,{children:`SSR`}),_jsx(_components.td,{children:`Hero, services overview, reviews, booking CTA`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/services`})}),_jsx(_components.td,{children:`Services`}),_jsx(_components.td,{children:`SSR`}),_jsx(_components.td,{children:`Salon/SPA toggle, category filter, service cards`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/services/[slug]`})}),_jsx(_components.td,{children:`Service Detail`}),_jsx(_components.td,{children:`SSG + ISR`}),_jsx(_components.td,{children:`Individual service with booking CTA`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/about`})}),_jsx(_components.td,{children:`About`}),_jsx(_components.td,{children:`SSG`}),_jsx(_components.td,{children:`Story, team gallery`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/contact`})}),_jsx(_components.td,{children:`Contact`}),_jsx(_components.td,{children:`SSG`}),_jsx(_components.td,{children:`Map, phone, email, contact form`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/faq`})}),_jsx(_components.td,{children:`FAQ`}),_jsx(_components.td,{children:`SSG`}),_jsx(_components.td,{children:`FAQPage JSON-LD, accordion`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/gallery`})}),_jsx(_components.td,{children:`Gallery`}),_jsx(_components.td,{children:`SSR`}),_jsx(_components.td,{children:`Photo grid from Payload CMS`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/offers`})}),_jsx(_components.td,{children:`Offers`}),_jsx(_components.td,{children:`SSR`}),_jsx(_components.td,{children:`Active offers and combos`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/blog`})}),_jsx(_components.td,{children:`Blog`}),_jsx(_components.td,{children:`SSR + ISR`}),_jsx(_components.td,{children:`Posts from Payload CMS`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/blog/[slug]`})}),_jsx(_components.td,{children:`Blog Post`}),_jsx(_components.td,{children:`SSG + ISR`}),_jsx(_components.td,{children:`Individual post with BlogPosting JSON-LD`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/offline`})}),_jsx(_components.td,{children:`Offline`}),_jsx(_components.td,{children:`Static`}),_jsx(_components.td,{children:`PWA offline fallback page`})]})]})]}),_jsx(Heading,{level:`3`,id:`authenticated-customer`,children:`Authenticated (Customer)`}),_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Route`}),_jsx(_components.th,{children:`Page`}),_jsx(_components.th,{children:`Notes`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/bookings`})}),_jsx(_components.td,{children:`My Bookings`}),_jsx(_components.td,{children:`Upcoming + past, cancel/reschedule`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/bookings/[id]`})}),_jsx(_components.td,{children:`Booking Detail`}),_jsx(_components.td,{children:`Status timeline, services, invoice link`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/membership`})}),_jsx(_components.td,{children:`My Membership`}),_jsx(_components.td,{children:`Tier, hours remaining, session history`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/gems`})}),_jsx(_components.td,{children:`Gems`}),_jsx(_components.td,{children:`Balance, transaction history, catalogue`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/favorites`})}),_jsx(_components.td,{children:`Favourites`}),_jsx(_components.td,{children:`Saved favourite services`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/notifications`})}),_jsx(_components.td,{children:`Notifications`}),_jsx(_components.td,{children:`Notification list, mark read`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/profile`})}),_jsx(_components.td,{children:`Profile`}),_jsx(_components.td,{children:`Editable fields, notification preferences`})]})]})]}),_jsx(Heading,{level:`3`,id:`auth-pages`,children:`Auth Pages`}),_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Route`}),_jsx(_components.th,{children:`Page`}),_jsx(_components.th,{children:`Notes`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/sign-in`})}),_jsx(_components.td,{children:`Sign In`}),_jsx(_components.td,{children:`Google OAuth button`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/onboarding`})}),_jsx(_components.td,{children:`Onboarding`}),_jsx(_components.td,{children:`First-time profile setup (name, phone, DOB, gender, consents)`})]})]})]}),_jsx(Heading,{level:`3`,id:`landing-\u0026-legal-ssg`,children:`Landing \u0026 Legal (SSG)`}),_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Route`}),_jsx(_components.th,{children:`Page`}),_jsx(_components.th,{children:`Notes`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/book`})}),_jsx(_components.td,{children:`Lead Capture`}),_jsx(_components.td,{children:`Meta/Instagram ad landing page — 3-field form, no nav`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/privacy`})}),_jsx(_components.td,{children:`Privacy Policy`}),_jsx(_components.td,{children:`DPDP Act 2023`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/terms`})}),_jsx(_components.td,{children:`Terms of Service`}),_jsx(_components.td,{children:`—`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/refund-policy`})}),_jsx(_components.td,{children:`Refund \u0026 Cancellation Policy`}),_jsx(_components.td,{children:`—`})]})]})]})]}),_jsxs(Tab,{title:`Admin Portal`,id:`admin-portal`,children:[_jsxs(_components.p,{children:[`All admin routes are served from `,_jsx(_components.code,{children:`admin.theroyalglow.in`}),` at `,_jsx(_components.strong,{children:`root paths`}),` (no `,_jsx(_components.code,{children:`/admin`}),` prefix) and require authentication with minimum role `,_jsx(_components.code,{children:`receptionist`}),`. The paths below are relative to `,_jsx(_components.code,{children:`admin.theroyalglow.in`}),`.`]}),_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Route`}),_jsx(_components.th,{children:`Min. Role`}),_jsx(_components.th,{children:`Page`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{\"data-numeric\":`true`,children:_jsx(_components.code,{children:`/`})}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Dashboard — today’s bookings, revenue, pending actions`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/bookings`})}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Booking list with filters`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/bookings/[id]`})}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Booking detail — approve/reject/assign/complete`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/bookings/new`})}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Walk-in booking creation`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/customers`})}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Customer list — search, filter, sort by LTV`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/customers/[id]`})}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Customer profile — history, notes, tags`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/leads`})}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Lead pipeline — kanban view`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/leads/[id]`})}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Lead detail — notes, UTM, WhatsApp link`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/memberships`})}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Membership list`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/memberships/[id]`})}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Membership detail — session recording`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/memberships/new`})}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Create new membership`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/billing`})}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Invoice list and detail`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/billing/[id]`})}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Invoice detail`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/leave`})}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Leave request queue — approve/reject`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/waitlist`})}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Waitlist management`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/services`})}),_jsx(_components.td,{children:`Manager`}),_jsxs(_components.td,{children:[`Redirect to the Payload CMS `,_jsx(_components.code,{children:`service`}),` collection — the catalogue is authored in the CMS, not the admin portal`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/offers`})}),_jsx(_components.td,{children:`Manager`}),_jsx(_components.td,{children:`Offer creation and management`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/staff`})}),_jsx(_components.td,{children:`Manager`}),_jsx(_components.td,{children:`Staff list and profiles`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/schedule`})}),_jsx(_components.td,{children:`Manager`}),_jsx(_components.td,{children:`Weekly staff availability grid`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/reports`})}),_jsx(_components.td,{children:`Manager`}),_jsx(_components.td,{children:`Revenue, bookings, staff performance`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/settings`})}),_jsx(_components.td,{children:`Manager`}),_jsx(_components.td,{children:`System settings`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/branches`})}),_jsx(_components.td,{children:`Owner`}),_jsx(_components.td,{children:`Branch management`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/users`})}),_jsx(_components.td,{children:`Owner`}),_jsx(_components.td,{children:`User management and role assignment`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/integrations`})}),_jsx(_components.td,{children:`Developer`}),_jsx(_components.td,{children:`Integration configuration`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/logs`})}),_jsx(_components.td,{children:`Developer`}),_jsx(_components.td,{children:`Audit logs`})]})]})]})]}),_jsxs(Tab,{title:`Staff Portal`,id:`staff-portal`,children:[_jsxs(_components.p,{children:[`Staff self-service pages live at `,_jsx(_components.code,{children:`/me/*`}),` within the admin app (`,_jsx(_components.code,{children:`admin.theroyalglow.in`}),`).`]}),_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Route`}),_jsx(_components.th,{children:`Min. Role`}),_jsx(_components.th,{children:`Page`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/me/schedule`})}),_jsx(_components.td,{children:`Staff`}),_jsx(_components.td,{children:`Own weekly schedule`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/me/leave`})}),_jsx(_components.td,{children:`Staff`}),_jsx(_components.td,{children:`Submit and view own leave requests`})]})]})]})]}),_jsxs(Tab,{title:`API`,id:`api`,\"data-child-heading-ids\":`[\"public-no-auth-%E2%80%94-theroyalglow-in\",\"authenticated-customer-%E2%80%94-theroyalglow-in\",\"admin-role-gated-%E2%80%94-admin-theroyalglow-in\"]`,children:[_jsxs(_components.p,{children:[`Customer API routes (below) are served from `,_jsx(_components.code,{children:`theroyalglow.in/api/*`}),` by `,_jsx(_components.code,{children:`@rgss/web`}),`. Admin API routes are served from `,_jsx(_components.code,{children:`admin.theroyalglow.in/api/*`}),` by `,_jsx(_components.code,{children:`@rgss/admin`}),` — there is `,_jsxs(_components.strong,{children:[`no `,_jsx(_components.code,{children:`/api/admin/`}),` segment`]}),`.`]}),_jsxs(Heading,{level:`3`,id:`public-no-auth-—-theroyalglow-in`,children:[`Public (No Auth) — `,_jsx(_components.code,{children:`theroyalglow.in`})]}),_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Endpoint`}),_jsx(_components.th,{children:`Method`}),_jsx(_components.th,{children:`Description`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/services`})}),_jsx(_components.td,{children:`GET`}),_jsx(_components.td,{children:`Active categories + services, read directly from Neon through Drizzle (no Redis cache; 5-minute Upstash cache planned)`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/services/[slug]`})}),_jsx(_components.td,{children:`GET`}),_jsx(_components.td,{children:`Single active service detail, read directly from Neon through Drizzle`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/availability`})}),_jsx(_components.td,{children:`GET`}),_jsxs(_components.td,{children:[`Generic 30-minute grid for `,_jsx(_components.code,{children:`date`}),` + `,_jsx(_components.code,{children:`branchId`}),`, built from Neon-backed business-hours settings; booking/staff/leave/holiday conflicts are not wired yet`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/leads`})}),_jsx(_components.td,{children:`POST`}),_jsxs(_components.td,{children:[`Campaign lead capture from `,_jsx(_components.code,{children:`/book`}),` form`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/health`})}),_jsx(_components.td,{children:`GET`}),_jsx(_components.td,{children:`System health check`})]})]})]}),_jsxs(Heading,{level:`3`,id:`authenticated-customer-—-theroyalglow-in`,children:[`Authenticated (Customer) — `,_jsx(_components.code,{children:`theroyalglow.in`})]}),_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Endpoint`}),_jsx(_components.th,{children:`Method`}),_jsx(_components.th,{children:`Description`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/bookings`})}),_jsx(_components.td,{children:`GET, POST`}),_jsx(_components.td,{children:`List bookings / create booking`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/bookings/[id]`})}),_jsx(_components.td,{children:`GET`}),_jsx(_components.td,{children:`Booking detail`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/bookings/[id]/cancel`})}),_jsx(_components.td,{children:`POST`}),_jsx(_components.td,{children:`Cancel booking`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/bookings/[id]/reschedule`})}),_jsx(_components.td,{children:`POST`}),_jsx(_components.td,{children:`Reschedule booking`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/membership`})}),_jsx(_components.td,{children:`GET`}),_jsx(_components.td,{children:`Customer’s active membership`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/gems`})}),_jsx(_components.td,{children:`GET`}),_jsx(_components.td,{children:`Gems balance + catalogue`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/gems/redeem`})}),_jsx(_components.td,{children:`POST`}),_jsx(_components.td,{children:`Redeem gems against a catalogue service`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/offers`})}),_jsx(_components.td,{children:`GET`}),_jsx(_components.td,{children:`Active offers for the customer`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/contact`})}),_jsx(_components.td,{children:`POST`}),_jsx(_components.td,{children:`Contact form submission`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/notifications`})}),_jsx(_components.td,{children:`GET, PATCH`}),_jsx(_components.td,{children:`Notifications list + mark read`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/profile/preferences`})}),_jsx(_components.td,{children:`PATCH`}),_jsx(_components.td,{children:`Update notification preferences`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/push/subscribe`})}),_jsx(_components.td,{children:`POST`}),_jsx(_components.td,{children:`Register push subscription`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/push/subscribe`})}),_jsx(_components.td,{children:`DELETE`}),_jsx(_components.td,{children:`Remove push subscription`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/ably/token`})}),_jsx(_components.td,{children:`POST`}),_jsx(_components.td,{children:`Scoped Ably JWT (Token Auth)`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/onboarding/complete`})}),_jsx(_components.td,{children:`POST`}),_jsx(_components.td,{children:`Save onboarding data`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/revalidate`})}),_jsx(_components.td,{children:`POST`}),_jsx(_components.td,{children:`On-demand ISR revalidation`})]})]})]}),_jsxs(Heading,{level:`3`,id:`admin-role-gated-—-admin-theroyalglow-in`,children:[`Admin (Role-Gated) — `,_jsx(_components.code,{children:`admin.theroyalglow.in`})]}),_jsxs(_components.p,{children:[`Served from `,_jsx(_components.code,{children:`admin.theroyalglow.in/api/*`}),`. There is no `,_jsx(_components.code,{children:`/api/admin/`}),` segment — the subdomain is the namespace. Paths below are relative to `,_jsx(_components.code,{children:`admin.theroyalglow.in`}),`.`]}),_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Endpoint`}),_jsx(_components.th,{children:`Method`}),_jsx(_components.th,{children:`Min. Role`}),_jsx(_components.th,{children:`Description`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/bookings`})}),_jsx(_components.td,{children:`GET, POST`}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`List / create booking`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/bookings/new`})}),_jsx(_components.td,{children:`POST`}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Walk-in booking creation`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/bookings/[id]`})}),_jsx(_components.td,{children:`PATCH`}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Approve, reject, assign staff`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/bookings/[id]/complete`})}),_jsx(_components.td,{children:`POST`}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Mark completed + invoice + gems`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/bookings/[id]/noshow`})}),_jsx(_components.td,{children:`POST`}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Mark no-show`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/customers`})}),_jsx(_components.td,{children:`GET`}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Customer list with search/filter`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/customers/[id]`})}),_jsx(_components.td,{children:`GET`}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Customer detail`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/customers/[id]/notes`})}),_jsx(_components.td,{children:`POST`}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Add CRM note`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/customers/[id]/tags`})}),_jsx(_components.td,{children:`POST`}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Add tag`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/customers/[id]/tags/[tagId]`})}),_jsx(_components.td,{children:`DELETE`}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Remove tag`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/leads`})}),_jsx(_components.td,{children:`GET, POST`}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Lead list / create manual lead`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/leads/[id]`})}),_jsx(_components.td,{children:`PATCH`}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Update lead status`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/leads/[id]/notes`})}),_jsx(_components.td,{children:`POST`}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Add lead note`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/billing`})}),_jsx(_components.td,{children:`GET`}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Invoice list`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/billing/[id]`})}),_jsx(_components.td,{children:`GET`}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Invoice detail`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/memberships`})}),_jsx(_components.td,{children:`GET, POST`}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`List / create membership`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/memberships/[id]`})}),_jsx(_components.td,{children:`GET`}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Membership detail`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/memberships/[id]/sessions`})}),_jsx(_components.td,{children:`POST`}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Record session`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/memberships/[id]/cancel`})}),_jsx(_components.td,{children:`POST`}),_jsx(_components.td,{children:`Manager`}),_jsx(_components.td,{children:`Cancel membership`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/membership-tiers`})}),_jsx(_components.td,{children:`GET`}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`SPA membership tiers`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/leave`})}),_jsx(_components.td,{children:`GET, POST`}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Leave queue / submit leave`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/leave/[id]`})}),_jsx(_components.td,{children:`PATCH`}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Approve / reject leave`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/me/leave`})}),_jsx(_components.td,{children:`GET, POST`}),_jsx(_components.td,{children:`Staff`}),_jsx(_components.td,{children:`Own leave list / submit`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/me/leave/[id]`})}),_jsx(_components.td,{children:`PATCH`}),_jsx(_components.td,{children:`Staff`}),_jsx(_components.td,{children:`Update own leave`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/me/schedule`})}),_jsx(_components.td,{children:`GET`}),_jsx(_components.td,{children:`Staff`}),_jsx(_components.td,{children:`Own schedule`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/schedule`})}),_jsx(_components.td,{children:`GET`}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Staff schedule for date`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/waitlist`})}),_jsx(_components.td,{children:`GET, POST`}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Waitlist list / add`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/waitlist/[id]`})}),_jsx(_components.td,{children:`PATCH, DELETE`}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Update / remove waitlist entry`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/tags`})}),_jsx(_components.td,{children:`GET`}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Available CRM tags`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/notifications`})}),_jsx(_components.td,{children:`GET, PATCH`}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Notifications list + mark read`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/offers`})}),_jsx(_components.td,{children:`GET, POST`}),_jsx(_components.td,{children:`Manager`}),_jsx(_components.td,{children:`List / create offer`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/offers/[id]`})}),_jsx(_components.td,{children:`PATCH, DELETE`}),_jsx(_components.td,{children:`Manager`}),_jsx(_components.td,{children:`Update / delete offer`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/services`})}),_jsx(_components.td,{children:`GET, POST`}),_jsx(_components.td,{children:`Manager`}),_jsx(_components.td,{children:`Service list / create`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/services/all`})}),_jsx(_components.td,{children:`GET`}),_jsx(_components.td,{children:`Manager`}),_jsx(_components.td,{children:`All services (incl. inactive)`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/services/[id]`})}),_jsx(_components.td,{children:`PATCH, DELETE`}),_jsx(_components.td,{children:`Manager`}),_jsx(_components.td,{children:`Update / delete service`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/service-categories`})}),_jsx(_components.td,{children:`GET, POST`}),_jsx(_components.td,{children:`Manager`}),_jsx(_components.td,{children:`Category list / create`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/service-categories/[id]`})}),_jsx(_components.td,{children:`PATCH, DELETE`}),_jsx(_components.td,{children:`Manager`}),_jsx(_components.td,{children:`Update / delete category`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/staff`})}),_jsx(_components.td,{children:`GET, POST`}),_jsx(_components.td,{children:`Manager`}),_jsx(_components.td,{children:`Staff list / create`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/staff/all`})}),_jsx(_components.td,{children:`GET`}),_jsx(_components.td,{children:`Manager`}),_jsx(_components.td,{children:`All staff`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/staff/[id]`})}),_jsx(_components.td,{children:`GET, PATCH`}),_jsx(_components.td,{children:`Manager`}),_jsx(_components.td,{children:`Staff detail / update`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/staff/[id]/services`})}),_jsx(_components.td,{children:`GET, PATCH`}),_jsx(_components.td,{children:`Manager`}),_jsx(_components.td,{children:`Staff service assignments`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/reports`})}),_jsx(_components.td,{children:`GET`}),_jsx(_components.td,{children:`Manager`}),_jsx(_components.td,{children:`Reports data`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/branches`})}),_jsx(_components.td,{children:`GET`}),_jsx(_components.td,{children:`Manager`}),_jsx(_components.td,{children:`Branch list`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/branches/[id]`})}),_jsx(_components.td,{children:`PATCH`}),_jsx(_components.td,{children:`Owner`}),_jsx(_components.td,{children:`Update branch`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/settings`})}),_jsx(_components.td,{children:`GET, PATCH`}),_jsx(_components.td,{children:`Manager`}),_jsx(_components.td,{children:`System settings`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/users`})}),_jsx(_components.td,{children:`GET`}),_jsx(_components.td,{children:`Owner`}),_jsx(_components.td,{children:`User list / role management`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/integrations`})}),_jsx(_components.td,{children:`GET`}),_jsx(_components.td,{children:`Developer`}),_jsx(_components.td,{children:`Integration configuration`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/logs`})}),_jsx(_components.td,{children:`GET`}),_jsx(_components.td,{children:`Developer`}),_jsx(_components.td,{children:`Audit logs`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/health`})}),_jsx(_components.td,{children:`GET`}),_jsx(_components.td,{children:`—`}),_jsx(_components.td,{children:`Admin health check`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/ably/token`})}),_jsx(_components.td,{children:`POST`}),_jsx(_components.td,{children:`Receptionist`}),_jsx(_components.td,{children:`Scoped Ably JWT (Token Auth)`})]})]})]})]}),_jsxs(Tab,{title:`Background Jobs`,id:`background-jobs`,\"data-child-heading-ids\":`[\"scheduled-14-%E2%80%94-qstash\",\"triggered-4-%E2%80%94-qstash%2C-event-driven-with-delay\",\"github-actions-cron-1\"]`,children:[_jsxs(_components.p,{children:[`QStash signature required. Hosted in `,_jsx(_components.code,{children:`@rgss/admin`}),` and served from `,_jsx(_components.code,{children:`admin.theroyalglow.in/api/jobs/*`}),`. `,_jsx(_components.strong,{children:`19 jobs total: 14 QStash scheduled + 4 QStash triggered + 1 GitHub Actions cron.`})]}),_jsx(Heading,{level:`4`,id:`scheduled-14-—-qstash`,children:`Scheduled (14 — QStash)`}),_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Endpoint`}),_jsx(_components.th,{children:`Description`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/jobs/appointment-reminders`})}),_jsx(_components.td,{children:`24h + 1h push + email reminders`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/jobs/membership-expiry`})}),_jsx(_components.td,{children:`30d/7d/1d expiry alerts`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/jobs/birthday-emails`})}),_jsx(_components.td,{children:`Birthday offer emails`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/jobs/membership-usage-nudges`})}),_jsx(_components.td,{children:`Usage nudge emails`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/jobs/lead-followups`})}),_jsx(_components.td,{children:`Stale lead alerts`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/jobs/daily-sales-report`})}),_jsx(_components.td,{children:`Daily report`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/jobs/weekly-report`})}),_jsx(_components.td,{children:`Weekly summary`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/jobs/gems-expiry-reminder`})}),_jsx(_components.td,{children:`7-day gems expiry push`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/jobs/nightly-sales-summary`})}),_jsx(_components.td,{children:`Nightly sales rollup`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/jobs/membership-auto-expire`})}),_jsx(_components.td,{children:`Hard-expire lapsed memberships`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/jobs/offer-auto-expire`})}),_jsx(_components.td,{children:`Expire ended offers`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/jobs/gems-auto-expire`})}),_jsx(_components.td,{children:`Expire gems past 365 days`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/jobs/session-cleanup`})}),_jsx(_components.td,{children:`Purge stale auth sessions`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/jobs/monthly-gst-summary`})}),_jsx(_components.td,{children:`Monthly GST summary`})]})]})]}),_jsx(Heading,{level:`4`,id:`triggered-4-—-qstash-event-driven-with-delay`,children:`Triggered (4 — QStash, event-driven with delay)`}),_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Endpoint`}),_jsx(_components.th,{children:`Trigger`}),_jsx(_components.th,{children:`Description`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/jobs/post-service-followup`})}),_jsx(_components.td,{children:`+24h after completion`}),_jsx(_components.td,{children:`Review request`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/jobs/stale-booking-alert`})}),_jsx(_components.td,{children:`+2h after pending`}),_jsx(_components.td,{children:`Stale pending booking alert`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/jobs/noshow-check`})}),_jsx(_components.td,{children:`+15min after end time`}),_jsx(_components.td,{children:`No-show check`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/jobs/membership-expired-notice`})}),_jsx(_components.td,{children:`+1h after expiry`}),_jsx(_components.td,{children:`Expired notice`})]})]})]}),_jsx(Heading,{level:`4`,id:`github-actions-cron-1`,children:`GitHub Actions cron (1)`}),_jsxs(_components.p,{children:[_jsx(_components.code,{children:`pprd`}),` DB sync — resets the `,_jsx(_components.code,{children:`pprd`}),` Neon branch from `,_jsx(_components.code,{children:`prod`}),` and strips PII. Runs in GitHub Actions, not as an HTTP route.`]}),_jsx(Info,{children:_jsxs(_components.p,{children:[`An internal `,_jsx(_components.code,{children:`/api/jobs/invoice-pdf`}),` route also exists: it hands invoice rendering to the `,_jsx(_components.code,{children:`@rgss/invoicing`}),` Cloud Run PDF service. It is a support route, not one of the 19 scheduled/triggered business jobs.`]})})]}),_jsx(Tab,{title:`Special`,id:`special`,children:_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Route`}),_jsx(_components.th,{children:`Description`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/api/auth/[...all]`})}),_jsx(_components.td,{children:`Better Auth catch-all (login, callback, session, sign-out)`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/llms.txt`})}),_jsx(_components.td,{children:`AI agent discovery file`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/llms-full.txt`})}),_jsx(_components.td,{children:`Detailed AI agent file with full service list`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/sitemap.xml`})}),_jsx(_components.td,{children:`Auto-generated by Next.js`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/robots.txt`})}),_jsx(_components.td,{children:`Auto-generated by Next.js`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/manifest.json`})}),_jsx(_components.td,{children:`PWA manifest`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`/sw.js`})}),_jsx(_components.td,{children:`Service worker (PWA offline support)`})]})]})]})})]}),`\n`,_jsx(Heading,{level:`2`,id:`related-pages`,children:`Related Pages`}),`\n`,_jsxs(Columns,{cols:2,children:[_jsx(Card,{title:`Frontend`,href:`/content/docs/frontend`,children:_jsx(_components.p,{children:`Component architecture and design system behind these pages`})}),_jsx(Card,{title:`API Reference`,href:`/content/docs/api-reference/index`,children:_jsx(_components.p,{children:`Full request/response contracts per endpoint`})}),_jsx(Card,{title:`Background Jobs`,href:`/content/docs/background-jobs`,children:_jsx(_components.p,{children:`Schedules and behaviour of all 19 jobs`})})]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"codeStyling":{"theme":{"light":"gruvbox-light-medium","dark":"gruvbox-dark-medium"}},"config":{},"pageMetadata":{"title":"Pages \u0026 Routes","description":"Complete map of all 104 pages and API routes in the Royal Glow platform.","icon":"route","href":"/content/docs/pages-and-routes"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Route Groups (@rgss/web — theroyalglow.in)","slug":"route-groups-@rgss/web-—-theroyalglow-in","depth":2,"children":[]},{"title":"Page \u0026 API Map","slug":"page-\u0026-api-map","depth":2,"children":[{"title":"Public (No Auth Required)","slug":"public-no-auth-required","depth":3,"children":[],"tabId":"customer"},{"title":"Authenticated (Customer)","slug":"authenticated-customer","depth":3,"children":[],"tabId":"customer"},{"title":"Auth Pages","slug":"auth-pages","depth":3,"children":[],"tabId":"customer"},{"title":"Landing \u0026 Legal (SSG)","slug":"landing-\u0026-legal-ssg","depth":3,"children":[],"tabId":"customer"},{"title":"Public (No Auth) — theroyalglow.in","slug":"public-no-auth-—-theroyalglow-in","depth":3,"children":[],"tabId":"api"},{"title":"Authenticated (Customer) — theroyalglow.in","slug":"authenticated-customer-—-theroyalglow-in","depth":3,"children":[],"tabId":"api"},{"title":"Admin (Role-Gated) — admin.theroyalglow.in","slug":"admin-role-gated-—-admin-theroyalglow-in","depth":3,"children":[],"tabId":"api"},{"title":"Scheduled (14 — QStash)","slug":"scheduled-14-—-qstash","depth":4,"children":[],"tabId":"background-jobs"},{"title":"Triggered (4 — QStash, event-driven with delay)","slug":"triggered-4-—-qstash-event-driven-with-delay","depth":4,"children":[],"tabId":"background-jobs"},{"title":"GitHub Actions cron (1)","slug":"github-actions-cron-1","depth":4,"children":[],"tabId":"background-jobs"}]},{"title":"Related Pages","slug":"related-pages","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"subdomain":"royal-glow-salon-and-spa","siteName":"Royal Glow Salon \u0026 Spa","title":"Pages \u0026 Routes - Royal Glow Salon \u0026 Spa","navMaps":{"firstHrefInVersion":{"Current":{"href":"/content/docs/pages-and-routes","matchLevel":0},"v2":{"href":"/content/docs-v2","matchLevel":3}},"firstHrefInLanguage":{}},"lastModified":"2026-09-01T06:21:13.514Z","gitLastModified":"2026-09-01T05:23:59.000Z","originalFileLocation":"content/docs/pages-and-routes.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"light\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Complete map of all 104 pages and API routes in the Royal Glow platform.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Royal Glow Salon \u0026amp; Spa\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/royal-glow-salon-and-spa/y0ASLgrdkFTEuGkt/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/royal-glow-salon-and-spa/y0ASLgrdkFTEuGkt/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/royal-glow-salon-and-spa/y0ASLgrdkFTEuGkt/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/royal-glow-salon-and-spa/y0ASLgrdkFTEuGkt/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/royal-glow-salon-and-spa/y0ASLgrdkFTEuGkt/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/royal-glow-salon-and-spa/y0ASLgrdkFTEuGkt/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/royal-glow-salon-and-spa/y0ASLgrdkFTEuGkt/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/royal-glow-salon-and-spa/y0ASLgrdkFTEuGkt/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/royal-glow-salon-and-spa/y0ASLgrdkFTEuGkt/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Pages \u0026amp; Routes - Royal Glow Salon \u0026amp; Spa\">\u003cmeta data-mint-head property=\"og:description\" content=\"Complete map of all 104 pages and API routes in the Royal Glow platform.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Royal Glow Salon \u0026amp; Spa Documentation\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.theroyalglow.in/content/docs/pages-and-routes\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://royal-glow-salon-and-spa.mintlify.app/_mintlify/api/og/v2?division=Application+surface\u0026amp;title=Pages+%26+Routes\u0026amp;description=Complete+map+of+all+104+pages+and+API+routes+in+the+Royal+Glow+platform.\u0026amp;theme=9ddabff0b3fd2d31abb74056\u0026amp;signature=de89720474f6650d80e8aae457a258d4b467af249b17f4338f355c6e647a6971\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Pages \u0026amp; Routes - Royal Glow Salon \u0026amp; Spa\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Complete map of all 104 pages and API routes in the Royal Glow platform.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://royal-glow-salon-and-spa.mintlify.app/_mintlify/api/og/v2?division=Application+surface\u0026amp;title=Pages+%26+Routes\u0026amp;description=Complete+map+of+all+104+pages+and+API+routes+in+the+Royal+Glow+platform.\u0026amp;theme=9ddabff0b3fd2d31abb74056\u0026amp;signature=de89720474f6650d80e8aae457a258d4b467af249b17f4338f355c6e647a6971\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/royal-glow-salon-and-spa/y0ASLgrdkFTEuGkt/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Royal Glow Salon \u0026amp; Spa\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#7D5C12\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.theroyalglow.in/content/docs/pages-and-routes\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/content/docs/pages-and-routes.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://theroyalglow.in/#organization\",\"name\":\"Royal Glow Salon \u0026 Spa\",\"url\":\"https://theroyalglow.in\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/royal-glow-salon-and-spa/dS3ivn1eYYDGMU1q/logo/brand.png?fit=max\u0026auto=format\u0026n=dS3ivn1eYYDGMU1q\u0026q=85\u0026s=9850260e71bb5f24f582245caa612a92\"},\"sameAs\":[\"https://github.com/royalglowsalonspa\"]},{\"@type\":\"WebSite\",\"@id\":\"https://docs.theroyalglow.in#website\",\"name\":\"Royal Glow Salon \u0026 Spa\",\"url\":\"https://docs.theroyalglow.in\",\"publisher\":{\"@id\":\"https://theroyalglow.in/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.theroyalglow.in/content/docs/pages-and-routes#webpage\",\"url\":\"https://docs.theroyalglow.in/content/docs/pages-and-routes\",\"name\":\"Pages \u0026 Routes\",\"description\":\"Complete map of all 104 pages and API routes in the Royal Glow platform.\",\"dateModified\":\"2026-09-01T05:23:59.000Z\",\"isPartOf\":{\"@id\":\"https://docs.theroyalglow.in#website\"},\"breadcrumb\":{\"@id\":\"https://docs.theroyalglow.in/content/docs/pages-and-routes#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.theroyalglow.in/content/docs/pages-and-routes#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Royal Glow Salon \u0026 Spa\",\"item\":\"https://docs.theroyalglow.in\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Pages \u0026 Routes\",\"item\":\"https://docs.theroyalglow.in/content/docs/pages-and-routes\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.theroyalglow.in/content/docs/pages-and-routes#article\",\"headline\":\"Pages \u0026 Routes\",\"name\":\"Pages \u0026 Routes\",\"description\":\"Complete map of all 104 pages and API routes in the Royal Glow platform.\",\"url\":\"https://docs.theroyalglow.in/content/docs/pages-and-routes\",\"mainEntityOfPage\":{\"@id\":\"https://docs.theroyalglow.in/content/docs/pages-and-routes#webpage\"},\"dateModified\":\"2026-09-01T05:23:59.000Z\",\"publisher\":{\"@id\":\"https://theroyalglow.in/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.theroyalglow.in#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Royal Glow Salon \u0026 Spa\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Royal Glow Salon \u0026 Spa","nav":{"global":null,"versions":[{"version":"Current","default":true,"tag":"Latest","tabs":[{"tab":"Documentation","icon":"book-open","pages":[{"title":"Documentation","href":"/content/docs"}]},{"tab":"Engineering","icon":"code","groups":[{"group":"Getting started","icon":"rocket","pages":[{"title":"Getting Started","icon":"rocket","href":"/content/docs/getting-started"},{"title":"Tech Stack","icon":"boxes","href":"/content/docs/tech-stack"},{"title":"Architecture","icon":"workflow","href":"/content/docs/architecture"}]},{"group":"System design","icon":"layers","pages":[{"title":"System Design","icon":"layers","href":"/content/docs/system-design/index"},{"title":"High-Level Design","icon":"network","href":"/content/docs/system-design/high-level-design"},{"title":"Low-Level Design","icon":"component","href":"/content/docs/system-design/low-level-design"}]},{"group":"Standards","icon":"shield-check","pages":[{"title":"Conventions","icon":"ruler","href":"/content/docs/conventions"},{"title":"Authentication \u0026 Roles","icon":"key-round","href":"/content/docs/authentication"},{"title":"Data Model","description":"The 38-table Drizzle schema for Royal Glow — conventions, table groupings, enums, and ID formats.","icon":"database","href":"/content/docs/data-model"}]},{"group":"Application surface","icon":"monitor","pages":[{"title":"Pages \u0026 Routes","icon":"route","href":"/content/docs/pages-and-routes"},{"title":"Frontend","description":"Component architecture, design system, styling conventions, and accessibility standards for Royal Glow.","icon":"panels-top-left","href":"/content/docs/frontend"}]},{"group":"Platform","icon":"server","pages":[{"title":"Background Jobs","icon":"timer","href":"/content/docs/background-jobs"},{"title":"Realtime (Ably)","icon":"radio","href":"/content/docs/realtime"},{"title":"Notifications \u0026 Email","icon":"mail","href":"/content/docs/notifications-email"},{"title":"SEO \u0026 AI Visibility","icon":"search","href":"/content/docs/seo"},{"title":"Analytics","icon":"chart-line","href":"/content/docs/analytics"},{"title":"Observability","icon":"radar","href":"/content/docs/observability"}]},{"group":"Quality \u0026 security","icon":"lock","pages":[{"title":"Security","icon":"shield","href":"/content/docs/security"},{"title":"Error Handling","icon":"triangle-alert","href":"/content/docs/error-handling"},{"title":"Testing","icon":"flask-conical","href":"/content/docs/testing"},{"title":"Environment Variables","icon":"sliders-horizontal","href":"/content/docs/environment-variables"}]},{"group":"Operations","icon":"wrench","pages":[{"title":"Deployment","icon":"cloud-upload","href":"/content/docs/deployment"},{"title":"Git Workflow","icon":"git-branch","href":"/content/docs/git-workflow"},{"title":"Data Seeding","icon":"sprout","href":"/content/docs/data-seeding"},{"title":"Operations","icon":"wrench","href":"/content/docs/operations"}]},{"group":"Delivery workflow","icon":"git-pull-request","pages":[{"title":"Engineering Workflow","icon":"workflow","href":"/engineering/index"},{"title":"CI/CD","icon":"gauge","href":"/engineering/ci-cd"},{"title":"Platform Implementation Report","icon":"clipboard-check","href":"/engineering/platform-implementation-report"},{"title":"GitHub Rulesets","icon":"shield-check","href":"/github/rulesets"},{"title":"Security And Coverage","icon":"scan-search","href":"/github/security"},{"title":"Versioning","icon":"tags","href":"/releases/versioning"},{"title":"Release Process","icon":"package-check","href":"/releases/release-please"},{"title":"Changelog","icon":"history","href":"/releases/changelog"}]}]},{"tab":"API reference","icon":"plug","pages":[{"title":"API reference","href":"/content/docs/api-reference"}]}]},{"version":"v2","tag":"Legacy","pages":[{"title":"v2","href":"/content/docs-v2"}]}]},"title":"Pages \u0026 Routes - Royal Glow Salon \u0026 Spa","buildId":"dpl_2oYXwqkEXirXBPk8wV1FtM5USFWi","deploymentId":"dpl_2oYXwqkEXirXBPk8wV1FtM5USFWi","dynamics":[],"chunks":[]}