Architecture Overview
The monorepo, the apps, and how they fit together.
Monorepo layout
npm workspaces, one repo, no separate API server:
LSCApp/
apps/
web/ Next.js — /admin (staff), /portal (customer web),
every public page, and every /api/* route
mobile/ Expo (React Native) — staff/manager companion app
customer/ Expo (React Native) — native customer app
print-agent/ Plain Node — runs on a Raspberry Pi at the physical
location, not deployed to Vercel
docs/ This documentation site
packages/
shared/ Prisma schema, shared TypeScript types and business
logic used by every app aboveapps/mobile and apps/customer are thin native clients — they call
apps/web's /api/* routes for everything. There is no independent
backend for either app.
Tech stack
- Database: AWS Aurora PostgreSQL, accessed through Prisma.
packages/sharedowns the schema. - File storage: AWS S3, for identity documents, signed agreements, and mail-scan photos — private, never a public bucket.
- Auth: Clerk — two separate applications, one invite-only for staff, one open-sign-up for customers. See Security & Access Model.
- Payments: Stripe (cards and ACH, subscriptions, invoicing).
- Hosting: Vercel for the web app; Aurora and S3 on AWS directly.
The two Clerk applications
| Staff app | Customer app | |
|---|---|---|
| Sign-up | Invite-only | Open |
| Serves | /admin, manage./admin. subdomains, staff mobile app | portal. subdomain, native customer app |
| Backend auth check | Against StaffMember records | Against Customer records |
They never share a session, a secret key, or a sign-up policy — this is a structural security boundary, not an implementation detail to work around.
Why one repo, not several
packages/shared is the reason: Prisma types and business logic (pricing,
approval rules, notification sending) are written once and used
identically by the web app and both native apps. A booking's price is
computed by the exact same function whether it's quoted from the public
website, the portal, or the native app — there's no separate copy that
can drift.
Deployment topology
Only apps/web deploys to Vercel automatically as part of the main
app's pipeline. apps/print-agent runs on physical hardware on-site.
apps/mobile and apps/customer build and submit through Expo/EAS to
TestFlight and the app stores. apps/docs (this site) deploys as its own
separate Vercel project, independent of the main app's deploys.