// This is your Prisma schema file, // learn more about it in the docs: https://pris.ly/d/prisma-schema // Looking for ways to speed up your queries, or scale easily with your serverless or edge functions? // Try Prisma Accelerate: https://pris.ly/cli/accelerate-init generator client { provider = "prisma-client-js" previewFeatures = ["postgresqlExtensions"] } datasource db { provider = "postgresql" url = env("DATABASE_URL") directUrl = env("DIRECT_URL") extensions = [pgcrypto] } model User { id String @id @db.Uuid email String @unique @db.VarChar(255) emailVerified Boolean @default(false) @map("email_verified") password String? @db.VarChar(255) firstName String? @map("first_name") @db.VarChar(255) lastName String? @map("last_name") @db.VarChar(255) avatar String? @db.VarChar(255) role Role @default(user) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") lastSignedIn DateTime? @map("last_signed_in") metadata Json? profile Profile? @@index([role]) @@map("users") } model Profile { id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid userId String @unique @map("user_id") @db.Uuid bio String? @db.Text phone String? @db.VarChar(20) address String? @db.VarChar(255) city String? @db.VarChar(100) country String? @db.VarChar(100) birthDate DateTime? @map("birth_date") user User @relation(fields: [userId], references: [id]) @@index([userId]) @@map("profiles") // Maps to Supabase's 'profiles' table } model ContactMessage { id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid name String? @db.VarChar(255) email String? @db.VarChar(255) phone String? @db.VarChar(20) messageType String? @map("message_type") @db.VarChar(50) messageTypeLabel String? @map("message_type_label") @db.VarChar(50) message String? @db.Text status StatusContactMessages @default(new) createdAt DateTime @default(dbgenerated("now()")) @map("created_at") @db.Timestamptz(6) updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(6) @@map("contact_messages") // Maps to Supabase's 'contact_messages' table } model NavItem { id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid title String @db.VarChar(255) url String @db.VarChar(255) slug String @db.VarChar(255) icon String @db.VarChar(100) isActive Boolean @default(false) @map("is_active") orderSeq Int @map("order_seq") createdAt DateTime @default(dbgenerated("now()")) @map("created_at") @db.Timestamptz(6) updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(6) subItems NavSubItem[] createdBy String? @map("created_by") @db.Uuid updatedBy String? @map("updated_by") @db.Uuid @@index([title]) @@index([isActive]) @@map("nav_items") } model NavSubItem { id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid title String @db.VarChar(255) url String @db.VarChar(255) slug String @db.VarChar(255) icon String @db.VarChar(100) isActive Boolean @default(false) @map("is_active") orderSeq Int @map("order_seq") navItemId String @map("nav_item_id") @db.Uuid createdAt DateTime @default(dbgenerated("now()")) @map("created_at") @db.Timestamptz(6) updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(6) createdBy String? @map("created_by") @db.Uuid updatedBy String? @map("updated_by") @db.Uuid navItem NavItem @relation(fields: [navItemId], references: [id], onDelete: Cascade) NavSubSubItem NavSubSubItem[] @@index([navItemId]) @@index([title]) @@map("nav_sub_items") } model NavSubSubItem { id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid title String @db.VarChar(255) url String @db.VarChar(255) slug String @db.VarChar(255) icon String @db.VarChar(100) isActive Boolean @default(false) @map("is_active") orderSeq Int @map("order_seq") navSubItemId String @map("nav_sub_item_id") @db.Uuid createdAt DateTime @default(dbgenerated("now()")) @map("created_at") @db.Timestamptz(6) updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(6) createdBy String? @map("created_by") @db.Uuid updatedBy String? @map("updated_by") @db.Uuid navSubItem NavSubItem @relation(fields: [navSubItemId], references: [id], onDelete: Cascade) @@index([navSubItemId]) @@index([title]) @@map("nav_sub_sub_items") } model NavigationItem { id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid title String @db.VarChar(255) url String? @db.VarChar(255) slug String @db.VarChar(255) icon String? @db.VarChar(100) path String @unique @db.VarChar(255) // Materialized path (e.g., "1.2.3") level Int @default(0) isActive Boolean @default(false) @map("is_active") orderSeq Int @map("order_seq") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") createdBy String? @map("created_by") @db.Uuid updatedBy String? @map("updated_by") @db.Uuid @@index([path]) @@index([level]) @@index([isActive]) @@map("navigation_items") } model City { id String @id @default(dbgenerated("gen_random_uuid()")) @map("id") @db.Uuid geographicId String? @map("geographic_id") @db.Uuid name String @map("name") @db.VarChar(100) code String @map("code") @db.VarChar(10) demographics Demographic[] crimes Crime[] districts District[] createdAt DateTime @default(dbgenerated("now()")) @map("created_at") @db.Timestamptz(6) updatedAt DateTime @default(dbgenerated("now()")) @updatedAt @map("updated_at") @db.Timestamptz(6) geographic Geographic? @relation(fields: [geographicId], references: [id]) @@index([name]) @@map("cities") } model District { id String @id @default(dbgenerated("gen_random_uuid()")) @map("id") @db.Uuid cityId String @map("city_id") @db.Uuid name String @map("name") @db.VarChar(100) code String @map("code") @db.VarChar(10) geographic Geographic? demographics Demographic[] crimes Crime[] createdAt DateTime @default(dbgenerated("now()")) @map("created_at") @db.Timestamptz(6) updatedAt DateTime @default(dbgenerated("now()")) @updatedAt @map("updated_at") @db.Timestamptz(6) city City @relation(fields: [cityId], references: [id], onDelete: Cascade) @@index([name]) @@map("districts") } model Geographic { id String @id @default(dbgenerated("gen_random_uuid()")) @map("id") @db.Uuid districtId String? @unique @map("district_id") @db.Uuid latitude Float? @map("latitude") longitude Float? @map("longitude") landArea Float? @map("land_area") polygon Json? @map("polygon") createdAt DateTime @default(dbgenerated("now()")) @map("created_at") @db.Timestamptz(6) updatedAt DateTime @default(dbgenerated("now()")) @updatedAt @map("updated_at") @db.Timestamptz(6) district District? @relation(fields: [districtId], references: [id]) cities City[] @@map("geographics") } model Demographic { id String @id @default(dbgenerated("gen_random_uuid()")) @map("id") @db.Uuid districtId String? @map("district_id") @db.Uuid cityId String? @map("city_id") @db.Uuid provinceId String? @map("province_id") @db.Uuid year Int @map("year") population Int @map("population") populationDensity Float @map("population_density") povertyRate Float @map("poverty_rate") createdAt DateTime @default(dbgenerated("now()")) @map("created_at") @db.Timestamptz(6) updatedAt DateTime @default(dbgenerated("now()")) @updatedAt @map("updated_at") @db.Timestamptz(6) district District? @relation(fields: [districtId], references: [id]) city City? @relation(fields: [cityId], references: [id]) @@unique([districtId, year]) @@unique([cityId, year]) @@map("demographics") } model Crime { id String @id @default(dbgenerated("gen_random_uuid()")) @map("id") @db.Uuid districtId String? @map("district_id") @db.Uuid cityId String? @map("city_id") @db.Uuid year Int @map("year") numberOfCrime Int @map("number_of_crime") rate CrimeRate @default(low) @map("rate") heatMap Json? @map("heat_map") createdAt DateTime @default(dbgenerated("now()")) @map("created_at") @db.Timestamptz(6) updatedAt DateTime @default(dbgenerated("now()")) @updatedAt @map("updated_at") @db.Timestamptz(6) district District? @relation(fields: [districtId], references: [id]) city City? @relation(fields: [cityId], references: [id]) crimeCases CrimeCase[] @@unique([districtId, year]) @@unique([cityId, year]) @@map("crimes") } model CrimeCase { id String @id @default(dbgenerated("gen_random_uuid()")) @map("id") @db.Uuid crimeId String? @map("crime_id") @db.Uuid crimeCategoryId String? @map("crime_category_id") @db.Uuid date DateTime @map("date") @db.Timestamptz(6) time DateTime @map("time") @db.Timestamptz(6) location String @map("location") @db.VarChar(255) latitude Float @map("latitude") longitude Float @map("longitude") description String @map("description") @db.Text victimCount Int @map("victim_count") status CrimeStatus @default(new) @map("status") createdAt DateTime @default(dbgenerated("now()")) @map("created_at") @db.Timestamptz(6) updatedAt DateTime @default(dbgenerated("now()")) @updatedAt @map("updated_at") @db.Timestamptz(6) crime Crime? @relation(fields: [crimeId], references: [id]) crimeCategory CrimeCategory? @relation(fields: [crimeCategoryId], references: [id]) @@map("crime_cases") } model CrimeCategory { id String @id @default(dbgenerated("gen_random_uuid()")) @map("id") @db.Uuid name String @map("name") @db.VarChar(255) description String @map("description") @db.Text crimeCases CrimeCase[] createdAt DateTime @default(dbgenerated("now()")) @map("created_at") @db.Timestamptz(6) updatedAt DateTime @default(dbgenerated("now()")) @updatedAt @map("updated_at") @db.Timestamptz(6) @@map("crime_categories") } enum Role { admin staff user @@map("roles") } enum StatusContactMessages { new read replied resolved @@map("status_contact_messages") } enum CrimeRate { low medium high @@map("crime_rates") } enum CrimeStatus { new inProgress @map("in_progress") resolved @@map("crime_status") }