diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 954a144b..1e73563b 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -2163,20 +2163,20 @@ enum StatusPeminjaman { // ========================================= USER ========================================= // model User { - id String @id @default(cuid()) + id String @id @default(cuid()) username String - nomor String @unique - roleId String @default("2") - isActive Boolean @default(false) - sessionInvalid Boolean @default(false) + nomor String @unique + roleId String @default("2") + isActive Boolean @default(false) + sessionInvalid Boolean @default(false) lastLogin DateTime? - createdAt DateTime @default(now()) - updatedAt DateTime @default(now()) @updatedAt - - sessions UserSession[] // ✅ Relasi one-to-many - role Role @relation(fields: [roleId], references: [id]) + createdAt DateTime @default(now()) + updatedAt DateTime @default(now()) @updatedAt + permissions Json? + sessions UserSession[] // ✅ Relasi one-to-many + role Role @relation(fields: [roleId], references: [id]) menuAccesses UserMenuAccess[] - + @@map("users") } @@ -2184,6 +2184,7 @@ model Role { id String @id @default(cuid()) name String @unique // ADMIN_DESA, ADMIN_KESEHATAN, ADMIN_SEKOLAH description String? + permissions Json? isActive Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@ -2203,18 +2204,18 @@ model KodeOtp { } model UserSession { - id String @id @default(cuid()) - token String @db.Text // ✅ JWT bisa panjang - expiresAt DateTime // ✅ Ubah jadi expiresAt (konsisten) - active Boolean @default(true) - createdAt DateTime @default(now()) - updatedAt DateTime @default(now()) @updatedAt - - user User @relation(fields: [userId], references: [id], onDelete: Cascade) - userId String // ✅ HAPUS @unique - user bisa punya multiple sessions - - @@index([userId]) // ✅ Index untuk query cepat - @@index([token]) // ✅ Index untuk verify cepat + id String @id @default(cuid()) + token String @db.Text // ✅ JWT bisa panjang + expiresAt DateTime // ✅ Ubah jadi expiresAt (konsisten) + active Boolean @default(true) + createdAt DateTime @default(now()) + updatedAt DateTime @default(now()) @updatedAt + + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + userId String // ✅ HAPUS @unique - user bisa punya multiple sessions + + @@index([userId]) // ✅ Index untuk query cepat + @@index([token]) // ✅ Index untuk verify cepat @@map("user_sessions") } diff --git a/prisma/seed.ts b/prisma/seed.ts index 5d90ea29..30ba668f 100644 --- a/prisma/seed.ts +++ b/prisma/seed.ts @@ -64,29 +64,22 @@ import { safeSeedUnique } from "./safeseedUnique"; (async () => { console.log("🔄 Seeding roles..."); - // Check for duplicate names in roles data - const roleNames = new Set(); - const duplicateRoleNames = roles.filter((r) => { - if (roleNames.has(r.name)) { - console.warn(`⚠️ Duplicate role name found: ${r.name}`); - return true; - } - roleNames.add(r.name); - return false; - }); - for (const r of roles) { try { + // ✅ Destructure to remove permissions if exists + const { permissions, ...roleData } = r as any; + await safeSeedUnique( "role", - { id: r.id }, + { id: roleData.id }, { - name: r.name, - description: r.description, - isActive: r.isActive, + name: roleData.name, + description: roleData.description, + permissions: roleData.permissions || {}, // ✅ Include permissions + isActive: roleData.isActive, } ); - console.log(`✅ Seeded role -> ${r.name}`); + console.log(`✅ Seeded role -> ${roleData.name}`); } catch (error: any) { if (error.code === "P2002") { console.warn(`⚠️ Role already exists (skipping): ${r.name}`); @@ -96,13 +89,15 @@ import { safeSeedUnique } from "./safeseedUnique"; } } console.log("✅ Roles seeding completed"); + // =========== USER =========== console.log("🔄 Seeding users..."); for (const u of users) { try { - // Verify role exists + // Verify role exists first const roleExists = await prisma.role.findUnique({ where: { id: u.roleId.toString() }, + select: { id: true }, // Only select id to minimize query }); if (!roleExists) { @@ -125,7 +120,13 @@ import { safeSeedUnique } from "./safeseedUnique"; ); console.log(`✅ Seeded user -> ${u.username}`); } catch (error: any) { - console.error(`❌ Failed to seed user ${u.username}:`, error.message); + if (error.code === "P2003") { + console.error( + `❌ Foreign key constraint failed for user ${u.username}: Role ${u.roleId} does not exist` + ); + } else { + console.error(`❌ Failed to seed user ${u.username}:`, error.message); + } } } console.log("✅ Users seeding completed");