Agent skill

vendix-prisma-schema

Prisma schema editing.

Stars 163
Forks 31

Install this agent skill to your Project

npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/data/vendix-prisma-schema

Metadata

Additional technical details for this skill

scope
[
    "root"
]
auto invoke
Editing Schema

SKILL.md

Vendix Prisma Schema Pattern

Schema Editing & Migrations - EdiciΓ³n de schema.prisma, relaciones y workflow de migraciones en desarrollo.

🎯 Schema Structure

File: apps/backend/prisma/schema.prisma

prisma
generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

πŸ“ Naming Conventions

Database Objects

prisma
// βœ… CORRECT - Tables in snake_case
model users {}
model product_variants {}
model sales_order_items {}

// βœ… CORRECT - Enums in snake_case with _enum suffix
enum user_state_enum {
  ACTIVE
  INACTIVE
  PENDING
}

// ❌ WRONG - Tables in PascalCase
model Users {}
model ProductVariants {}

// ❌ WRONG - Enums in PascalCase
enum UserState {}

Fields

prisma
// βœ… CORRECT - Fields in snake_case
model users {
  id               Int
  user_name        String
  email_address    String
  organization_id  Int
  main_store_id    Int?
  created_at       DateTime
  updated_at       DateTime
}

// ❌ WRONG - Fields in camelCase
model users {
  id               Int
  userName         String
  emailAddress     String
  organizationId   Int
  createdAt        DateTime
}

πŸ”— Relationship Patterns

One-to-Many

prisma
model organizations {
  id        Int       @id @default(autoincrement())
  name      String
  users     users[]   // One organization has many users
  stores    stores[]  // One organization has many stores
}

model users {
  id              Int            @id @default(autoincrement())
  organization_id Int
  organization    organizations  @relation(fields: [organization_id], references: [id])

  // Index for foreign key
  @@index([organization_id])
}

Many-to-Many

prisma
model users {
  id         Int          @id @default(autoincrement())
  user_name  String
  store_users store_users[]  // Join table
}

model stores {
  id         Int          @id @default(autoincrement())
  name       String
  store_users store_users[]  // Join table
}

// Join table
model store_users {
  user_id    Int
  store_id   Int
  role       String

  user       users     @relation(fields: [user_id], references: [id], onDelete: Cascade)
  store      stores    @relation(fields: [store_id], references: [id], onDelete: Cascade)

  @@id([user_id, store_id])  // Composite primary key
}

Self-Referencing

prisma
model users {
  id           Int      @id @default(autoincrement())
  user_name    String
  manager_id   Int?
  manager      users?   @relation("ManagerRelation", fields: [manager_id], references: [id])
  subordinates users[]  @relation("ManagerRelation")
}

🎨 Field Types & Attributes

Common Field Types

prisma
model products {
  id            Int      @id @default(autoincrement())
  name          String
  description   String?  @db.Text
  base_price    Decimal  @db.Decimal(10, 2)
  is_active     Boolean  @default(true)
  stock_quantity Int     @default(0)
  created_at    DateTime @default(now())
  updated_at    DateTime @updatedAt

  // Enums
  status        product_status_enum @default(ACTIVE)

  // JSON field for metadata
  metadata      Json?

  // Array of strings (PostgreSQL specific)
  tags          String[]

  // Indexes
  @@index([organization_id, store_id])
  @@index([is_active])
}

enum product_status_enum {
  ACTIVE
  INACTIVE
  DRAFT
  ARCHIVED
}

Field Attributes

Attribute Description Example
@id Primary key id Int @id
@default(value) Default value created_at DateTime @default(now())
@unique Unique constraint email String @unique
@relation Define relation organization organizations @relation(...)
@map(name) Map to different column name user_name String @map("userName")
@updatedAt Auto-update timestamp updated_at DateTime @updatedAt
@db.Type Database-specific type price Decimal @db.Decimal(10,2)
@@index Define index @@index([field1, field2])
@@unique Unique constraint on multiple fields @@unique([email, organization_id])
@@map Map table to different name @@map("users")

πŸ”„ Migration Workflow

Development Mode

bash
# 1. Make changes to schema.prisma

# 2. Create migration (auto-applies in development)
npx prisma migrate dev --name describe_your_changes

# This will:
# - Generate migration SQL
# - Apply migration to database
# - Regenerate Prisma Client

# 3. Verify migration was applied
npx prisma migrate status

# 4. If needed, reset database (WARNING: deletes all data)
npx prisma migrate reset

Production Mode

bash
# 1. Create migration without applying
npx prisma migrate dev --create-only --name describe_your_changes

# 2. Review generated migration SQL
# Edit migration if needed

# 3. Apply migration (production environment)
npx prisma migrate deploy

🎯 Schema Editing Workflow

Step 1: Backup Current State

bash
# Export current schema
npx prisma migrate diff \
  --from-empty \
  --to-schema-datamodel prisma/schema.prisma \
  --script > backup.sql

Step 2: Edit Schema

prisma
// Example: Adding new field
model products {
  id            Int      @id @default(autoincrement())
  name          String
  weight        Decimal?  @db.Decimal(10, 2)  // NEW FIELD
  dimensions    Json?                         // NEW FIELD
}

Step 3: Create Migration

bash
npx prisma migrate dev --name add_product_weight_and_dimensions

Step 4: Review Migration

sql
-- Migration SQL
ALTER TABLE "products" ADD COLUMN "weight" DECIMAL(10,2);
ALTER TABLE "products" ADD COLUMN "dimensions" JSONB;

Step 5: Apply & Test

bash
# Migration applied automatically
# Verify with Docker logs
docker logs --tail 40 vendix_backend

πŸ” Common Schema Patterns

Soft Delete Pattern

prisma
model users {
  id         Int       @id @default(autoincrement())
  user_name  String
  deleted_at DateTime?  // Soft delete timestamp
  is_active  Boolean   @default(true)

  @@index([deleted_at])
}

// Query for non-deleted records
const users = await prisma.users.findMany({
  where: {
    deleted_at: null,
    is_active: true,
  },
});

Timestamps Pattern

prisma
model base_model {
  id         Int      @id @default(autoincrement())
  created_at DateTime @default(now())
  updated_at DateTime @updatedAt
}

Multi-Tenant Pattern

prisma
model products {
  id              Int      @id @default(autoincrement())
  name            String
  organization_id Int      // Tenant ID
  store_id        Int      // Sub-tenant ID

  organization    organizations @relation(fields: [organization_id], references: [id])
  store           stores        @relation(fields: [store_id], references: [id])

  @@index([organization_id, store_id])
}

🚫 Common Mistakes

❌ WRONG: PascalCase Tables

prisma
model Users {  // ❌ WRONG
  id Int @id
  UserName String  // ❌ WRONG
}

βœ… CORRECT: snake_case Tables

prisma
model users {  // βœ… CORRECT
  id        Int      @id
  user_name String   // βœ… CORRECT
}

❌ WRONG: Missing Foreign Key Indexes

prisma
model products {
  id              Int
  organization_id Int  // ❌ Missing index
}

βœ… CORRECT: With Indexes

prisma
model products {
  id              Int
  organization_id Int

  @@index([organization_id])  // βœ… Index for foreign key
}

πŸ” Key Files Reference

File Purpose
prisma/schema.prisma Database schema definition
prisma/migrations/ Migration files
prisma/services/ Extended Prisma services

Related Skills

  • vendix-backend-prisma - Prisma service patterns
  • vendix-prisma-seed - Seed data patterns
  • vendix-naming-conventions - Naming conventions (CRITICAL)

Didn't find tool you were looking for?

Be as detailed as possible for better results