The coach web app is the Next.js 16 project in frontend/apps/saas. Studio owners and coaches use it to manage trainees, plans, forms, content, tasks and billing. It has no database of its own. Every read and write goes to the core API (the Express service in backend, port 3031 locally). The repo is a pnpm workspace driven by Turborepo. The root package.json is named perform-web.

What the web app owns today

  • The UI: pages, layouts, client components, design tokens and translations.
  • A thin server layer: server components that load data, server actions that write, and a handful of route handlers.
  • Three ways of reaching the core API. See Talking to the core API.
It does not own authentication logic, the oRPC router, Prisma, mail, storage or AI. Those packages were moved into the backend during the server consolidation. The folders are still on disk but are empty apart from leftover node_modules:
frontend/README.md, frontend/docs/README.md and the workspace CLAUDE.md still describe these as live packages, a MySQL database and pnpm db:generate. None of that exists in the code now. See Corrections to older docs.

Folder map

Inside apps/saas

app/

The App Router tree. Feature code is colocated with its route: a typical area holds page.tsx (server component), one or more client views, actions.ts (server actions), pure model files and their tests. The full tree is documented in Route tree.

modules/

Code shared across routes. Each module has a path alias in tsconfig.json and vitest.config.ts. modules/sign (the public PDF signing page) has no alias and is imported through @/modules/sign/....

modules/shared/lib highlights

Stack

Running locally

pnpm dev first runs ../tools/ensure-core-api.sh --start from the workspace root. That script checks the API’s /healthz endpoint on local port 3031 and starts pnpm dev in backend when the API is not up. Then it starts saas on port 3000 and marketing on port 3001 through Turborepo. Use pnpm dev:app to skip the API check. There is no .env.example in the repo. The root .env currently defines these names: Optional variables read by the code: AUTH_TRUSTED_ORIGINS (extra dev origins), MARKETING_URL (dev marketing server, default http://localhost:3001), NEXT_PUBLIC_MARKETING_URL, NEXT_PUBLIC_DOCS_URL, NEXT_PUBLIC_TRAINEE_PREVIEW_URL, NEXT_PUBLIC_LANGUAGE_SWITCH_EMAILS, DEPLOYMENT_VERSION and the PRICE_ID_* overrides in packages/payments/config.ts.

Where to go next

Route tree

Every route group, page and what it renders.

Talking to the core API

The proxy, the signed lane, headers and error handling.

Server actions

The read in page, write in action pattern.

Feature areas

Where the code for each product area lives.