Architecture Overview
CaseSolo is a multi-tenant legal practice SaaS (Next.js App Router) where each Firm is an isolated tenant. One Next.js deployment serves the marketing site, the authenticated dashboard, the client portal, and all JSON APIs.
Request flow
Request → proxy.ts (session/route gating) → App Router page or /api/* handler
→ getCurrentUser(headers) → firmId → getTenantPrisma(firmId) → PostgreSQL
- Auth: JWT access token (15 min) + rotating HTTP-only refresh token
- Tenant isolation: firm-scoped models carry
firmId;getTenantPrisma(firmId) - RBAC: 7 roles (
SUPER_ADMIN→READONLY) with a permission matrix.
(jose + bcryptjs). Portal clients use a separate JWT flow.
(in src/lib/db) auto-injects it. Never query firm data with the raw client without a manual firmId filter.
Directory map
src/
app/ # Routes: (auth), (dashboard), (portal), intake, api/* (82 groups)
components/ # Domain components + ui/ (shadcn/Radix primitives)
lib/ # Server logic: db, auth, ai, billing, jobs, realtime,
# storage, webhooks, integrations, observability, ...
hooks/ types/ # Client hooks, shared TypeScript types
generated/ # Prisma-generated client (do not edit)
prisma/
schema.prisma # 102 models — source of truth for the data model
migrations/ # Forward-only migration history
Background work (BullMQ + Redis)
Workers boot in src/instrumentation.ts: overdue detection, SOL tracker, agent runs, document processing (OCR), auto-tasks, task reminders. Scheduled user-visible items (emails, broadcasts, recurring tasks, lead reminders) additionally need the cron dispatcher — see deployment.
Realtime and storage
- Socket.io (JWT-authenticated, firm/case-scoped) for presence and
- S3-compatible object storage (self-hosted MinIO preferred; R2 supported)
collaborative notes; SSE for server-push updates.
with pending-record + PUT-confirmation upload flow.
Key invariants
- Standalone output, Turbopack-only build,
HOSTNAME=0.0.0.0via - No
any, noconsole.log(useemitEvent()), Zod-validate mutations. - Docs for adjacent detail: tech stack,
scripts/start-standalone.mjs — see deployment.
API + data model, database.