Add a Prisma Model¶
Canonical example: Faq model at libs/_prisma/src/schema/api.prisma:113-123.
1. Pick the right schema file¶
The Prisma schema is split across three files under libs/_prisma/src/schema/.
Each maps to a PostgreSQL schema:
| File | PG schema | What goes here |
|---|---|---|
api.prisma |
public |
Everything except game-server tables |
blackjack.prisma |
blackjack |
Blackjack tables/hands/configs |
speed_roulette.prisma |
speed_roulette |
Speed-roulette rounds/bets |
The generator and datasource blocks live only in api.prisma:1-14 — don't duplicate them.
2. Define the model¶
Add your model at the bottom of the chosen file. Follow the existing conventions exactly:
model Announcement {
id Int @id @default(autoincrement()) @map("id")
title String @map("title")
body String @map("body")
active Boolean @default(true) @map("active")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
@@map("announcement")
@@schema("public")
}
Conventions enforced by the codebase:
@map("snake_case")on every field — Prisma uses camelCase in TypeScript, the DB uses snake_case.@@map("table_name")— sets the Postgres table name.@@schema("public")— required becausemultiSchemais enabled (api.prisma:3).@id @default(autoincrement())for integer PKs, or@id @default(uuid())for UUID PKs (seeUserFairnessSeedsatapi.prisma:147).@default(now())oncreatedAt,@updatedAtonupdatedAt.
Adding a relation¶
Follow the UserNote pattern (api.prisma:322-337):
model Announcement {
id Int @id @default(autoincrement()) @map("id")
title String @map("title")
body String @map("body")
active Boolean @default(true) @map("active")
authorId Int @map("author_id")
author User @relation(fields: [authorId], references: [id])
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
@@index([authorId])
@@map("announcement")
@@schema("public")
}
Then add the back-relation on the User model:
Adding an enum¶
Define it next to the model. Every enum also needs @@map and @@schema:
3. Generate the migration¶
cd ebit-api
npm run db:migrate:dev
# Prisma prompts for a migration name — use snake_case: add_announcement
This does three things in one command:
1. Diffs your schema against the database
2. Creates a SQL migration file under libs/_prisma/src/schema/migrations/<timestamp>_add_announcement/migration.sql
3. Applies the migration and regenerates the Prisma Client
All prisma commands are wrapped with env-cmd -f .env (package.json:23) — never call npx prisma directly or it will miss the DATABASE_URL.
To create a migration without applying it (for review):
4. Regenerate the client (if needed separately)¶
The generated client lands at node_modules/.prisma/client (no custom output in the generator block at api.prisma:1-4). Import it as:
5. Add seed data¶
Create libs/_prisma/src/seed/announcement.ts:
import prisma from './prisma';
export default async function announcement() {
await prisma.announcement.upsert({
where: { id: 1 },
update: {},
create: {
title: 'Welcome',
body: 'First announcement',
active: true,
},
});
}
Register it in libs/_prisma/src/seed/index.ts:26-54 — add the import at the top
and call await announcement() inside main():
import announcement from './announcement';
async function main() {
// ... existing seeds ...
await announcement(); // add at the end of the non-debug block
}
Use upsert so the seed is idempotent — it won't fail on re-runs.
6. Wire it into the app¶
Create a repository (standard NestJS pattern — see apps/api/src/bet/bet.repository.ts):
import { Injectable } from '@nestjs/common';
import { PrismaService } from '@app/_prisma';
@Injectable()
export class AnnouncementRepository {
constructor(private readonly prisma: PrismaService) {}
findMany() {
return this.prisma.announcement.findMany({
where: { active: true },
orderBy: { createdAt: 'desc' },
});
}
}
Register it as a provider in your module.
Useful commands¶
| Command | Purpose |
|---|---|
npm run db:migrate:dev |
Create + apply migration + regen client |
npm run db:migrate:dev:create |
Create migration only (review before applying) |
npm run db:seed |
Re-run all seeds |
npm run db:reset |
Drop + recreate + migrate + seed (destructive) |
npm run db:studio |
Open Prisma Studio GUI at localhost:5555 |
npm run prisma:dev:test |
Migrate the test database (uses .env.test) |