diff --git a/prisma/migrations/20260604191234_multi_hotel_and_hotel_stay/migration.sql b/prisma/migrations/20260604191234_multi_hotel_and_hotel_stay/migration.sql new file mode 100644 index 0000000..0f9a59c --- /dev/null +++ b/prisma/migrations/20260604191234_multi_hotel_and_hotel_stay/migration.sql @@ -0,0 +1,33 @@ +-- DropIndex +DROP INDEX "Hotel_programId_key"; + +-- CreateTable +CREATE TABLE "HotelStay" ( + "id" TEXT NOT NULL, + "attendingMemberId" TEXT NOT NULL, + "hotelId" TEXT NOT NULL, + "roomNumber" TEXT, + "checkInAt" TIMESTAMP(3), + "checkOutAt" TIMESTAMP(3), + "notes" TEXT, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "HotelStay_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "HotelStay_attendingMemberId_key" ON "HotelStay"("attendingMemberId"); + +-- CreateIndex +CREATE INDEX "HotelStay_hotelId_idx" ON "HotelStay"("hotelId"); + +-- CreateIndex +CREATE INDEX "Hotel_programId_idx" ON "Hotel"("programId"); + +-- AddForeignKey +ALTER TABLE "HotelStay" ADD CONSTRAINT "HotelStay_attendingMemberId_fkey" FOREIGN KEY ("attendingMemberId") REFERENCES "AttendingMember"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "HotelStay" ADD CONSTRAINT "HotelStay_hotelId_fkey" FOREIGN KEY ("hotelId") REFERENCES "Hotel"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 12aa257..1e95b84 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -506,7 +506,7 @@ model Program { // Grand-finale logistics finalistSlotQuotas FinalistSlotQuota[] waitlistEntries WaitlistEntry[] - hotel Hotel? + hotels Hotel[] lunchEvent LunchEvent? @@unique([name, year]) @@ -2786,6 +2786,7 @@ model AttendingMember { flightDetail FlightDetail? visaApplication VisaApplication? lunchPick MemberLunchPick? + hotelStay HotelStay? @@unique([confirmationId, userId]) @@index([userId]) @@ -2802,7 +2803,7 @@ enum FlightDetailStatus { model Hotel { id String @id @default(cuid()) - programId String @unique // 1:1 — one hotel per edition + programId String // many hotels per edition name String address String? @db.Text link String? // external URL to hotel page / booking confirmation @@ -2810,7 +2811,28 @@ model Hotel { createdAt DateTime @default(now()) updatedAt DateTime @updatedAt - program Program @relation(fields: [programId], references: [id], onDelete: Cascade) + program Program @relation(fields: [programId], references: [id], onDelete: Cascade) + stays HotelStay[] + + @@index([programId]) +} + +/// Per-attendee hotel/room assignment (1:1 with AttendingMember, mirrors FlightDetail). +model HotelStay { + id String @id @default(cuid()) + attendingMemberId String @unique + hotelId String + roomNumber String? + checkInAt DateTime? + checkOutAt DateTime? + notes String? @db.Text + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + attendingMember AttendingMember @relation(fields: [attendingMemberId], references: [id], onDelete: Cascade) + hotel Hotel @relation(fields: [hotelId], references: [id], onDelete: Restrict) + + @@index([hotelId]) } model FlightDetail {