// prisma/schema.prisma generator client { provider = "prisma-client-js" output = "../node_modules/.prisma/client" engineType = "binary" } datasource db { provider = "postgresql" } // ─── Enums ────────────────────────────────────────────────────── enum UserRole { USER SHELTER_ADMIN ADMIN } enum Species { DOG CAT OTHER } enum Sex { MALE FEMALE } enum AnimalStatus { AVAILABLE RESERVED ADOPTED } enum DonationType { MONETARY FOOD TOYS } enum ReservationStatus { PENDING CONFIRMED CANCELLED COMPLETED } enum DonationStatus { PENDING CONFIRMED DELIVERED CANCELLED } // ─── Models ───────────────────────────────────────────────────── model User { id String @id @default(cuid()) email String @unique password String // bcrypt hash — nunca em texto simples name String birthdate DateTime district String role UserRole @default(USER) darkMode Boolean @default(false) emailVerified Boolean @default(false) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt reservations Reservation[] donations Donation[] @@index([email]) @@index([district]) } model Shelter { id String @id @default(cuid()) name String district String address String latitude Float longitude Float phone String email String @unique passwordHash String description String? website String? // JSON: { mon: "09:00-18:00", tue: "09:00-18:00", ... , sun: null } openHours Json verified Boolean @default(false) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt animals Animal[] donations Donation[] needs ShelterNeed[] @@index([district]) } model Animal { id String @id @default(cuid()) shelterId String shelter Shelter @relation(fields: [shelterId], references: [id]) name String species Species breed String? // relevante para DOG e CAT ageMonths Int // idade em meses para precisão sex Sex sterilized Boolean status AnimalStatus @default(AVAILABLE) urgent Boolean @default(false) description String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt photos AnimalPhoto[] reservations Reservation[] @@index([shelterId]) @@index([species]) @@index([status]) } model AnimalPhoto { id String @id @default(cuid()) animalId String animal Animal @relation(fields: [animalId], references: [id], onDelete: Cascade) url String isPrimary Boolean @default(false) createdAt DateTime @default(now()) @@index([animalId]) } model Reservation { id String @id @default(cuid()) userId String user User @relation(fields: [userId], references: [id]) animalId String animal Animal @relation(fields: [animalId], references: [id]) date DateTime status ReservationStatus @default(PENDING) emailSent Boolean @default(false) notes String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([userId]) @@index([animalId]) @@index([date]) } model Donation { id String @id @default(cuid()) userId String user User @relation(fields: [userId], references: [id]) shelterId String shelter Shelter @relation(fields: [shelterId], references: [id]) type DonationType // Para FOOD: { foodType: "dry|wet", animalType: "dog|cat", ageGroup: "adult|puppy" } // Para TOYS: { category: "chew|plush|interactive" } // Para MONETARY: { amount: 25.00, currency: "EUR" } // Partilhado: { deliveryMethod: "pickup|home_delivery", address?: "..." } details Json status DonationStatus @default(PENDING) emailSent Boolean @default(false) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt payment Payment? @@index([userId]) @@index([shelterId]) @@index([type]) } model Payment { id String @id @default(cuid()) donationId String @unique donation Donation @relation(fields: [donationId], references: [id]) stripePaymentId String @unique amount Int // em cêntimos (ex: 2500 = 25,00€) currency String @default("eur") status String // stripe payment status receiptUrl String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } model ShelterNeed { id String @id @default(cuid()) shelterId String shelter Shelter @relation(fields: [shelterId], references: [id]) type String // "food_dry_dog", "toys", "blankets", etc. description String? urgent Boolean @default(false) active Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([shelterId]) @@index([active]) }