Skip to main content
← All notes
Building

Ten models, three enums, and every delete cascades

software

The database schema is one Prisma file with ten models and four enums. Client is the root — every other model connects back to it directly or through Project. A Client has an optional clerkId that starts null until the Clerk webhook links it, a unique email, an optional stripeCustomerId for invoice lookups, and an archivedAt timestamp for soft deletes. Project belongs to Client and carries a ServiceType enum — SOFTWARE, ACCESSIBILITY, AUDIO, PRODUCTION, MUSICIAN — and a ProjectStatus enum — ACTIVE, IN_REVIEW, COMPLETED, ON_HOLD. Six models hang off Project with cascading deletes — Milestone, Session, Goal, Deliverable, ActionItem, and Attachment. Delete a project and everything underneath disappears in one operation. Milestone has a sortOrder integer so the timeline renders in the right sequence and a MilestoneStatus enum — TODO, ACTIVE, DONE. Session stores a durationMin integer, optional notes as a Text column for long content, and an optional calendarEventId that links it to Google Calendar. Comment is the most connected model — it has optional foreign keys to Session, Milestone, and Goal so the same comment model serves inline threads on three different entity types. Each comment carries an isJames boolean and an authorName string for the avatar system, plus editedAt and deletedAt timestamps for audit trails. Attachment stores the R2 key as url, the file size, the MIME type, and an uploadedBy string defaulting to james. Deliverable has its own four-stage enum — PENDING, IN_PROGRESS, DELIVERED, APPROVED — and an optional one-to-one link to an Attachment. Booking stands apart from the project tree — it connects directly to Client with a unique calendarEventId for upsert-based sync and indexed startTime for chronological queries. Every foreign key that connects to Project or Session uses onDelete Cascade. Every model that needs frequent lookups has an index on its parent key. Ten models, fourteen indexes, four enums, and the whole schema fits in two hundred lines.

Comments coming soon

Sign in with TikTok to leave a comment. Coming soon.