Agent skill
vendix-prisma-seed
Seeding patterns.
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/data/vendix-prisma-seed
Metadata
Additional technical details for this skill
- scope
-
[ "root" ] - auto invoke
- Creating Seeds
SKILL.md
Vendix Prisma Seed Pattern
Seed Data Structure - Seeds estructurados con orden de eliminaciΓ³n y creaciΓ³n consistente.
π― Seed Structure
File: apps/backend/prisma/seeds/shared/database.ts
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
export async function clearDatabase(prisma_client: PrismaClient = prisma) {
// Deletion order (reverse of dependencies)
const deleteOperations = [
// Delete dependents first
{ name: 'sales_order_items', model: prisma_client.sales_order_items },
{ name: 'sales_orders', model: prisma_client.sales_orders },
{ name: 'cart_items', model: prisma_client.cart_items },
{ name: 'wishlists', model: prisma_client.wishlists },
// Delete main entities
{ name: 'products', model: prisma_client.products },
{ name: 'stores', model: prisma_client.stores },
{ name: 'store_users', model: prisma_client.store_users },
{ name: 'users', model: prisma_client.users },
{ name: 'organizations', model: prisma_client.organizations },
];
for (const operation of deleteOperations) {
await operation.model.deleteMany({});
console.log(`β Cleared ${operation.name}`);
}
}
π Seed Directory Structure
apps/backend/prisma/seeds/
βββ shared/
β βββ database.ts # Database utilities
β βββ helpers.ts # Seed helpers
βββ dev/
β βββ index.ts # Main seed file
β βββ seed-organizations.ts # Organization seeds
β βββ seed-users.ts # User seeds
β βββ seed-stores.ts # Store seeds
β βββ seed-products.ts # Product seeds
βββ prod/
βββ index.ts # Production seeds (minimal)
π± Seed Pattern
Base Seed Function
// seeds/shared/helpers.ts
export async function seedWithRetry<T>(
seed_name: string,
seed_function: () => Promise<T>,
max_retries = 3,
): Promise<T> {
let last_error: Error | null = null;
for (let attempt = 1; attempt <= max_retries; attempt++) {
try {
console.log(`Seeding ${seed_name} (attempt ${attempt}/${max_retries})...`);
const result = await seed_function();
console.log(`β ${seed_name} seeded successfully`);
return result;
} catch (error) {
last_error = error;
console.error(`β Failed to seed ${seed_name}:`, error.message);
if (attempt < max_retries) {
console.log(`Retrying in 1 second...`);
await new Promise(resolve => setTimeout(resolve, 1000));
}
}
}
throw last_error;
}
Organization Seed
// seeds/dev/seed-organizations.ts
import { PrismaClient } from '@prisma/client';
import { seedWithRetry } from '../shared/helpers';
export async function seedOrganizations(prisma: PrismaClient) {
return seedWithRetry('organizations', async () => {
const organizations = await Promise.all([
prisma.organizations.create({
data: {
name: 'Acme Corporation',
domain_name: 'acme',
is_active: true,
},
}),
prisma.organizations.create({
data: {
name: 'Globex Inc',
domain_name: 'globex',
is_active: true,
},
}),
prisma.organizations.create({
data: {
name: 'Soylent Corp',
domain_name: 'soylent',
is_active: false, // Inactive organization
},
}),
]);
console.log(`β Created ${organizations.length} organizations`);
return organizations;
});
}
User Seed
// seeds/dev/seed-users.ts
import { PrismaClient } from '@prisma/client';
import * as bcrypt from 'bcrypt';
import { seedWithRetry } from '../shared/helpers';
export async function seedUsers(prisma: PrismaClient, organizations: any[]) {
return seedWithRetry('users', async () => {
const hashed_password = await bcrypt.hash('Password123!', 10);
const users = await Promise.all([
// Super Admin
prisma.users.create({
data: {
user_name: 'super_admin',
email: 'superadmin@vendix.com',
password: hashed_password,
organization_id: organizations[0].id,
roles: ['super_admin'],
is_active: true,
},
}),
// Organization Admin
prisma.users.create({
data: {
user_name: 'org_admin',
email: 'admin@acme.com',
password: hashed_password,
organization_id: organizations[0].id,
main_store_id: null,
roles: ['organization_admin'],
is_active: true,
},
}),
// Store Admin
prisma.users.create({
data: {
user_name: 'store_admin',
email: 'storeadmin@acme.com',
password: hashed_password,
organization_id: organizations[0].id,
roles: ['store_admin'],
is_active: true,
},
}),
// Regular User
prisma.users.create({
data: {
user_name: 'john_doe',
email: 'john@acme.com',
password: hashed_password,
organization_id: organizations[0].id,
roles: ['store_user'],
is_active: true,
},
}),
]);
console.log(`β Created ${users.length} users`);
return users;
});
}
Store Seed
// seeds/dev/seed-stores.ts
import { PrismaClient } from '@prisma/client';
import { seedWithRetry } from '../shared/helpers';
export async function seedStores(prisma: PrismaClient, organizations: any[]) {
return seedWithRetry('stores', async () => {
const stores = await Promise.all([
prisma.stores.create({
data: {
name: 'Acme Main Store',
domain_name: 'acme-main',
description: 'Main retail location',
organization_id: organizations[0].id,
is_active: true,
logo_url: 'https://example.com/logo.png',
theme_config: {
primary_color: '#0066cc',
secondary_color: '#ff6600',
font_family: 'Roboto',
},
},
}),
prisma.stores.create({
data: {
name: 'Acme Online Store',
domain_name: 'acme-online',
description: 'E-commerce storefront',
organization_id: organizations[0].id,
is_active: true,
theme_config: {
primary_color: '#0099ff',
secondary_color: '#ff9900',
font_family: 'Open Sans',
},
},
}),
]);
console.log(`β Created ${stores.length} stores`);
return stores;
});
}
Product Seed
// seeds/dev/seed-products.ts
import { PrismaClient } from '@prisma/client';
import { seedWithRetry } from '../shared/helpers';
export async function seedProducts(prisma: PrismaClient, stores: any[]) {
return seedWithRetry('products', async () => {
const products = await Promise.all([
prisma.products.create({
data: {
name: 'Wireless Headphones',
description: 'High-quality wireless headphones',
base_price: 79.99,
organization_id: stores[0].organization_id,
store_id: stores[0].id,
is_active: true,
stock_quantity: 100,
images: [
'https://example.com/headphones1.jpg',
'https://example.com/headphones2.jpg',
],
product_variants: {
create: [
{
sku: 'WH-BLK',
color: 'Black',
price_adjustment: 0,
stock_quantity: 50,
},
{
sku: 'WH-WHT',
color: 'White',
price_adjustment: 0,
stock_quantity: 50,
},
],
},
},
}),
prisma.products.create({
data: {
name: 'USB-C Cable',
description: '6ft USB-C charging cable',
base_price: 12.99,
organization_id: stores[0].organization_id,
store_id: stores[0].id,
is_active: true,
stock_quantity: 500,
images: [
'https://example.com/cable.jpg',
],
product_variants: {
create: [
{
sku: 'UC-6FT',
color: 'Red',
price_adjustment: 0,
stock_quantity: 250,
},
{
sku: 'UC-10FT',
color: 'Blue',
price_adjustment: 2.00,
stock_quantity: 250,
},
],
},
},
}),
]);
console.log(`β Created ${products.length} products`);
return products;
});
}
π Main Seed File
// seeds/dev/index.ts
import { PrismaClient } from '@prisma/client';
import { clearDatabase } from '../shared/database';
import { seedOrganizations } from './seed-organizations';
import { seedUsers } from './seed-users';
import { seedStores } from './seed-stores';
import { seedProducts } from './seed-products';
const prisma = new PrismaClient();
async function main() {
console.log('π± Starting database seed...\n');
// Clear existing data
console.log('Clearing existing data...');
await clearDatabase(prisma);
console.log('β Database cleared\n');
// Seed in order of dependencies
const organizations = await seedOrganizations(prisma);
console.log('');
const users = await seedUsers(prisma, organizations);
console.log('');
const stores = await seedStores(prisma, organizations);
console.log('');
const products = await seedProducts(prisma, stores);
console.log('');
// Assign stores to users
console.log('Assigning stores to users...');
await Promise.all([
// Store admin gets main store
prisma.store_users.create({
data: {
user_id: users[2].id, // store_admin
store_id: stores[0].id,
role: 'store_admin',
},
}),
// Regular user gets online store
prisma.store_users.create({
data: {
user_id: users[3].id, // john_doe
store_id: stores[1].id,
role: 'store_user',
},
}),
]);
console.log('β Stores assigned\n');
console.log('β
Database seed completed successfully!');
console.log('\nπ Summary:');
console.log(` - ${organizations.length} organizations`);
console.log(` - ${users.length} users`);
console.log(` - ${stores.length} stores`);
console.log(` - ${products.length} products`);
}
main()
.catch((e) => {
console.error('β Seed failed:', e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});
π§ Running Seeds
Development Seed
# Reset database and seed
npx prisma migrate reset
# Or run seed directly
npx prisma db seed
# Or with npm script
npm run db:seed
Production Seed
# Only seed essential data (admin users, etc.)
npx prisma db seed -- --production
π Package.json Configuration
{
"prisma": {
"seed": "ts-node --compiler-options {\"module\":\"CommonJS\"} prisma/seeds/dev/index.ts"
}
}
π Key Files Reference
| File | Purpose |
|---|---|
seeds/shared/database.ts |
Database utilities |
seeds/shared/helpers.ts |
Seed helper functions |
seeds/dev/index.ts |
Main seed file |
seeds/dev/seed-*.ts |
Entity-specific seeds |
Related Skills
vendix-prisma-schema- Schema editing patternsvendix-backend-prisma- Prisma service patternsvendix-naming-conventions- Naming conventions (CRITICAL)
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
Didn't find tool you were looking for?