UH UserHappy Architecture Docs

Interactive system brief

Readable architecture for the UserHappy product surface.

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

Start with the map, then drill into decisions.

Interactive map

One product, distinct runtime boundaries.

UserHappy keeps the browser bundle broad, the API authority narrow, and customer data separated behind explicit tenant resolution.

Internet
Edge
Data and services

Backend decisions

Edge API, isolated data, portable contracts.

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.

B1

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.

B2

Domain context shapes behavior

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.

B3

Tenant isolation is the database story

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.

B4

SQLite compatibility preserves options

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

Role-aware shell, narrow context, simple state.

The frontend documentation explains how React stays understandable without reaching for a heavier global store before the app actually needs one.

F1

One bundle, multiple shells

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.

F2

Context only for cross-route identity

LiveTeamContextProvider publishes identity, organization, system-user state, staff role, and impersonation provenance because those values affect navigation and page access across the route tree.

F3

Local hooks handle local concerns

Route-local UI state remains in useState, useMemo, and useEffect. Browser-backed hooks handle device state such as the selected customer connection.

F4

Typed fetch modules keep pages clean

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

Anonymous pulse submission from link to D1 write.

The survey URL contains the invite token. No user account is created and no dashboard navigation is shown.

Role access

Filter capabilities by persona.

Frontend role gates are a usability layer. Backend route checks and D1 ownership rules remain the security boundary.

Customer owner

customer_owner

  • Dashboard, Create A Pulse, Manage Audience, View Reports, Team, and Help Requests
  • Invite teammates, assign roles, revoke access, resend pending invites
  • Create, launch, close, and review customer-owned pulses

Customer admin

customer_admin

  • Pulse, audience, report, dashboard, and help request workflows
  • Team page is visible but role-management controls are hidden
  • Cannot revoke teammates or assign elevated customer access

Customer member

customer_user

  • Core workspace access for repeated product work
  • Pulse and audience work under backend permission rules
  • No invite, role-change, or revoked-access controls

UserHappy staff

staff user

  • Staff-domain shell, inbox, and profile workflows
  • Explicit customer connection before acting in customer workspace
  • No admin-only or super-admin route exposure

UserHappy admin

admin

  • Staff capabilities plus admin-only app routes
  • System help inbox and approval workflow navigation
  • No super-admin dashboard access

Super admin

super_admin

  • Admin capabilities plus super-admin guarded routes
  • Can create controlled customer impersonation sessions
  • Impersonation provenance remains visible in the app shell

Anonymous respondent

invite token

  • Open the survey route and submit answers once
  • Optional audio transcription through the Worker
  • No dashboard, team access, reports, or customer APIs

Concept finder

Search the architecture vocabulary.

Cloudflare Pages

Static delivery for the Vite bundle. Hostname and routes decide which shell appears after the browser loads.

View in map

Hono Worker

The API authority for auth, pulses, contacts, audience, survey responses, team access, staff actions, and AI suggestions.

Backend decisions

D1 and tenant isolation

D1 keeps the early stack compact while preserving a SQLite-compatible path for future adapter swaps.

Backend decisions

LiveTeamContextProvider

Publishes current user, organization, system-user state, staff role, and impersonation context to routed views.

Frontend decisions

Staff impersonation

Controlled customer sessions carry staff provenance so the UI can show who is acting for the customer.

Role access

Workers AI

Optional AI binding for pulse suggestions and survey audio transcription without a separate service hop.

View in map

Scale and portability

Cloudflare now, adapter swaps later.

Now to 50 orgs

Build on D1 and Workers

Keep costs low, keep latency close to users, and avoid infrastructure overhead while the product surface stabilizes.

50 to 300 orgs

Monitor, do not migrate early

Track D1 storage, reads, writes, Worker requests, and customer data size. The architecture is still comfortably inside the Cloudflare shape.

300+ orgs

Evaluate the business trigger

Migration should be driven by customer requirements, cost shape, or operational needs, not by fear of the current stack.

Migration path

Swap adapters, preserve contracts

Workers can move toward Lambda, D1 toward SQLite-compatible stores, Workers AI toward Bedrock, and Pages toward S3 plus CloudFront.