Skip to content

API and Data Model

API conventions

All product APIs are Next.js App Router route handlers under src/app/api (82 route groups). Public surface: Swagger UI at /api-docs, OpenAPI 3.1.0 JSON at /api/docs/openapi.

Authenticated handler contract

  1. const ctx = await getCurrentUser(request.headers); return 401 if missing.
  2. Enforce role checks on admin-only routes (403 if insufficient).
  3. Scope every DB read/write by ctx.firmId (tenant client or where clause).
  4. select only the fields the caller needs; noCacheHeaders() on sensitive GETs.
  5. Never return keys, tokens, signed URLs, or provider secrets — return
  6. readiness booleans, hostnames, or redacted labels instead.

Status codes: 200 read/action · 201 created · 400 invalid input · 401 unauthenticated · 403 forbidden · 404 tenant-scoped not found · 409 conflict · 500 unexpected (secret-safe logging).

Mutations

Public developer API

Scoped API keys (/api/settings/api-keys), usage reporting (/api/settings/api-usage), registry in src/lib/developer-portal/registry.ts. External-key routes must validate key hash, active status, expiry, firm ownership, scope, and rate-limit/usage accounting. When adding a public endpoint: update the registry/OpenAPI source, document auth + scopes with success/failure examples, add a route test, and confirm /api/docs/openapi stays valid.

Full handler detail: api-reference.

Data model (102 models, prisma/schema.prisma)

| Domain | Models | |---|---| | Tenant + team | Firm, User (+ roles), Invitation | | Case core | Case, CaseStatusHistory, CaseParty, CaseAssignment, Note, Task | | Intake | Lead, IntakeSubmission, ReferralSource | | Contacts | Contact, OpposingCounsel, ExpertWitness | | Medical | MedicalRecord, MedicalProvider, Treatment, MedicalBill | | Legal | InsurancePolicy, InsuranceClaim, SubrogationLien, NegotiationEntry, Deposition, JurisdictionStatute, DiscoveryRequest, Evidence | | Financial | Invoice, Payment, TimeEntry, TrustTransaction, TrustAccount, Expense, MileageEntry | | Comms | CommunicationRecord, SmsConsent, SmsMessage, EmailLog | | AI / automation | AgentConfig, AgentRun, DocumentChunk (pgvector), Workflow, WorkflowRun, WorkflowRunStep, Template | | Documents / media | Document, Recording, KnowledgeArticle | | Scheduling | CalendarEvent | | Config | CustomFieldDefinition/Value, AlertRule, WebhookEndpoint, ApiKey, SavedReport, ChecklistTemplate/Item | | Signatures | SignatureRequest, SignatureSigner | | Ops | Activity (audit trail), Notification |

Key enums: CaseStatus (LEAD → … → CLOSED/REJECTED), UserRole (SUPER_ADMIN, ADMIN, ATTORNEY, PARALEGAL, INTAKE_SPECIALIST, CLIENT, READONLY), CaseType, ContactType, TaskStatus, TaskPriority.

Multi-tenancy rule

Firm-scoped models carry firmId; use getTenantPrisma(firmId) so scoping is automatic. With the raw client, filter firmId manually. Unscoped models (e.g. Note) inherit scoping through parents (Note → Case → Firm).

Migrations

npx prisma migrate dev --name your-change  # author (commits SQL under prisma/migrations/)
npx prisma migrate deploy                  # apply (production runs this at boot)
npx prisma migrate status

Forward-only: revert with a new migration, never delete history. Expand/contract procedure: database-migrations.

Source: docs/dev/api-data-model.md