Prisma Schema
Translate the conceptual model to a clean, readable Prisma schema optimized for:
- Postgres
- clarity for junior devs
- future growth (versioning, traceability, ERD)
1. Assumptions & conventions
- User exists elsewhere (auth system)
- UUIDs everywhere
- Explicit join tables (no hidden many-to-many)
- Controlled enums
- JSON used only where it adds value
2. Enums
schema.prisma
enum WorkspaceRole {
AUTHOR
REVIEWER
VIEWER
}
enum SRSStatus {
DRAFT
RELEASED
ARCHIVED
}
enum RequirementType {
FUNCTIONAL
NON_FUNCTIONAL
CONSTRAINT
}
enum RequirementPriority {
MUST
SHOULD
COULD
WONT
}
enum RequirementStatus {
DRAFT
APPROVED
DEPRECATED
}
enum DiagramType {
ERD
SEQUENCE
CONTEXT
}
enum DiagramSource {
MERMAID
IMPORTED_SCHEMA
}
enum ReviewStatus {
OPEN
APPROVED
REJECTED
}
enum ApprovalDecision {
APPROVE
REJECT
}
enum ExportFormat {
MARKDOWN
PDF
}
enum TraceRelation {
SATISFIES
IMPACTS
DEPENDS_ON
}
enum TargetType {
REQUIREMENT
SECTION
DIAGRAM
ENTITY
}3. Workspace & collaboration
schema.prisma
model Workspace {
id String @id @default(uuid())
name String
description String?
standard String // ISO/IEC/IEEE 29148:2018
createdAt DateTime @default(now())
members Member[]
versions SRSVersion[]
diagrams Diagram[]
dataModels DataModel[]
exportProfiles ExportProfile[]
}
model Member {
id String @id @default(uuid())
userId String
role WorkspaceRole
workspace Workspace @relation(fields: [workspaceId], references: [id])
workspaceId String
approvals Approval[]
}4. SRS versioning & structure
schema.prisma
model SRSVersion {
id String @id @default(uuid())
versionTag String // v1.0, v1.1
status SRSStatus
createdAt DateTime @default(now())
workspace Workspace @relation(fields: [workspaceId], references: [id])
workspaceId String
sections Section[]
reviews Review[]
exports ExportArtifact[]
}
model Section {
id String @id @default(uuid())
code String // e.g. 3.2.1
title String
description String?
order Int
srsVersion SRSVersion @relation(fields: [srsVersionId], references: [id])
srsVersionId String
requirements Requirement[]
sectionDiagrams SectionDiagram[]
}5. Requirements (core domain)
schema.prisma
model Requirement {
id String @id @default(uuid())
identifier String // REQ-001
type RequirementType
priority RequirementPriority
status RequirementStatus
statement String
rationale String?
section Section @relation(fields: [sectionId], references: [id])
sectionId String
acceptanceCriteria AcceptanceCriterion[]
versions RequirementVersion[]
tracesFrom TraceLink[] @relation("TraceFrom")
tracesTo TraceLink[] @relation("TraceTo")
}
model AcceptanceCriterion {
id String @id @default(uuid())
format String // Given/When/Then | Plain
content String
requirement Requirement @relation(fields: [requirementId], references: [id])
requirementId String
}
model RequirementVersion {
id String @id @default(uuid())
changeType String // Created | Modified | Deprecated
changeNote String?
createdAt DateTime @default(now())
requirement Requirement @relation(fields: [requirementId], references: [id])
requirementId String
srsVersion SRSVersion @relation(fields: [srsVersionId], references: [id])
srsVersionId String
}6. Diagrams & ERD
schema.prisma
model Diagram {
id String @id @default(uuid())
type DiagramType
source DiagramSource
content String // Mermaid or serialized diagram
workspace Workspace @relation(fields: [workspaceId], references: [id])
workspaceId String
sectionDiagrams SectionDiagram[]
tracesFrom TraceLink[] @relation("TraceFrom")
tracesTo TraceLink[] @relation("TraceTo")
}
model SectionDiagram {
sectionId String
diagramId String
section Section @relation(fields: [sectionId], references: [id])
diagram Diagram @relation(fields: [diagramId], references: [id])
@@id([sectionId, diagramId])
}Data model & entities (ERD)
schema.prisma
model DataModel {
id String @id @default(uuid())
sourceType String // Prisma | SQL | Manual
schemaText String
workspace Workspace @relation(fields: [workspaceId], references: [id])
workspaceId String
entities Entity[]
}schema.prisma
model Entity {
id String @id @default(uuid())
name String
dataModel DataModel @relation(fields: [dataModelId], references: [id])
dataModelId String
tracesFrom TraceLink[] @relation("TraceFrom")
tracesTo TraceLink[] @relation("TraceTo")
}7. Traceability (polymorphic, explicit)
schema.prisma
model TraceLink {
id String @id @default(uuid())
relation TraceRelation
fromType TargetType
fromId String
toType TargetType
toId String
// Logical relations handled at application layer
// Prisma does not support polymorphic FKs natively
}This is intentional. Polymorphic traceability must be enforced in service logic, not DB constraints.
8. Review & approval
schema.prisma
model Review {
id String @id @default(uuid())
status ReviewStatus
srsVersion SRSVersion @relation(fields: [srsVersionId], references: [id])
srsVersionId String
comments ReviewComment[]
approvals Approval[]
}
model ReviewComment {
id String @id @default(uuid())
content String
targetType TargetType
targetId String
review Review @relation(fields: [reviewId], references: [id])
reviewId String
}
model Approval {
id String @id @default(uuid())
decision ApprovalDecision
decidedAt DateTime @default(now())
review Review @relation(fields: [reviewId], references: [id])
reviewId String
member Member @relation(fields: [memberId], references: [id])
memberId String
}9. Export & publishing
schema.prisma
model ExportProfile {
id String @id @default(uuid())
name String
format ExportFormat
config Json // sections included, verbosity rules
workspace Workspace @relation(fields: [workspaceId], references: [id])
workspaceId String
}
model ExportArtifact {
id String @id @default(uuid())
format ExportFormat
generatedAt DateTime @default(now())
versionTag String
srsVersion SRSVersion @relation(fields: [srsVersionId], references: [id])
srsVersionId String
exportProfile ExportProfile? @relation(fields: [exportProfileId], references: [id])
exportProfileId String?
}10. Why this schema is solid
-
Maps 1-to-1 with SRS concepts
-
Teaches juniors domain-driven thinking
-
Scales to:
- traceability matrices
- impact analysis
- multi-version exports
- ERD ↔ requirement links
And it plays very nicely with:
- Next.js API routes
- Prisma Client
- Mermaid generation
- PDF pipelines
11. Next logical move
- Cut this down to an MVP schema (what to ship in v0.1)
- Define service-layer rules (where invariants live)
- Design API endpoints
- UI → domain mapping (screens → entities)