calcom/cal.com
prisma
Purpose
packages/prisma is the database layer. It owns schema.prisma (the single source of truth for every table), the migration history, the seed scripts, and three generators that turn the schema into typed Prisma client code, Zod schemas, and Kysely types.
Directory layout
prisma/
├── schema.prisma # 2,877 lines, 100 models, 46 enums
├── migrations/ # 596 directories of historical migrations
├── zod/ # Generated Zod schemas (output of zod-prisma-types)
├── client/ # Re-exports of the generated Prisma client
├── extensions/ # Custom Prisma client extensions
├── selects/ # Reusable `select` snippets
├── sql/ # Raw SQL helpers (grants, PBAC, ...)
├── seed.ts # Main seed script
├── seed-pbac-only.ts # PBAC-only seed
├── auto-migrations.ts # Auto-runs pending migrations on boot in some envs
├── cleanup-pbac.ts
├── delete-app.ts
├── enum-generator.ts # Wrapper for the prisma-enum-generator
├── run-enum-generator.js
├── docker-compose.yml # Local Postgres
├── index.ts # Exports the configured PrismaClient
├── is-prisma-available-check.ts
├── package.json
├── zod-utils.ts (34 KB) # Hand-written Zod helpers extending the generated set
├── zod-utils.test.ts
└── __mocks__/ # In-memory mock clientGenerators
schema.prisma declares four generators. The expected output of each is committed-out and regenerated on demand:
| Generator | Output | Purpose |
|---|---|---|
prisma-client |
packages/prisma/generated/prisma |
The TypeScript Prisma client with types |
zod-prisma-types |
packages/prisma/zod/ |
One Zod schema per model |
prisma-kysely |
packages/kysely/types.ts |
Kysely-compatible types for raw SQL workspace |
prisma-enum-generator |
(custom) | Generates a single enums.ts for runtime enum checks |
yarn workspace @calcom/prisma prisma generateSchema highlights
100 models. The most central:
User— the universal userEventType— bookable offering (with self-relationparentIdfor managed event types)Booking+BookingReference— booking + third-party event IDsAttendee— non-organizer participantsSchedule+Availability— recurring availability templatesSelectedCalendar— calendars to read free/busy fromDestinationCalendar— single calendar to write bookings toCredential— encrypted third-party tokens (thekeyJSON column is encrypted withCALENDSO_ENCRYPTION_KEYand never appears in API responses;AGENTS.md)App— installed app-store entriesWebhook+Workflow(workflow runtime is being deprecated)Host+HostGroup+HostLocation— team event-type assignmentsMembership+Team+Profile— team / org structuresHashedLink— private booking linksTask— backing table for the in-process tasker queueOAuthClient+Tokens— Platform tenant credentials
46 enums. Among the more important:
SchedulingType—ROUND_ROBIN,COLLECTIVE,MANAGEDPeriodType—UNLIMITED,ROLLING,ROLLING_WINDOW,RANGECreationSource—API_V1,API_V2,WEBAPPBookingStatus—ACCEPTED,PENDING,CANCELLED,REJECTED,AWAITING_HOSTWorkflowMethods,WorkflowTriggerEvents, etc.CancellationReasonRequirement—MANDATORY_BOTH,OPTIONAL_BOTH, ...
See primitives for narrative coverage of the most-referenced models.
Migrations
packages/prisma/migrations/ contains 596 migration directories — one of the longest migration histories in any open-source TypeScript codebase. Each migration is a Prisma-generated SQL file plus a migration.toml. The .github/workflows/check-prisma-migrations.yml workflow ensures every PR that changes the schema includes a corresponding migration.
auto-migrations.ts runs pending migrations on boot in some deploy modes; production uses explicit prisma migrate deploy.
Seeds
seed.ts— the main seed for local dev (creates a couple of users, event types, and apps).scripts/seed-app-store.ts— seeds theApptable from the registry generated byapp-store-cli.scripts/seed-booking-audit.ts,seed-huge-event-types.ts,seed-performance-testing.ts— purpose-built seeds for specific scenarios.seed-pbac-only.tsandcleanup-pbac.ts— PBAC (permission-based access control) helpers.
yarn db-seed invokes seed.ts via the prisma config block in the root package.json:
"prisma": {
"schema": "packages/prisma/schema.prisma",
"seed": "ts-node --transpile-only ./packages/prisma/seed.ts"
}Conventions
- Use
select, notinclude— every Prisma query in repositories must list its columns explicitly. - Never expose the
Credential.keycolumn in any query that flows to a client. - Wrap multi-write operations in
prisma.$transaction([...]). - Long-running side effects belong in the tasker (
packages/features/tasker), not inline. - Reusable selects live in
packages/prisma/selects/and should be imported instead of duplicated.
Integration points
- Web app + API v2 both consume the generated client.
- Repositories in
packages/features/*/repositories/are the only layer that should import@calcom/prisma. - Tests import the in-memory mock from
packages/prisma/__mocks__(powered byprismock). - Kysely types in
packages/kyselyare used wherever raw SQL is needed (rare; mostly analytics and PBAC).
Entry points for modification
- Schema change: edit
schema.prisma, generate a migration withprisma migrate dev, regenerate client + zod + kysely. Add or update repositories, then services, then handlers. - Adding a reusable select: drop a file in
packages/prisma/selects/and update the repository. - Custom client behavior: extensions go under
packages/prisma/extensions/(e.g., logging, soft-delete).
Related pages
- primitives — narrative coverage of the most-referenced models
- features — every domain has a
repositories/directory - reference → data models
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.