Session-first foundation for a multi-tenant therapy practice management system for the German market. Scheduling remains the hero subsystem, but the session is the central operational object for completion, documentation, and billing-relevant follow-up.
The current product direction is:
- scheduling remains the main operational surface
- sessions carry the actual care-delivery outcome and workflow state
- UX is shaped by role: Therapist, Reception, Admin, Accounting
- documentation is embedded in the session workflow, not treated as a detached afterthought
- scheduling conflicts are explicit and severity-based: hard stop, soft warning, or auto-adjust where appropriate
- setup dependencies are surfaced early so staff can recover before work is blocked
- permissions, auditability, and EU-only infrastructure remain baseline requirements
Terminology used across this repository:
Appointment: the scheduled slot on the calendarSession: the operational record of what actually happened for that slotPrescription: the treatment and administrative context around the care planDocumentation: session-linked output such as notes, transcripts, and drafts
- ARCHITECTURE.md
- BACKLOG.md
- PERMISSIONS_MATRIX.md
- AUDIT_EVENTS.md
- SECURITY_BASELINE.md
- UI_STYLE_GUIDE.md
- AGENTS.md
- Next.js App Router
- TypeScript
- Prisma
- Zod
- Vitest
- Playwright
- pnpm
.
├── prisma/ # Prisma schema, migrations, and seed data
├── src/
│ ├── app/ # App Router entrypoints and global styles
│ └── lib/ # Shared runtime helpers such as env parsing
├── tests/ # Vitest unit and integration coverage
├── e2e/ # Playwright golden-path coverage
└── .github/workflows/ # CI pipeline
-
Install pnpm if it is not already available, or use Corepack.
-
Install dependencies:
pnpm install
-
Copy the example environment file:
cp .env.example .env
-
Generate the Prisma client and apply migrations:
pnpm db:generate pnpm db:migrate pnpm db:seed
-
Start the application:
pnpm dev
-
Open http://localhost:3000. The root route redirects to
/de, and/enis available as the English variant.
Demo users seeded by pnpm db:seed:
admin@demo.physio.local(Admin)frontdesk@demo.physio.local(Reception)therapist@demo.physio.local(Therapist)billing@demo.physio.local(Accounting)
- Locale routing uses the App Router via
src/app/[locale]. - Translation dictionaries live in
src/i18n/messages. - Shared localized domain values can use
src/i18n/localized-value.ts, which is intended for bilingual fields such as service type labels and session workflow text.
- Prisma schema includes
practices,users,practice_memberships,magic_link_tokens, auth sessions, and practice-scoped foundational domain tables. - Every scoped model stores
practice_id, and composite foreign keys keep related records inside the same practice. - Magic-link tokens are tied to a concrete practice membership when requested, so login resolves the current practice before the session is created.
- Server-side request context prefers the authenticated session practice and only falls back to
x-practice-idorpractice_idwhen no session exists. - If a user belongs to multiple practices and no preferred practice is supplied, the oldest membership becomes the default selection until a later practice switcher exists.
- Practice memberships carry one of the base roles:
Admin,Reception,Therapist, orAccounting. - Permission checks are enforced in backend helpers and service boundaries. Missing or unresolved permission paths deny access by default.
- Scheduling is the main operational entry point, but session state drives completion, documentation, and billing-relevant follow-up.
- Role-shaped surfaces should default to:
- Therapist: today and next sessions, session completion, documentation
- Reception: search, scheduling, conflict handling, recovery from cancellations or no-shows
- Admin: configuration, staffing, dependency setup, billing oversight
- Accounting: invoice and payment workflows with limited schedule context
- Schedule visibility remains broader than chart visibility. Seeing a patient in the schedule does not grant chart access.
- Documentation is linked to sessions conceptually and operationally.
- Conflict handling must be explicit about severity and any override path must be traceable.
- Auth sessions use
HttpOnly,SameSite=Lax, path-scoped cookies. Production defaults toSecure=true. - The session cookie defaults to
__Host-physio_sessionin production andphysio_sessionlocally to avoid breaking HTTP development. - The practice hint cookie is also server-only (
HttpOnly) because it is read only by backend request-context code. - EU-only hosting, EU-only AI inference and transcription, backup expectations, and private-by-default file storage are documented in SECURITY_BASELINE.md.
- The Agentation dev toolbar is mounted at the app root through
src/components/agentation-devtools.tsx. - It renders only in development.
- Set
NEXT_PUBLIC_AGENTATION_ENDPOINT=http://localhost:4747to connect the React overlay to a local Agentation MCP server.
pnpm lint
pnpm typecheck
pnpm testDatabase utilities:
pnpm db:generate
pnpm db:migrate
pnpm db:seedOptional end-to-end coverage:
pnpm test:e2e