rtrips-online/prisma/schema.prisma

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])
}