feat: add image support to the products
CI / build-and-test (push) Canceled after 0s

This commit is contained in:
2026-10-21 12:45:19 +02:00
parent ec77dd0e27
commit 5c604e0851
38 changed files with 1241 additions and 77 deletions
+23 -1
View File
@@ -59,7 +59,8 @@ model ClientUser {
email String @unique
passwordHash String
name String
role String @default("viewer")
// admin (the owner: users and terminals) | manager (runs the venue: products, stock, tabs, reminders)
role String @default("manager")
createdAt DateTime @default(now())
venue Venue @relation(fields: [venueId], references: [id])
@@ -222,6 +223,8 @@ model TabEvent {
items Json?
// stock_set: the counted stock, null to stop tracking
stockSetTo Int?
// product_created / product_updated: the product's fields as sent by the terminal
productData Json?
occurredAt DateTime
receivedAt DateTime @default(now())
@@ -252,6 +255,12 @@ model Product {
reportedAt DateTime
// Deleted on the dashboard: hidden on the terminals, kept because tabs and history refer to it
archivedAt DateTime?
imageId String?
// When each field was last changed ({ name: ISO date, ... }): a change from the dashboard or an (offline)
// terminal only wins over a later one per field, so edits of different fields never overwrite each other
fieldUpdatedAt Json?
image ProductImage? @relation(fields: [imageId], references: [id])
venue Venue @relation(fields: [venueId], references: [id])
@@ -330,3 +339,16 @@ model Settlement {
@@index([venueId, sequence])
@@index([venueId, settledAt])
}
// A product picture, resized and cropped on upload. The id is the SHA-256 of the stored bytes, so the picture at
// an address never changes and can be cached forever, and the same picture is stored once.
model ProductImage {
id String @id
contentType String
width Int
height Int
bytes Bytes
createdAt DateTime @default(now())
products Product[]
}