Single Worker API authority
Hono routes live behind one Worker and expose the product API under /api/*. That lets the app keep route middleware, auth checks, D1 access, and Workers AI bindings in one deployable surface.
Interactive system brief
A single-page field guide to how the React workspace, staff shell, anonymous survey flow, Cloudflare Worker, D1 data model, and portability plan fit together.
How to read this
Interactive map
UserHappy keeps the browser bundle broad, the API authority narrow, and customer data separated behind explicit tenant resolution.
Backend decisions
The backend documentation centers on three choices: Cloudflare is the fast default, D1 keeps the data model SQLite-compatible, and adapter boundaries keep future migration from touching route logic.
Hono routes live behind one Worker and expose the product API under /api/*. That lets the app keep route middleware, auth checks, D1 access, and Workers AI bindings in one deployable surface.
The browser bundle can be shared, but hostnames and route guards make the customer app, staff shell, preview workflow, and respondent survey path feel distinct.
The architecture favors a registry plus isolated tenant stores. Even when the current implementation evolves, the core principle is unchanged: never let customer ownership become an afterthought in shared queries.
D1 gives a low-friction Cloudflare start. If scale or customer requirements shift, SQLite-compatible stores such as libSQL/Turso keep the migration centered on adapters instead of SQL rewrites.
Frontend decisions
The frontend documentation explains how React stays understandable without reaching for a heavier global store before the app actually needs one.
App.tsx uses hostname and routes to choose the staff shell, customer workspace, public auth routes, and token-based survey route from one Vite-built bundle.
LiveTeamContextProvider publishes identity, organization, system-user state, staff role, and impersonation provenance because those values affect navigation and page access across the route tree.
Route-local UI state remains in useState, useMemo, and useEffect. Browser-backed hooks handle device state such as the selected customer connection.
Pages call focused data modules for pulses, team access, audience, and staff onboarding instead of assembling fetch headers and JSON error parsing in every view.
Request flow
The survey URL contains the invite token. No user account is created and no dashboard navigation is shown.
The same Vite bundle loads quickly from the edge. The route renders only the survey experience for /survey/:token.
The Worker resolves the token, fetches pulse metadata and questions, and returns the minimum payload needed by the respondent UI.
If the survey records audio feedback, the Worker can use its AI binding for transcription before the final answer set is submitted.
The Worker writes the response and marks the invite as used. Database constraints protect against duplicate respondent submissions.
Role access
Frontend role gates are a usability layer. Backend route checks and D1 ownership rules remain the security boundary.
customer_owner
customer_admin
customer_user
staff user
admin
super_admin
invite token
Concept finder
Static delivery for the Vite bundle. Hostname and routes decide which shell appears after the browser loads.
View in mapThe API authority for auth, pulses, contacts, audience, survey responses, team access, staff actions, and AI suggestions.
Backend decisionsD1 keeps the early stack compact while preserving a SQLite-compatible path for future adapter swaps.
Backend decisionsPublishes current user, organization, system-user state, staff role, and impersonation context to routed views.
Frontend decisionsControlled customer sessions carry staff provenance so the UI can show who is acting for the customer.
Role accessOptional AI binding for pulse suggestions and survey audio transcription without a separate service hop.
View in mapNo matching concepts. Try a shorter term.
Scale and portability
Keep costs low, keep latency close to users, and avoid infrastructure overhead while the product surface stabilizes.
Track D1 storage, reads, writes, Worker requests, and customer data size. The architecture is still comfortably inside the Cloudflare shape.
Migration should be driven by customer requirements, cost shape, or operational needs, not by fear of the current stack.
Workers can move toward Lambda, D1 toward SQLite-compatible stores, Workers AI toward Bedrock, and Pages toward S3 plus CloudFront.