191 lines
5.0 KiB
Plaintext
191 lines
5.0 KiB
Plaintext
// This is your Prisma schema file,
|
|
// learn more about it in the docs: https://pris.ly/d/prisma-schema
|
|
|
|
generator client {
|
|
provider = "prisma-client-js"
|
|
previewFeatures = ["driverAdapters"]
|
|
}
|
|
|
|
datasource db {
|
|
provider = "postgresql"
|
|
url = env("DATABASE_URL")
|
|
}
|
|
|
|
// --- Enums ---
|
|
|
|
enum ParticipantRole {
|
|
OWNER
|
|
MANAGER
|
|
MEMBER
|
|
MEMBER_NO_FINANCE
|
|
VIEWER_ONLY
|
|
}
|
|
|
|
enum JoinRequestStatus {
|
|
PENDING
|
|
ACCEPTED
|
|
REJECTED
|
|
}
|
|
|
|
enum ExpenseCategory {
|
|
ACCOMMODATION
|
|
FOOD
|
|
TRANSPORT
|
|
TICKET
|
|
OTHER
|
|
}
|
|
|
|
enum LocationStatus {
|
|
PENDING
|
|
COMPLETED
|
|
}
|
|
|
|
enum LocationType {
|
|
MOVE
|
|
VISIT
|
|
REST
|
|
EAT
|
|
}
|
|
|
|
enum PrivacyLevel {
|
|
PUBLIC
|
|
TOUR_ONLY
|
|
PRIVATE
|
|
}
|
|
|
|
// --- Models ---
|
|
|
|
model User {
|
|
id String @id @default(uuid())
|
|
email String @unique
|
|
passwordHash String
|
|
name String?
|
|
phone String?
|
|
address String?
|
|
avatar String?
|
|
createdAt DateTime @default(now())
|
|
isAdmin Boolean @default(false)
|
|
isBlocked Boolean @default(false)
|
|
|
|
createdTours Tour[] @relation("TourCreator")
|
|
tourParticipations TourParticipant[]
|
|
requestedJoinRequests JoinRequest[] @relation("JoinRequestUser")
|
|
receivedJoinRequests JoinRequest[] @relation("JoinRequester")
|
|
uploadedPhotos Photo[]
|
|
paidExpenses Expense[] @relation("ExpensePaidBy")
|
|
}
|
|
|
|
model Tour {
|
|
id String @id @default(uuid())
|
|
title String
|
|
description String?
|
|
startDate DateTime?
|
|
endDate DateTime?
|
|
createdAt DateTime @default(now())
|
|
totalCost Decimal @default(0) @db.Decimal(15, 2)
|
|
|
|
adultCount Int @default(1)
|
|
childCount Int @default(0)
|
|
childDiscount Int @default(30)
|
|
|
|
createdById String
|
|
creator User @relation("TourCreator", fields: [createdById], references: [id])
|
|
|
|
participants TourParticipant[]
|
|
joinRequests JoinRequest[]
|
|
legs Leg[]
|
|
photos Photo[]
|
|
}
|
|
|
|
model JoinRequest {
|
|
id String @id @default(uuid())
|
|
tourId String
|
|
userId String
|
|
requestedById String
|
|
status JoinRequestStatus @default(PENDING)
|
|
createdAt DateTime @default(now())
|
|
|
|
tour Tour @relation(fields: [tourId], references: [id], onDelete: Cascade)
|
|
user User @relation("JoinRequestUser", fields: [userId], references: [id], onDelete: Cascade)
|
|
requestedBy User @relation("JoinRequester", fields: [requestedById], references: [id], onDelete: Cascade)
|
|
|
|
@@index([tourId, status])
|
|
@@index([userId])
|
|
}
|
|
|
|
model TourParticipant {
|
|
tourId String
|
|
userId String
|
|
role ParticipantRole @default(MEMBER)
|
|
|
|
tour Tour @relation(fields: [tourId], references: [id], onDelete: Cascade)
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@id([tourId, userId])
|
|
}
|
|
|
|
model Leg {
|
|
id String @id @default(uuid())
|
|
tourId String
|
|
sequence Int
|
|
note String? @db.Text
|
|
startDate DateTime?
|
|
endDate DateTime?
|
|
description String? @db.Text
|
|
|
|
tour Tour @relation(fields: [tourId], references: [id], onDelete: Cascade)
|
|
locations Location[]
|
|
expenses Expense[]
|
|
}
|
|
|
|
model Location {
|
|
id String @id @default(uuid())
|
|
legId String
|
|
name String
|
|
address String?
|
|
latitude Float
|
|
longitude Float
|
|
|
|
plannedStart DateTime?
|
|
plannedEnd DateTime?
|
|
actualStart DateTime?
|
|
actualEnd DateTime?
|
|
|
|
status LocationStatus @default(PENDING)
|
|
type LocationType @default(VISIT)
|
|
|
|
leg Leg @relation(fields: [legId], references: [id], onDelete: Cascade)
|
|
expenses Expense[]
|
|
photos Photo[]
|
|
}
|
|
|
|
model Expense {
|
|
id String @id @default(uuid())
|
|
legId String @map("leg_id")
|
|
locationId String? @map("location_id")
|
|
category ExpenseCategory
|
|
amount Decimal @db.Decimal(15, 2)
|
|
description String? @db.Text
|
|
note String? @db.Text
|
|
paidById String? @map("paid_by_id")
|
|
|
|
leg Leg @relation(fields: [legId], references: [id], onDelete: Cascade)
|
|
location Location? @relation(fields: [locationId], references: [id], onDelete: Cascade)
|
|
paidBy User? @relation("ExpensePaidBy", fields: [paidById], references: [id], onDelete: SetNull)
|
|
}
|
|
|
|
model Photo {
|
|
id String @id @default(uuid())
|
|
tourId String
|
|
locationId String?
|
|
uploaderId String
|
|
imageUrl String
|
|
capturedAt DateTime @default(now())
|
|
metadata Json?
|
|
privacy PrivacyLevel @default(TOUR_ONLY)
|
|
|
|
tour Tour @relation(fields: [tourId], references: [id], onDelete: Cascade)
|
|
location Location? @relation(fields: [locationId], references: [id], onDelete: SetNull)
|
|
uploader User @relation(fields: [uploaderId], references: [id])
|
|
}
|