31 — Product domain surfaces & Beacon
Target hostname map · API on apex · Beacon rebrand · phased cutover · July 2026
CEO Summary
Today most product surfaces share one host (staging.gopastearth.com) with path prefixes (/dashboard, /pos, /admin/signage). The target is a clear product domain structure: dedicated subdomains for operator-facing apps, while all API and shared services stay on the main domain. Digital signage is product-named Beacon (UI: “Beacon Screen”; nav: “Beacon”).
Business value: Cleaner bookmarks for staff and devices, stronger branding per surface, easier CDN/TLS policy per workload, room to grow without path soup. Risk if rushed: Session cookies and CORS break login across hosts — this doc plans that first.
Design principles
- One money spine, many windows. Subdomains are presentation shells. Core Invoicing, inventory, tenants, and auth remain one backend.
- API lives on the main domain. Browsers and devices call
https://gopastearth.com/api/… (and related service paths), not api.pos.gopastearth.com.
- Subdomains are surface routers. Each host loads the SPA entry that belongs there and may deep-link into path routes for compatibility.
- Cookies span the product family. Session cookie domain =
.gopastearth.com so dashboard ↔ POS ↔ KDS share login when appropriate.
- Beacon is the product name for signage. Code may keep
signage packages for a while; user-facing strings and hostnames use Beacon.
Target domain map
flowchart TB
subgraph apex [Main domain — gopastearth.com]
MKT[Marketing public site]
API["/api · /auth · /customer · /media · /health"]
WS["Bridge WebSocket · webhooks"]
end
subgraph product [Product surface subdomains]
DASH[dashboard.gopastearth.com]
POS[pos.gopastearth.com]
KDS[kds.gopastearth.com]
BCN[beacon.gopastearth.com]
BC[barcodes.gopastearth.com]
MS[memestream.gopastearth.com]
end
subgraph platform [Platform / ops hosts — keep]
STG[staging.gopastearth.com]
DOC[dochub.gopastearth.com]
GIT[gperep.gopastearth.com]
end
DASH -->|XHR/fetch cookies| API
POS --> API
KDS --> API
BCN -->|public playlist + assets| API
BC -->|public barcode API| API
MS -->|JSON feed for web + Qt| API
MKT --> API
STG -.->|current all-in-one| API
| Hostname | Audience | Primary UX | Today (path on staging) |
gopastearth.com
www.gopastearth.com |
Public + all clients |
Marketing, signup entry, API & shared services |
public-site + /api on same host |
dashboard.gopastearth.com |
Owners, managers, staff (office) |
Login, Dashboard, Admin, Catalog, Inventory, Reports, Business Hub, Master Admin, HR, Tickets admin, Beacon config |
/login · /dashboard · /admin/* · /inventory · /reports · /master-admin |
pos.gopastearth.com |
Cashiers, floor, mobile handheld browsers |
Modern POS, Mobile POS, register open, kiosk entry (optional) |
/pos · /pos/* · /pos/kiosk |
kds.gopastearth.com |
Kitchen / expo screens |
Kitchen Display System only (fullscreen-friendly) |
/pos/kitchen (and related KDS routes) |
beacon.gopastearth.com |
TVs, lobby players, menu boards |
Beacon Screen public player (playlist loop) |
/{tenant}/signage/{displaySlug} |
barcodes.gopastearth.com |
Public web + GPE merchants |
Barcodes — standalone UPC/EAN/GTIN catalog lookup (same master catalog as POS) |
/barcode on marketing / staging |
memestream.gopastearth.com |
Public web + Dogecoin Qt client |
Meme Stream — scrollable Doge/community feed, Doge of the Day, soft likes; on-chain tips phase 2 |
/memestream on marketing; API /api/public/memestream/* |
staging.gopastearth.com |
Internal QA |
All-in-one host during migration (compat) |
Current production-like environment |
dochub.gopastearth.com |
Engineering / product |
DocHub + OAO |
Already live |
gperep.gopastearth.com |
Engineering |
Gitea |
Already live |
Optional later hosts (not required for first cut)
| Host | Use | Notes |
shop.gopastearth.com or path on apex | Tenant storefronts | Today /{slug}/store; may stay path-based on apex or dashboard-linked |
app.gopastearth.com | Alias → dashboard | Marketing “Open app” CTA |
bridge.gopastearth.com | Documented WS endpoint only | Prefer WS under apex /api/bridges/connect unless ops needs split |
API & shared services on the main domain
All surface subdomains are API consumers. They do not host Express.
Path on gopastearth.com | Service | Used by |
/api/* | REST Business OS (POS, invoices, catalog, Beacon admin API, storefront, HR, …) | All product SPAs, public storefront, Beacon player playlist |
/auth/* | Auth helpers (if mounted separately) | Login flows |
/customer/* | Customer portal API | Customer portal SPA / pages |
/media/* | Static/media (platform catalog images, uploads) | POS, admin, Beacon creatives |
/health | Liveness | LB / ops |
/api/bridges/connect (WS) | On-prem Bridge | Bridge clients |
/api/webhooks/* | Inbound PSP / crypto webhooks | External providers |
/api/signage/* → product docs as Beacon API | Folders, ads, displays, public playlist | Dashboard admin + Beacon players |
Why not api.gopastearth.com first?
Path-based API on the apex keeps one TLS name, simpler cookie pairing with marketing signup, and matches current Nginx mental model
(/api → backend. A dedicated API host can be added later as a CNAME/alias without rewriting business logic.
Frontend env (target)
# Product SPAs (dashboard / pos / kds / beacon builds)
VITE_API_BASE_URL=https://gopastearth.com
# or relative only if SPA is reverse-proxied with /api on same host (staging all-in-one)
# Cookie / CORS (backend)
COOKIE_DOMAIN=.gopastearth.com
CORS_ORIGIN=https://dashboard.gopastearth.com,https://pos.gopastearth.com,https://kds.gopastearth.com,https://beacon.gopastearth.com,https://gopastearth.com,https://www.gopastearth.com,https://staging.gopastearth.com
SESSION_SAME_SITE=None # if cross-site; or Lax if always same-site eTLD+1 with Domain=.gopastearth.com
SESSION_SECURE=true
Beacon (was: Signage / nSign-class service)
| Context | Name |
| Product / marketing | Beacon |
| Page title / H1 | Beacon Screen |
| Dashboard nav label | Beacon (not “Signage & ads”) |
| Hostname | beacon.gopastearth.com |
| Player URL (target) | https://beacon.gopastearth.com/{tenantSlug}/{displaySlug} |
| Player URL (today) | https://staging…/{tenantSlug}/signage/{displaySlug} |
| Admin config (target) | https://dashboard.gopastearth.com/admin/beacon (alias of signage routes) |
| API (stable, code) | GET/POST /api/signage/* initially; optional /api/beacon/* facade later |
Beacon responsibilities
- Player host: fullscreen loop, public playlist fetch, optional
?reloadSec=, offline-friendly cache later
- Admin (on dashboard): folders, creatives (image/video/URL/HTML), named displays, bridge notify
- Bridge: optional
signageUpdate → product docs call this “Beacon refresh push”
Deep technical behavior remains in 26 — Signage & Displays until that chapter is fully retitled; this chapter owns naming + host placement.
Surface → route ownership
| Host | SPA shell serves | Redirects / defaults |
| dashboard |
/dashboard, /admin/*, /inventory/*, /reports/*, /business-hub, /master-admin/*, /hr/*, tickets admin, login |
/ → /dashboard (if session) else /login |
| pos |
/pos, mobile POS, optional kiosk |
/ → /pos; staff without register → open-register flow |
| kds |
Kitchen display only |
/ → KDS home; no admin chrome |
| beacon |
Public player only (minimal chrome) |
/ → help “paste display URL” or device pairing later; /{tenant}/{display} → player |
| apex |
Marketing, pricing, signup; reverse-proxy /api |
CTA “Open dashboard” → dashboard host |
Auth & tenant context across hosts
sequenceDiagram
participant U as User
participant D as dashboard.gopastearth.com
participant A as gopastearth.com/api
participant P as pos.gopastearth.com
U->>D: Login
D->>A: POST /api/auth/login
A-->>D: Set-Cookie session Domain=.gopastearth.com
U->>P: Open POS
P->>A: GET /api/... Cookie sent
A-->>P: 200 tenant-scoped data
- Session cookie:
Domain=.gopastearth.com, Secure, HttpOnly, path /
- CORS: allow product subdomains with
credentials: true
- CSRF: keep existing same-site strategy; re-validate when SameSite=None
- Tenant header: continue
X-Tenant-Slug / session tenant; Beacon player often tenant-in-URL (public playlist)
- Device auth: KDS / POS register may use device tokens independent of platform session — unchanged
Nginx sketch (target)
# Apex — marketing + API
server {
server_name gopastearth.com www.gopastearth.com;
location /api/ { proxy_pass http://127.0.0.1:4000; ... }
location /auth/ { proxy_pass http://127.0.0.1:4000; ... }
location /media/ { proxy_pass http://127.0.0.1:4000; ... }
location /health { proxy_pass http://127.0.0.1:4000; }
location / { proxy_pass http://public_site_or_static; }
}
# Product shells — same frontend build or surface-specific builds
server {
server_name dashboard.gopastearth.com pos.gopastearth.com
kds.gopastearth.com beacon.gopastearth.com;
# SPA fallback
location / { proxy_pass http://127.0.0.1:5173; /* or static dist */ }
# Optional: do NOT proxy /api here — force clients to apex (clear separation)
}
# Compat during migration
server {
server_name staging.gopastearth.com;
# Keep today's path-based all-in-one until cutover complete
}
TLS: wildcard *.gopastearth.com + apex, or individual certs via Certbot. Prefer wildcard for product subdomains.
DNS: A/AAAA for apex + each host (or CNAME to load balancer) → current edge IP.
Build / deploy strategy
| Option | Description | When |
| A. Single SPA + host-based entry |
One frontend build; on boot read window.location.hostname and route to dashboard / pos / kds / beacon shell |
Recommended first — lowest fork cost |
| B. Multi-entry Vite builds |
dashboard.html, pos.html, kds.html, beacon.html smaller bundles |
After traffic justifies split |
| C. Separate repos |
Not recommended — shared components and auth would diverge |
Avoid |
Host-based entry (Option A) — logic sketch
const host = window.location.hostname;
if (host.startsWith('pos.')) defaultRoute = '/pos';
if (host.startsWith('kds.')) defaultRoute = '/pos/kitchen'; // confirm actual path
if (host.startsWith('beacon.')) defaultRoute = beaconPlayerFromPath();
if (host.startsWith('dashboard.') || host === 'app.') defaultRoute = '/dashboard';
// API base always https://gopastearth.com (prod) or staging for QA
Phased delivery plan
Phase 0 — Document & decide (this chapter)
- Lock hostnames, Beacon naming, API-on-apex rule
- Inventory all absolute links that hardcode
staging.gopastearth.com paths
Phase 1 — DNS + TLS + Nginx skeletons
- Create DNS records for
dashboard, pos, kds, beacon (+ apex if not live)
- Wildcard or multi-SAN cert
- Nginx server blocks; initially all proxy to current SPA + still allow path mode on staging
Phase 2 — Auth hardens for multi-host
COOKIE_DOMAIN=.gopastearth.com
- CORS allowlist of product hosts
- Frontend
VITE_API_BASE_URL (or runtime config) pointing at apex
- Smoke: login on dashboard → open POS host still authenticated
Phase 3 — Surface defaults + Beacon rebrand (UI)
- Host-based default routes
- Nav: “Beacon”; page: “Beacon Screen”; player URLs show beacon host in admin copy
- Redirect helpers:
/admin/signage → /admin/beacon (alias)
Phase 4 — Storefront & public on apex
- Marketing +
/{slug}/store (or shop subdomain later)
- Signup completion → dashboard host
Phase 5 — Deprecate path-only mental model on staging
- staging remains all-in-one for QA
- Production traffic prefers product hosts
- Update bridge docs, device bookmarks, Beacon display URL generator
Cutover checklist
| Item | Owner | Done when |
| DNS A/CNAME for four product hosts | Ops | dig resolves |
| TLS cert covers hosts | Ops | HTTPS green |
| Nginx vhosts live | Ops | SPA loads per host |
| Session cookie Domain | Backend | Cross-subdomain login works |
| CORS list | Backend | No browser CORS errors with credentials |
| API base URL config | Frontend | Network tab shows apex API |
| Beacon labels + URLs | Frontend | Admin shows beacon. host |
| KDS bookmark test | QA | Kitchen screen cold-boot works |
| POS register open | QA | PIN flow on pos. host |
| DocHub / OAO updated | Docs | This chapter + DocHub 13/31 |
Non-goals (for this initiative)
- Splitting databases per surface
- Separate backend processes per subdomain (unless scale forces it later)
- Replacing Bridge with a cloud-only LAN story
- Forcing storefront onto
shop. before apex path works
- Immediate full rename of every
signage code symbol (UI + host first; code aliases second)
Glossary snippet
| Term | Meaning |
| Surface | A branded hostname + SPA entry focused on one job (POS, KDS, …) |
| Apex / main domain | gopastearth.com — marketing + API/services |
| Beacon | Product name for digital display / menu-board system |
| Beacon Screen | Full product name on admin/player pages |
| Signage (legacy) | Code paths and chapter 26 title; synonymous with Beacon until rename completes |