30 — Full-stack architecture

Go Past Earth (legacy codebase: PAWSPOS / pawspos) • Site-wide wiring • April 2026

CEO summary

This page is the single scroll of diagrams for how the platform is assembled: clients, edge, API process, databases, on-site Bridge, and major API groups. It complements Master Map (narrative layers) and INDEX.md (doc map). For exhaustive HTTP mounts, use Appendix: Route Table and API Explorer.

Markdown companion: 30-FULL-STACK-ARCHITECTURE.md (text summary; diagrams render here only).

Legend and naming

TermMeaning
Go Past EarthCustomer-facing product name; production host gopastearth.com.
PAWSPOS / pawsposHistorical project name; repo paths, PM2 names, cookie prefix may still use it.
TenantOne business customer; identified by slug, IDs in session or headers.
Master DBShared MySQL: Tenants, platform Users, platform_product_catalog, etc.
Tenant main DBMYSQL_TENANT_DB_PREFIX + slug (e.g. dev-sawyer-farms) — Staff, POS, orders, inventory, …
Tenant HR DBdev-hr-{slug} via multiDatabaseManager — payroll employees, W-4, etc.
Express staticProduction serves frontend/dist from backend/server.js so one process can ship the SPA.

1. Deployment and runtime

Typical staging/production: browsers hit Nginx (TLS); Nginx proxies API and static to Node. PM2 may run the backend only (SPA from dist) or also separate Vite dev servers for development-style hosting — your infrastructure/ecosystem.production.config.js describes the full process list.

flowchart TB subgraph clients [Client layer] BR["Browser: admin POS staff business-hub"] PUB["Public: marketing signup"] SIG["Signage: fullscreen player"] end subgraph edge [Edge] NX[Nginx TLS and routing] end subgraph host [Application host PM2] BE["Node Express server.js :4000"] VFE["Vite dashboard dev :5173"] VPS["Vite public-site dev :5174"] end subgraph sqltier [MySQL] MDB[(Master)] TDB[(Tenant per slug)] end subgraph site [On-site optional] BRG[Bridge WebSocket client] HW["LAN: printers KDS tablets"] end BR --> NX PUB --> NX SIG --> NX NX --> BE NX -.-> VFE NX -.-> VPS BE --> MDB BE --> TDB BE <-->|WSS bridge| BRG BRG --> HW

2. Data plane

Application code chooses a pool via slug or tenant id: getTenantConnection(slug, main) for the operational tenant database; dbManager.getConnection(tenantId, HR) resolves dev-hr-{slug} after master lookup. Analytics DBs follow MYSQL_ANALYTICS_DB_PREFIX.

flowchart LR subgraph master [Master MySQL] TEN[Tenants slug plan] USR[Users and org linkage] PLC[platform_product_catalog] end subgraph tmain [Tenant main DB prefix slug] STF[Staff Devices Orders] INV[Inventory catalog] POSC[POS carts shifts] end subgraph thr [Tenant HR DB dev-hr-slug] EMP[employees payroll tax tables] end subgraph tan [Tenant analytics optional] ANA[reporting aggregates] end EX[Express services] EX --> master EX --> tmain EX --> thr EX --> tan

3. HTTP request shell

Order varies slightly by route (e.g. raw webhooks before JSON body). Most authenticated API calls pass through session, rate limiting, then per-router tenantResolver and auth.

flowchart LR IN[Incoming HTTPS] --> NX[Nginx] NX --> EX[Express] EX --> SEC[helmet cors compression] SEC --> CK[cookie parser] CK --> SES[express-session FileStore pawspos.sid] SES --> JSON[body parser except raw webhooks] JSON --> LOG[morgan requestId metrics] LOG --> RL[rateLimiter on api] RL --> RT[Router mount] RT --> AUTH[requireSessionAuth or flexible or public] AUTH --> TR[tenantResolver when needed] TR --> HND[Route handler] HND --> SVC[Service layer] SVC --> POOL[mysql2 pool]

4. Backend API domains

Logical grouping of backend/routes mounts from server.js (not every prefix shown). Payments v1 lives under /api/v1; POS under /api/pos; HR under /api/hr.

flowchart TB subgraph core [Core and identity] A1["/api/auth /auth OAuth"] A2["/api/users"] A3["/api/master-admin provisioning"] A4["/api/tenants /api/plans /api/features"] end subgraph money [Money and orders] B1["/api/v1 payments invoices transactions ledger"] B2["/api/pos carts tender"] B3["/api/pos register shifts PIN"] B4["/api/invoices core-invoicing"] B5["/api/core-invoicing"] end subgraph catalog [Catalog and inventory] C1["/api/products categories modifiers"] C2["/api/platform-catalog"] C3["/api/inventory and subpaths"] end subgraph people [People and time] D1["/api/staff /api/hr /api/payroll"] D2["/api/tenant-time timeclock roster"] D3["/api/employee-portal"] end subgraph cx [Customer experience] E1["/api/storefront /api/signage"] E2["/api/giftcards /api/loyalty"] E3["Tickets appointments public portals"] end subgraph crypto [Crypto and bridge] F1["/api doge ltc rates crypto-config"] F2["/api bridge WebSocket"] F3["Webhooks stripe coinbase doge"] end NODE[Node process server.js] core --> NODE money --> NODE catalog --> NODE people --> NODE cx --> NODE crypto --> NODE

5. Client applications

Primary SPA: frontend/ → production build frontend/dist. Routes include /admin, /pos, /business-hub, /staff, /employee-portal, /master-admin. POS may use IndexedDB offline queue (pawspos_offline) for mutation replay.

flowchart TB subgraph spa [React SPA] ADM[Admin and Business Hub] POSU[POS Modern Mobile Kiosk Bar] STF[Staff dashboard login] EMP[Employee portal] MA[Master admin] end subgraph serve [How it is served] STATIC[Express static frontend dist] FALL[Fallback index.html for client routes] end subgraph pub [Public site separate app] MK[Marketing signup] end subgraph off [Offline layer] IDB[(IndexedDB queue)] end spa --> STATIC STATIC --> FALL MK --> PNX[nginx or separate port] POSU -.-> IDB IDB -->|POST /api when online| API[Express API] spa --> API

6. Authentication modes

Platform users use session cookie. POS register open uses email + PIN without creating a full platform session. Kiosk/mobile device routes use device auth. Some reads are public (storefront config, signage playlist, public signup).

flowchart TB subgraph plat [Platform login] S1[POST auth login] S2[Session cookie pawspos.sid] S3[User role tenantSlug orgId in session] end subgraph reg [Register only] R1[POST api pos register authenticate] R2[Returns staff object no session] end subgraph dev [Device] D1[deviceAuth optionalDeviceAuth] D2["/api/kiosk /api/mobile"] end plat --> API[Protected API routes] reg --> POSOPEN[Open shift and POS context] dev --> API