Summary
Implement the first production consumer of the Database Schema IR to validate the architecture.
Motivation
Forge recently introduced a database-agnostic Database Schema IR as an intermediate representation layer. The current pipeline is incomplete:
Contract → Semantic Model → Database Schema IR → (NO CONSUMER)
The IR architecture cannot be validated without a real generator consuming it. Prisma will be the first consumer to prove the design.
Technical Design
Architecture
The Prisma generator must consume only the DatabaseSchema IR, not the AST or Semantic Model:
Contract
↓
Semantic Model
↓
Database Schema IR ← PrismaGenerator reads ONLY from here
↓
schema.prisma
Implementation Structure
Create new module:
packages/generators/src/prisma/
├── generator.ts (main generator class)
├── mapper.ts (type mappings)
├── writer.ts (file output)
└── index.ts (module exports)
Type Mappings
Forge → Prisma:
string → String
int → Int
float → Float
decimal → Decimal
boolean → Boolean
uuid → String (Prisma doesn't have native UUID)
datetime → DateTime
date → DateTime
Field Modifiers
Support DatabaseField properties:
isPrimary → @id decorator
isNullable → optional field (no !)
isUnique → @unique decorator
Acceptance Criteria
Example Output
Input
Forge contract:
contract User {
id: uuid
name: string
email: string
}
Semantic model produces these fields:
{ name: 'id', type: 'uuid', isPrimary: true, isNullable: false, isUnique: true }
{ name: 'name', type: 'string', isPrimary: false, isNullable: false }
{ name: 'email', type: 'string', isPrimary: false, isNullable: false }
Database Schema IR:
{
tables: [
{
name: 'User',
fields: [
{ name: 'id', type: 'uuid', isPrimary: true, isNullable: false, isUnique: true },
{ name: 'name', type: 'string', isPrimary: false, isNullable: false },
{ name: 'email', type: 'string', isPrimary: false, isNullable: false }
]
}
]
}
Generated schema.prisma:
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model User {
id String @id
name String
email String
}
Files to Create/Modify
New Files:
packages/generators/src/prisma/generator.ts (NEW)
packages/generators/src/prisma/mapper.ts (NEW)
packages/generators/src/prisma/writer.ts (NEW)
packages/generators/src/prisma/index.ts (NEW)
tests/prisma.test.mjs (NEW)
Modified Files:
packages/generators/src/index.ts (add generatePrisma export)
packages/generators/package.json (if new dependencies needed)
Test Strategy
Create comprehensive test suite tests/prisma.test.mjs:
Unit Tests
Integration Tests
Edge Cases
Non-Goals
Explicitly out of scope (v0.3+):
- Relationship definitions (@relation)
- Foreign key constraints
- Indexes beyond primary
- Indexes beyond unique
- Field-level constraints (e.g., @db.VarChar(255))
- Migrations
- Prisma client generation
Future Extensions
Phase 2 (v0.3):
- Relationship support (OneToOne, OneToMany from contract references)
- Custom indexes
- Provider configuration
Phase 3 (v0.4):
- Multi-database provider support (MySQL, SQLite)
- Custom type attributes
- Advanced constraints
Implementation Notes
- Critical: Only consume DatabaseSchema interface. Do NOT access SemanticModel or AST.
- Error handling: Throw with file location info
- Output: Write to
generated/prisma/schema.prisma
- Formatting: Use standard Prisma formatting
Success Criteria
✅ Database Schema IR has first real consumer
✅ Validates IR architecture is sound
✅ Proves IR is reusable by multiple generators
✅ Unblocks next generation features (migrations, relationships)
Summary
Implement the first production consumer of the Database Schema IR to validate the architecture.
Motivation
Forge recently introduced a database-agnostic Database Schema IR as an intermediate representation layer. The current pipeline is incomplete:
The IR architecture cannot be validated without a real generator consuming it. Prisma will be the first consumer to prove the design.
Technical Design
Architecture
The Prisma generator must consume only the DatabaseSchema IR, not the AST or Semantic Model:
Implementation Structure
Create new module:
Type Mappings
Forge → Prisma:
string→Stringint→Intfloat→Floatdecimal→Decimalboolean→Booleanuuid→String(Prisma doesn't have native UUID)datetime→DateTimedate→DateTimeField Modifiers
Support DatabaseField properties:
isPrimary→@iddecoratorisNullable→ optional field (no!)isUnique→@uniquedecoratorAcceptance Criteria
@id@unique!constraintExample Output
Input
Forge contract:
Semantic model produces these fields:
Database Schema IR:
Generated schema.prisma:
Files to Create/Modify
New Files:
packages/generators/src/prisma/generator.ts(NEW)packages/generators/src/prisma/mapper.ts(NEW)packages/generators/src/prisma/writer.ts(NEW)packages/generators/src/prisma/index.ts(NEW)tests/prisma.test.mjs(NEW)Modified Files:
packages/generators/src/index.ts(add generatePrisma export)packages/generators/package.json(if new dependencies needed)Test Strategy
Create comprehensive test suite
tests/prisma.test.mjs:Unit Tests
Integration Tests
Edge Cases
String?IntNon-Goals
Explicitly out of scope (v0.3+):
Future Extensions
Phase 2 (v0.3):
Phase 3 (v0.4):
Implementation Notes
generated/prisma/schema.prismaSuccess Criteria
✅ Database Schema IR has first real consumer
✅ Validates IR architecture is sound
✅ Proves IR is reusable by multiple generators
✅ Unblocks next generation features (migrations, relationships)