Files
kapteins-daagbok/server/prisma/schema.prisma
T
elpatron d90f292a21 fix(appearance): Theme-Einstellungen serverseitig speichern und beim Login wiederherstellen
Nach PWA-Cache-Löschung gingen Theme und Farbschema verloren, weil sie nur in localStorage lagen. Die Präferenzen werden jetzt synchronisiert und nach dem Login erneut angewendet.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-31 14:03:17 +02:00

203 lines
5.7 KiB
Plaintext

datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model User {
id String @id @default(uuid())
username String @unique
createdAt DateTime @default(now())
encryptedMasterKeyPrf String? // Encrypted using PRF-derived key
encryptedMasterKeyPrfIv String?
encryptedMasterKeyPrfTag String?
encryptedMasterKeyRec String // Encrypted using 12-word recovery phrase
encryptedMasterKeyRecIv String
encryptedMasterKeyRecTag String
credentials Credential[]
logbooks Logbook[]
collaborations Collaboration[]
pushSubscriptions PushSubscription[]
notificationPrefs UserNotificationPrefs?
appearancePrefs UserAppearancePrefs?
}
model PushSubscription {
id String @id @default(uuid())
userId String
endpoint String @unique
p256dh String
auth String
userAgent String?
locale String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([userId])
}
model UserNotificationPrefs {
userId String @id
collaboratorChangesEnabled Boolean @default(false)
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}
model UserAppearancePrefs {
userId String @id
theme String @default("auto")
colorScheme String @default("auto")
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}
model Credential {
id String @id @default(uuid())
userId String
credentialId String @unique
label String?
publicKey Bytes
counter BigInt
transports String[] // WebAuthn transports list
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([userId])
}
model Logbook {
id String @id @default(uuid())
userId String
encryptedTitle String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
// E2E Encrypted key for the owner (encrypted with owner's master key)
encryptedKey String?
iv String?
tag String?
yachts YachtPayload[]
crews CrewPayload[]
deviations DeviationPayload[]
entries EntryPayload[]
photos PhotoPayload[]
gpsTracks GpsTrackPayload[]
collaborators Collaboration[]
invitations Invitation[]
@@index([userId])
}
model Collaboration {
id String @id @default(uuid())
logbookId String
userId String
role String // "READ" | "WRITE"
// The Logbook Key encrypted with this collaborator's master key
encryptedLogbookKey String
iv String
tag String
createdAt DateTime @default(now())
logbook Logbook @relation(fields: [logbookId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([logbookId, userId])
}
model Invitation {
token String @id @default(uuid())
logbookId String
role String // "READ" | "WRITE"
createdAt DateTime @default(now())
expiresAt DateTime
logbook Logbook @relation(fields: [logbookId], references: [id], onDelete: Cascade)
}
model YachtPayload {
id String @id @default(uuid())
logbookId String @unique
encryptedData String
iv String
tag String
updatedAt DateTime @updatedAt
logbook Logbook @relation(fields: [logbookId], references: [id], onDelete: Cascade)
}
model CrewPayload {
id String @id @default(uuid())
logbookId String
payloadId String
encryptedData String
iv String
tag String
updatedAt DateTime @updatedAt
logbook Logbook @relation(fields: [logbookId], references: [id], onDelete: Cascade)
@@unique([logbookId, payloadId])
}
model DeviationPayload {
id String @id @default(uuid())
logbookId String @unique
encryptedData String
iv String
tag String
updatedAt DateTime @updatedAt
logbook Logbook @relation(fields: [logbookId], references: [id], onDelete: Cascade)
}
model EntryPayload {
id String @id @default(uuid())
logbookId String
payloadId String
encryptedData String
iv String
tag String
updatedAt DateTime @updatedAt
logbook Logbook @relation(fields: [logbookId], references: [id], onDelete: Cascade)
@@unique([logbookId, payloadId])
@@index([logbookId])
}
model PhotoPayload {
id String @id @default(uuid())
logbookId String
payloadId String
entryId String
encryptedData String
iv String
tag String
updatedAt DateTime @updatedAt
logbook Logbook @relation(fields: [logbookId], references: [id], onDelete: Cascade)
@@unique([logbookId, payloadId])
@@index([logbookId])
@@index([entryId])
}
model GpsTrackPayload {
id String @id @default(uuid())
logbookId String
entryId String @unique
encryptedData String
iv String
tag String
updatedAt DateTime @updatedAt
logbook Logbook @relation(fields: [logbookId], references: [id], onDelete: Cascade)
@@index([logbookId])
}