226 lines
6.5 KiB
Plaintext
226 lines
6.5 KiB
Plaintext
generator client {
|
|
provider = "prisma-client-js"
|
|
}
|
|
|
|
datasource db {
|
|
provider = "postgresql"
|
|
url = env("DATABASE_URL")
|
|
}
|
|
|
|
// ─── Users ──────────────────────────────────────────────────────────
|
|
|
|
model User {
|
|
id String @id @default(cuid())
|
|
did String @unique // EncryptID DID
|
|
username String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
trips TripCollaborator[]
|
|
expenses Expense[]
|
|
packingItems PackingItem[]
|
|
}
|
|
|
|
// ─── Trips ──────────────────────────────────────────────────────────
|
|
|
|
model Trip {
|
|
id String @id @default(cuid())
|
|
title String
|
|
slug String @unique
|
|
description String? @db.Text
|
|
rawInput String? @db.Text // Original NL input preserved
|
|
startDate DateTime?
|
|
endDate DateTime?
|
|
budgetTotal Float?
|
|
budgetCurrency String @default("USD")
|
|
status TripStatus @default(PLANNING)
|
|
canvasSlug String? // rspace community slug
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
collaborators TripCollaborator[]
|
|
destinations Destination[]
|
|
itineraryItems ItineraryItem[]
|
|
bookings Booking[]
|
|
expenses Expense[]
|
|
packingItems PackingItem[]
|
|
}
|
|
|
|
enum TripStatus {
|
|
PLANNING
|
|
BOOKED
|
|
IN_PROGRESS
|
|
COMPLETED
|
|
CANCELLED
|
|
}
|
|
|
|
model TripCollaborator {
|
|
id String @id @default(cuid())
|
|
userId String
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
tripId String
|
|
trip Trip @relation(fields: [tripId], references: [id], onDelete: Cascade)
|
|
role CollaboratorRole @default(MEMBER)
|
|
joinedAt DateTime @default(now())
|
|
|
|
@@unique([userId, tripId])
|
|
@@index([tripId])
|
|
}
|
|
|
|
enum CollaboratorRole {
|
|
OWNER
|
|
EDITOR
|
|
VIEWER
|
|
MEMBER
|
|
}
|
|
|
|
// ─── Destinations ───────────────────────────────────────────────────
|
|
|
|
model Destination {
|
|
id String @id @default(cuid())
|
|
tripId String
|
|
trip Trip @relation(fields: [tripId], references: [id], onDelete: Cascade)
|
|
name String
|
|
country String?
|
|
lat Float?
|
|
lng Float?
|
|
arrivalDate DateTime?
|
|
departureDate DateTime?
|
|
notes String? @db.Text
|
|
sortOrder Int @default(0)
|
|
canvasShapeId String? // ID of folk-destination on canvas
|
|
createdAt DateTime @default(now())
|
|
|
|
itineraryItems ItineraryItem[]
|
|
bookings Booking[]
|
|
|
|
@@index([tripId])
|
|
}
|
|
|
|
// ─── Itinerary ──────────────────────────────────────────────────────
|
|
|
|
model ItineraryItem {
|
|
id String @id @default(cuid())
|
|
tripId String
|
|
trip Trip @relation(fields: [tripId], references: [id], onDelete: Cascade)
|
|
destinationId String?
|
|
destination Destination? @relation(fields: [destinationId], references: [id], onDelete: SetNull)
|
|
title String
|
|
description String? @db.Text
|
|
date DateTime?
|
|
startTime String? // "09:00" format
|
|
endTime String? // "17:00" format
|
|
category ItineraryCategory @default(ACTIVITY)
|
|
sortOrder Int @default(0)
|
|
canvasShapeId String?
|
|
createdAt DateTime @default(now())
|
|
|
|
@@index([tripId])
|
|
@@index([destinationId])
|
|
}
|
|
|
|
enum ItineraryCategory {
|
|
FLIGHT
|
|
TRANSPORT
|
|
ACCOMMODATION
|
|
ACTIVITY
|
|
MEAL
|
|
FREE_TIME
|
|
OTHER
|
|
}
|
|
|
|
// ─── Bookings ───────────────────────────────────────────────────────
|
|
|
|
model Booking {
|
|
id String @id @default(cuid())
|
|
tripId String
|
|
trip Trip @relation(fields: [tripId], references: [id], onDelete: Cascade)
|
|
destinationId String?
|
|
destination Destination? @relation(fields: [destinationId], references: [id], onDelete: SetNull)
|
|
type BookingType
|
|
provider String? // "Air Canada", "Booking.com"
|
|
confirmationNumber String?
|
|
details String? @db.Text // JSON for flexible data
|
|
cost Float?
|
|
currency String @default("USD")
|
|
startDate DateTime?
|
|
endDate DateTime?
|
|
status BookingStatus @default(PLANNED)
|
|
canvasShapeId String?
|
|
createdAt DateTime @default(now())
|
|
|
|
@@index([tripId])
|
|
}
|
|
|
|
enum BookingType {
|
|
FLIGHT
|
|
HOTEL
|
|
CAR_RENTAL
|
|
TRAIN
|
|
BUS
|
|
FERRY
|
|
ACTIVITY
|
|
RESTAURANT
|
|
OTHER
|
|
}
|
|
|
|
enum BookingStatus {
|
|
PLANNED
|
|
BOOKED
|
|
CONFIRMED
|
|
CANCELLED
|
|
}
|
|
|
|
// ─── Expenses ───────────────────────────────────────────────────────
|
|
|
|
model Expense {
|
|
id String @id @default(cuid())
|
|
tripId String
|
|
trip Trip @relation(fields: [tripId], references: [id], onDelete: Cascade)
|
|
paidById String?
|
|
paidBy User? @relation(fields: [paidById], references: [id], onDelete: SetNull)
|
|
description String
|
|
amount Float
|
|
currency String @default("USD")
|
|
category ExpenseCategory @default(OTHER)
|
|
date DateTime?
|
|
splitType SplitType @default(EQUAL)
|
|
createdAt DateTime @default(now())
|
|
|
|
@@index([tripId])
|
|
}
|
|
|
|
enum ExpenseCategory {
|
|
FLIGHT
|
|
ACCOMMODATION
|
|
FOOD
|
|
TRANSPORT
|
|
ACTIVITY
|
|
SHOPPING
|
|
OTHER
|
|
}
|
|
|
|
enum SplitType {
|
|
EQUAL
|
|
CUSTOM
|
|
INDIVIDUAL
|
|
}
|
|
|
|
// ─── Packing ────────────────────────────────────────────────────────
|
|
|
|
model PackingItem {
|
|
id String @id @default(cuid())
|
|
tripId String
|
|
trip Trip @relation(fields: [tripId], references: [id], onDelete: Cascade)
|
|
addedById String?
|
|
addedBy User? @relation(fields: [addedById], references: [id], onDelete: SetNull)
|
|
name String
|
|
category String? // "Clothing", "Electronics", "Documents"
|
|
packed Boolean @default(false)
|
|
quantity Int @default(1)
|
|
sortOrder Int @default(0)
|
|
createdAt DateTime @default(now())
|
|
|
|
@@index([tripId])
|
|
}
|