From 8da53127c7b2da09453672f857e86436bca2400f Mon Sep 17 00:00:00 2001 From: nico Date: Fri, 27 Mar 2026 14:36:46 +0800 Subject: [PATCH] feat: add duplicate prevention to seed - skip if data already exists - Added hasExistingData() function to check for existing seed data - Checks core entities: users (>1), banjars (>=6), divisions (>=4) - runSeed() now skips entirely if data exists - runSpecificSeeder() skips non-auth seeders if data exists - Provides helpful message with reset instructions - Prevents accidental duplicate data on re-run Usage: - bun run seed - Will skip if data exists - bun x prisma migrate reset - Reset database before re-seeding Co-authored-by: Qwen-Coder --- prisma/seed.ts | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/prisma/seed.ts b/prisma/seed.ts index d74aaad..6e0195f 100644 --- a/prisma/seed.ts +++ b/prisma/seed.ts @@ -19,6 +19,22 @@ import { seedPhase2 } from "./seeders/seed-phase2"; const prisma = new PrismaClient(); +/** + * Check if seed has already been run + * Returns true if core data already exists + */ +export async function hasExistingData(): Promise { + // Check for core entities that should always exist after seeding + const [userCount, banjarCount, divisionCount] = await Promise.all([ + prisma.user.count(), + prisma.banjar.count(), + prisma.division.count(), + ]); + + // If we have more than 1 user (admin), 6 banjars, and 4 divisions, assume seeded + return userCount > 1 && banjarCount >= 6 && divisionCount >= 4; +} + /** * Run All Seeders * Executes all seeder functions in the correct order @@ -26,6 +42,17 @@ const prisma = new PrismaClient(); export async function runSeed() { console.log("🌱 Starting seed...\n"); + // Check if data already exists + const existingData = await hasExistingData(); + if (existingData) { + console.log("⏭️ Existing data detected. Skipping seed to prevent duplicates.\n"); + console.log("💡 To re-seed, either:"); + console.log(" 1. Run: bun x prisma migrate reset (resets database)"); + console.log(" 2. Manually delete data from tables\n"); + console.log("✅ Seed skipped successfully!\n"); + return; + } + // 1. Seed Authentication (Admin & Demo Users) console.log("📁 [1/7] Authentication & Users"); const adminId = await seedAdminUser(); @@ -84,6 +111,17 @@ export async function runSeed() { export async function runSpecificSeeder(name: string) { console.log(`🌱 Running specific seeder: ${name}\n`); + // Check if data already exists for specific seeder + const existingData = await hasExistingData(); + if (existingData && name !== "auth") { + console.log("⚠️ Warning: Existing data detected for this seeder category.\n"); + console.log("💡 To re-seed, either:"); + console.log(" 1. Run: bun x prisma migrate reset (resets database)"); + console.log(" 2. Manually delete data from tables\n"); + console.log("✅ Seeder skipped to prevent duplicates!\n"); + return; + } + switch (name) { case "auth": case "users":