feat: replacement
This commit is contained in:
@@ -46,17 +46,18 @@ model Product {
|
||||
}
|
||||
|
||||
model PickupSlot {
|
||||
id String @id @default(cuid())
|
||||
id String @id @default(cuid())
|
||||
// Human label fallback (e.g. "Måndag förmiddag").
|
||||
labelSv String
|
||||
labelEn String
|
||||
startsAt DateTime
|
||||
endsAt DateTime
|
||||
capacity Int @default(50)
|
||||
active Boolean @default(true)
|
||||
bookings Booking[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
labelSv String
|
||||
labelEn String
|
||||
startsAt DateTime
|
||||
endsAt DateTime
|
||||
capacity Int @default(50)
|
||||
active Boolean @default(true)
|
||||
bookings Booking[]
|
||||
replacements ReplacementRequest[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
// BookingStatus values (string, since SQLite has no enums):
|
||||
@@ -91,6 +92,8 @@ model Booking {
|
||||
pickupSlotId String?
|
||||
pickupSlot PickupSlot? @relation(fields: [pickupSlotId], references: [id])
|
||||
|
||||
replacements ReplacementRequest[]
|
||||
|
||||
notes String?
|
||||
|
||||
// Snapshots in öre at booking time
|
||||
@@ -131,5 +134,72 @@ model BookingItem {
|
||||
deliveredQuantity Int @default(0)
|
||||
returnedQuantity Int @default(0)
|
||||
|
||||
replacements ReplacementRequest[]
|
||||
|
||||
@@index([bookingId])
|
||||
}
|
||||
|
||||
// Customer-side magic-link tokens. Raw token lives only in the email;
|
||||
// DB stores SHA-256 hash. Single-use + 1h expiry.
|
||||
model CustomerMagicLink {
|
||||
id String @id @default(cuid())
|
||||
tokenHash String @unique
|
||||
email String
|
||||
expiresAt DateTime
|
||||
usedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@index([email])
|
||||
@@index([expiresAt])
|
||||
}
|
||||
|
||||
// Customer-side browser sessions, cookie value is hashed before storage.
|
||||
// Email is the identity — magic link gives access to all bookings with this email.
|
||||
model CustomerSession {
|
||||
id String @id @default(cuid())
|
||||
tokenHash String @unique
|
||||
email String
|
||||
expiresAt DateTime
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@index([email])
|
||||
@@index([expiresAt])
|
||||
}
|
||||
|
||||
// ReplacementRequest values for status (string, SQLite has no enums):
|
||||
// REQUESTED — customer just asked
|
||||
// SCHEDULED — admin assigned a slot / confirmed
|
||||
// DELIVERED — exchange done
|
||||
// CANCELLED — terminal
|
||||
model ReplacementRequest {
|
||||
id String @id @default(cuid())
|
||||
bookingId String
|
||||
booking Booking @relation(fields: [bookingId], references: [id])
|
||||
bookingItemId String
|
||||
bookingItem BookingItem @relation(fields: [bookingItemId], references: [id])
|
||||
|
||||
quantity Int
|
||||
notes String?
|
||||
|
||||
// Price snapshot at request time — a swap is its own sale (full cylinder
|
||||
// price). Snapshotted so future Product price changes don't rewrite history.
|
||||
sku String
|
||||
nameSv String
|
||||
nameEn String
|
||||
unitPriceOre Int
|
||||
vatBp Int
|
||||
lineTotalOre Int
|
||||
|
||||
// Pickup slot chosen by the customer (optional — admin can override)
|
||||
pickupSlotId String?
|
||||
pickupSlot PickupSlot? @relation(fields: [pickupSlotId], references: [id])
|
||||
|
||||
status String @default("REQUESTED")
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([bookingId])
|
||||
@@index([status])
|
||||
@@index([createdAt])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user