4.8 KiB
4.8 KiB
09. Database — Migrate Full Prisma Schema to Drizzle ORM
meta: id: shieldai-unified-restructure-09 feature: shieldai-unified-restructure priority: P0 depends_on: [] tags: [backend, database, drizzle, schema]
objective:
- Convert the entire 900-line Prisma schema from
packages/db/prisma/schema.prismainto Drizzle ORM TypeScript schema files inweb/src/server/db/schema.tsand related files. This is the foundational data layer for the unified monolith.
deliverables:
web/src/server/db/schema.ts— Main schema file with all tables:- User & Authentication (User, Account, Session, DeviceToken)
- Family & Subscription (FamilyGroup, FamilyGroupMember, Subscription)
- DarkWatch (WatchlistItem, Exposure)
- Notifications & Alerts (Alert)
- VoicePrint (VoiceEnrollment, VoiceAnalysis, AnalysisJob, AnalysisResult)
- SpamShield (SpamFeedback, SpamRule)
- Audit & Analytics (AuditLog, KPISnapshot)
- Correlation (NormalizedAlert, CorrelationGroup)
- Reports (SecurityReport)
- Marketing (WaitlistEntry, BlogPost)
- HomeTitle (PropertyWatchlistItem, PropertySnapshot, PropertyChange)
- RemoveBrokers (InfoBroker, RemovalRequest, BrokerListing)
web/src/server/db/schema/— Optional split directory if single file becomes unwieldy:auth.ts,subscription.ts,darkwatch.ts,voiceprint.ts,spamshield.ts,alerts.ts,correlation.ts,reports.ts,marketing.ts,hometitle.ts,removebrokers.ts
- All enums defined as TypeScript const arrays or Drizzle
pgEnum - All indexes, unique constraints, and foreign keys preserved
- Relations defined using Drizzle's
relations()helper
steps:
- Read and analyze
packages/db/prisma/schema.prismacompletely. Document every model, enum, relation, index, and constraint. - Install Drizzle ORM and PostgreSQL driver in
web/:drizzle-ormpg(node-postgres) or@neondatabase/serverlessif using Neondrizzle-kitfor migrations
- Create
web/src/server/db/schema.ts(or split directory). - For each Prisma model, create a Drizzle table definition:
- Map Prisma field types to Drizzle column types:
String→varchar,text,uuidInt→integerFloat→realBoolean→booleanDateTime→timestampJson→jsonbString[]→text().array()
- Preserve
@id,@default(uuid()),@unique,@index,@relation - Map Prisma enums to Drizzle
pgEnum()
- Map Prisma field types to Drizzle column types:
- Define all indexes using Drizzle's
.index()and.unique()on table definitions. - Define relations using
relations()helper for:- User → accounts, sessions, familyGroups, subscriptions, alerts, voice enrollments, etc.
- Subscription → watchlistItems, exposures, alerts, propertyWatchlistItems, removalRequests
- WatchlistItem → exposures
- PropertyWatchlistItem → snapshots, changes
- And all other one-to-many / many-to-one relations
- Export a unified schema object for use with Drizzle Kit.
- Verify the schema compiles without TypeScript errors.
- Generate an ER diagram or schema summary for documentation.
steps:
- Unit: Schema file compiles without TS errors
- Integration:
drizzle-kit generateproduces migration SQL that matches Prisma schema structure - Compare: Automated or manual comparison of Prisma schema vs Drizzle schema to ensure no models/fields are missing
acceptance_criteria:
- Every model from Prisma schema has a corresponding Drizzle table definition
- All enums are defined and used correctly
- All primary keys, unique constraints, and indexes are preserved
- All foreign key relations are defined using Drizzle relations
drizzle-kit generateruns successfully and outputs SQL- Generated SQL creates tables with correct column types and constraints
- No data loss: the new schema is structurally equivalent to the old one
validation:
- Run
cd web && npx drizzle-kit generateand inspect generated SQL - Compare table count: Prisma schema has X models, Drizzle schema has X tables
- Verify enum values match exactly between Prisma and Drizzle
- Run
npx drizzle-kit pushagainst a local PostgreSQL instance and confirm all tables are created
notes:
- This is the most critical backend task. A missing field or incorrect relation will cascade into broken tRPC routers.
- Prisma's implicit many-to-many relations must be explicitly defined as junction tables in Drizzle.
- Prisma's
@updatedAtauto-timestamp can be replicated with Drizzle's$onUpdateFn(() => new Date()). - Keep the old Prisma schema file as reference until task 41.
- Consider using
drizzle-zodlater (task 11+) to auto-generate validation schemas from Drizzle tables. - The schema uses PostgreSQL-specific features (arrays, enums, jsonb). Ensure the Drizzle definitions use
pgTable,pgEnum, etc.