696 lines
23 KiB
Plaintext
696 lines
23 KiB
Plaintext
// This is your Prisma schema file
|
|
|
|
datasource db {
|
|
provider = "postgres"
|
|
url = env("DATABASE_URL")
|
|
}
|
|
|
|
generator client {
|
|
provider = "prisma-client-js"
|
|
}
|
|
|
|
generator json {
|
|
provider = "prisma-json-types-generator"
|
|
}
|
|
|
|
enum CommentStatus {
|
|
PENDING
|
|
HUMAN_PENDING
|
|
APPROVED
|
|
VERIFIED
|
|
REJECTED
|
|
}
|
|
|
|
enum OrderIdStatus {
|
|
PENDING
|
|
APPROVED
|
|
REJECTED
|
|
WITHDRAWN
|
|
}
|
|
|
|
model Comment {
|
|
id Int @id @default(autoincrement())
|
|
/// Computed via trigger. Do not update through prisma.
|
|
upvotes Int @default(0)
|
|
status CommentStatus @default(PENDING)
|
|
suspicious Boolean @default(false)
|
|
requiresAdminReview Boolean @default(false)
|
|
communityNote String?
|
|
verificationNote String?
|
|
internalNote String?
|
|
privateContext String?
|
|
orderId String? @db.VarChar(100)
|
|
orderIdStatus OrderIdStatus? @default(PENDING)
|
|
kycRequested Boolean @default(false)
|
|
fundsBlocked Boolean @default(false)
|
|
content String
|
|
rating Int? @db.SmallInt
|
|
ratingActive Boolean @default(false)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @default(now()) @updatedAt
|
|
author User @relation(fields: [authorId], references: [id], onDelete: Cascade)
|
|
authorId Int
|
|
service Service @relation(fields: [serviceId], references: [id], onDelete: Cascade)
|
|
serviceId Int
|
|
parentId Int?
|
|
parent Comment? @relation("CommentReplies", fields: [parentId], references: [id], onDelete: Cascade)
|
|
replies Comment[] @relation("CommentReplies")
|
|
karmaTransactions KarmaTransaction[]
|
|
votes CommentVote[]
|
|
|
|
notificationPreferenceswatchedComments NotificationPreferences[] @relation("watchedComments")
|
|
Notification Notification[]
|
|
|
|
@@unique([serviceId, orderId], name: "unique_orderId_per_service")
|
|
@@index([status])
|
|
@@index([createdAt])
|
|
@@index([serviceId])
|
|
@@index([authorId])
|
|
@@index([upvotes])
|
|
@@index([rating])
|
|
@@index([ratingActive])
|
|
}
|
|
|
|
enum VerificationStatus {
|
|
COMMUNITY_CONTRIBUTED
|
|
// COMMUNITY_VERIFIED
|
|
APPROVED
|
|
VERIFICATION_SUCCESS
|
|
VERIFICATION_FAILED
|
|
}
|
|
|
|
enum ServiceInfoBanner {
|
|
NONE
|
|
NO_LONGER_OPERATIONAL
|
|
}
|
|
|
|
enum ServiceVisibility {
|
|
PUBLIC
|
|
UNLISTED
|
|
HIDDEN
|
|
ARCHIVED
|
|
}
|
|
|
|
enum Currency {
|
|
MONERO
|
|
BITCOIN
|
|
LIGHTNING
|
|
FIAT
|
|
CASH
|
|
}
|
|
|
|
enum EventType {
|
|
WARNING
|
|
WARNING_SOLVED
|
|
ALERT
|
|
ALERT_SOLVED
|
|
INFO
|
|
NORMAL
|
|
UPDATE
|
|
}
|
|
|
|
enum ServiceUserRole {
|
|
OWNER
|
|
ADMIN
|
|
MODERATOR
|
|
SUPPORT
|
|
TEAM_MEMBER
|
|
}
|
|
|
|
enum AccountStatusChange {
|
|
ADMIN_TRUE
|
|
ADMIN_FALSE
|
|
VERIFIED_TRUE
|
|
VERIFIED_FALSE
|
|
MODERATOR_TRUE
|
|
MODERATOR_FALSE
|
|
SPAMMER_TRUE
|
|
SPAMMER_FALSE
|
|
}
|
|
|
|
enum NotificationType {
|
|
TEST
|
|
COMMENT_STATUS_CHANGE
|
|
REPLY_COMMENT_CREATED
|
|
COMMUNITY_NOTE_ADDED
|
|
/// Comment that is not a reply. May include a rating.
|
|
ROOT_COMMENT_CREATED
|
|
SUGGESTION_CREATED
|
|
SUGGESTION_MESSAGE
|
|
SUGGESTION_STATUS_CHANGE
|
|
// KARMA_UNLOCK // TODO: [KARMA_UNLOCK] Will be added later, when karma unloks are in the database, not in the code.
|
|
KARMA_CHANGE
|
|
/// Marked as spammer, promoted to admin, etc.
|
|
ACCOUNT_STATUS_CHANGE
|
|
EVENT_CREATED
|
|
SERVICE_VERIFICATION_STATUS_CHANGE
|
|
}
|
|
|
|
enum CommentStatusChange {
|
|
MARKED_AS_SPAM
|
|
UNMARKED_AS_SPAM
|
|
MARKED_FOR_ADMIN_REVIEW
|
|
UNMARKED_FOR_ADMIN_REVIEW
|
|
STATUS_CHANGED_TO_APPROVED
|
|
STATUS_CHANGED_TO_VERIFIED
|
|
STATUS_CHANGED_TO_REJECTED
|
|
STATUS_CHANGED_TO_PENDING
|
|
}
|
|
|
|
enum ServiceVerificationStatusChange {
|
|
STATUS_CHANGED_TO_COMMUNITY_CONTRIBUTED
|
|
STATUS_CHANGED_TO_APPROVED
|
|
STATUS_CHANGED_TO_VERIFICATION_SUCCESS
|
|
STATUS_CHANGED_TO_VERIFICATION_FAILED
|
|
}
|
|
|
|
enum ServiceSuggestionStatusChange {
|
|
STATUS_CHANGED_TO_PENDING
|
|
STATUS_CHANGED_TO_APPROVED
|
|
STATUS_CHANGED_TO_REJECTED
|
|
STATUS_CHANGED_TO_WITHDRAWN
|
|
}
|
|
|
|
enum KarmaTransactionAction {
|
|
COMMENT_APPROVED
|
|
COMMENT_VERIFIED
|
|
COMMENT_SPAM
|
|
COMMENT_SPAM_REVERTED
|
|
COMMENT_UPVOTE
|
|
COMMENT_DOWNVOTE
|
|
COMMENT_VOTE_REMOVED
|
|
SUGGESTION_APPROVED
|
|
MANUAL_ADJUSTMENT
|
|
}
|
|
|
|
enum AnnouncementType {
|
|
INFO
|
|
WARNING
|
|
ALERT
|
|
}
|
|
|
|
model Notification {
|
|
id Int @id @default(autoincrement())
|
|
userId Int
|
|
user User @relation("NotificationOwner", fields: [userId], references: [id], onDelete: Cascade)
|
|
type NotificationType
|
|
read Boolean @default(false)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @default(now()) @updatedAt
|
|
|
|
aboutComment Comment? @relation(fields: [aboutCommentId], references: [id])
|
|
aboutCommentId Int?
|
|
aboutEvent Event? @relation(fields: [aboutEventId], references: [id])
|
|
aboutEventId Int?
|
|
aboutService Service? @relation(fields: [aboutServiceId], references: [id])
|
|
aboutServiceId Int?
|
|
aboutServiceSuggestion ServiceSuggestion? @relation(fields: [aboutServiceSuggestionId], references: [id])
|
|
aboutServiceSuggestionId Int?
|
|
aboutServiceSuggestionMessage ServiceSuggestionMessage? @relation(fields: [aboutServiceSuggestionMessageId], references: [id])
|
|
aboutServiceSuggestionMessageId Int?
|
|
aboutAccountStatusChange AccountStatusChange?
|
|
aboutCommentStatusChange CommentStatusChange?
|
|
aboutServiceVerificationStatusChange ServiceVerificationStatusChange?
|
|
aboutSuggestionStatusChange ServiceSuggestionStatusChange?
|
|
aboutKarmaTransaction KarmaTransaction? @relation(fields: [aboutKarmaTransactionId], references: [id])
|
|
aboutKarmaTransactionId Int?
|
|
|
|
@@index([userId])
|
|
@@index([read])
|
|
@@index([createdAt])
|
|
@@index([userId, read, createdAt])
|
|
@@index([userId, type, aboutCommentId])
|
|
@@index([userId, type, aboutServiceSuggestionMessageId], map: "idx_notification_suggestion_message")
|
|
@@index([userId, type, aboutServiceSuggestionId], map: "idx_notification_suggestion_status")
|
|
@@index([userId, type, aboutAccountStatusChange], map: "idx_notification_account_status")
|
|
}
|
|
|
|
model NotificationPreferences {
|
|
id Int @id @default(autoincrement())
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @default(now()) @updatedAt
|
|
|
|
userId Int @unique
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
enableOnMyCommentStatusChange Boolean @default(true)
|
|
enableAutowatchMyComments Boolean @default(true)
|
|
enableNotifyPendingRepliesOnWatch Boolean @default(false)
|
|
karmaNotificationThreshold Int @default(10)
|
|
|
|
onEventCreatedForServices Service[] @relation("onEventCreatedForServices")
|
|
onRootCommentCreatedForServices Service[] @relation("onRootCommentCreatedForServices")
|
|
onVerificationChangeForServices Service[] @relation("onVerificationChangeForServices")
|
|
watchedComments Comment[] @relation("watchedComments")
|
|
|
|
onServiceVerificationChangeFilter NotificationPreferenceOnServiceVerificationChangeFilterFilter[]
|
|
}
|
|
|
|
model NotificationPreferenceOnServiceVerificationChangeFilterFilter {
|
|
id Int @id @default(autoincrement())
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @default(now()) @updatedAt
|
|
|
|
verificationStatus VerificationStepStatus
|
|
notificationPreferences NotificationPreferences @relation(fields: [notificationPreferencesId], references: [id], onDelete: Cascade)
|
|
notificationPreferencesId Int
|
|
|
|
categories Category[]
|
|
attributes Attribute[]
|
|
currencies Currency[]
|
|
/// 0-10
|
|
scores Int[]
|
|
|
|
@@unique([verificationStatus, notificationPreferencesId])
|
|
}
|
|
|
|
model Event {
|
|
id Int @id @default(autoincrement())
|
|
title String
|
|
content String
|
|
source String?
|
|
type EventType
|
|
visible Boolean @default(true)
|
|
startedAt DateTime
|
|
/// If null, the event is ongoing. If same as startedAt, the event is a one-time event. If startedAt is in the future, the event is upcoming.
|
|
endedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @default(now()) @updatedAt
|
|
service Service @relation(fields: [serviceId], references: [id], onDelete: Cascade)
|
|
serviceId Int
|
|
Notification Notification[]
|
|
|
|
@@index([visible])
|
|
@@index([startedAt])
|
|
@@index([createdAt])
|
|
@@index([endedAt])
|
|
@@index([type])
|
|
@@index([serviceId])
|
|
}
|
|
|
|
enum ServiceSuggestionStatus {
|
|
PENDING
|
|
APPROVED
|
|
REJECTED
|
|
WITHDRAWN
|
|
}
|
|
|
|
enum ServiceSuggestionType {
|
|
CREATE_SERVICE
|
|
EDIT_SERVICE
|
|
}
|
|
|
|
enum KycLevelClarification {
|
|
NONE
|
|
DEPENDS_ON_PARTNERS
|
|
}
|
|
|
|
model ServiceSuggestion {
|
|
id Int @id @default(autoincrement())
|
|
type ServiceSuggestionType
|
|
status ServiceSuggestionStatus @default(PENDING)
|
|
notes String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @default(now()) @updatedAt
|
|
userId Int
|
|
serviceId Int
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
service Service @relation(fields: [serviceId], references: [id], onDelete: Cascade)
|
|
messages ServiceSuggestionMessage[]
|
|
Notification Notification[]
|
|
KarmaTransaction KarmaTransaction[]
|
|
|
|
@@index([userId])
|
|
@@index([serviceId])
|
|
}
|
|
|
|
model ServiceSuggestionMessage {
|
|
id Int @id @default(autoincrement())
|
|
content String
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @default(now()) @updatedAt
|
|
userId Int
|
|
suggestionId Int
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
suggestion ServiceSuggestion @relation(fields: [suggestionId], references: [id], onDelete: Cascade)
|
|
notifications Notification[]
|
|
|
|
@@index([userId])
|
|
@@index([suggestionId])
|
|
@@index([createdAt])
|
|
}
|
|
|
|
model Service {
|
|
id Int @id @default(autoincrement())
|
|
name String
|
|
slug String @unique
|
|
previousSlugs String[] @default([])
|
|
description String
|
|
categories Category[] @relation("ServiceToCategory")
|
|
kycLevel Int @default(4)
|
|
kycLevelClarification KycLevelClarification @default(NONE)
|
|
overallScore Int @default(0)
|
|
privacyScore Int @default(0)
|
|
trustScore Int @default(0)
|
|
/// Computed via trigger. Do not update through prisma.
|
|
averageUserRating Float?
|
|
serviceVisibility ServiceVisibility @default(PUBLIC)
|
|
serviceInfoBanner ServiceInfoBanner @default(NONE)
|
|
serviceInfoBannerNotes String?
|
|
verificationStatus VerificationStatus @default(COMMUNITY_CONTRIBUTED)
|
|
verificationSummary String?
|
|
verificationRequests ServiceVerificationRequest[]
|
|
verificationProofMd String?
|
|
/// [UserSentiment]
|
|
userSentiment Json?
|
|
userSentimentAt DateTime?
|
|
referral String?
|
|
acceptedCurrencies Currency[] @default([])
|
|
serviceUrls String[]
|
|
tosUrls String[] @default([])
|
|
onionUrls String[] @default([])
|
|
i2pUrls String[] @default([])
|
|
imageUrl String?
|
|
/// [TosReview]
|
|
tosReview Json?
|
|
tosReviewAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @default(now()) @updatedAt
|
|
/// Computed via trigger when the visibility is PUBLIC or (ARCHIVED and listedAt was null). Do not update through prisma.
|
|
listedAt DateTime?
|
|
/// Computed via trigger when the verification status is APPROVED. Do not update through prisma.
|
|
approvedAt DateTime?
|
|
/// Computed via trigger when the verification status is VERIFICATION_SUCCESS. Do not update through prisma.
|
|
verifiedAt DateTime?
|
|
/// Computed via trigger when the verification status is VERIFICATION_FAILED. Do not update through prisma.
|
|
spamAt DateTime?
|
|
/// Computed via trigger. Do not update through prisma.
|
|
isRecentlyApproved Boolean @default(false)
|
|
comments Comment[]
|
|
events Event[]
|
|
contactMethods ServiceContactMethod[] @relation("ServiceToContactMethod")
|
|
attributes ServiceAttribute[]
|
|
verificationSteps VerificationStep[]
|
|
suggestions ServiceSuggestion[]
|
|
internalNotes InternalServiceNote[] @relation("ServiceRecievedNotes")
|
|
|
|
onEventCreatedForServices NotificationPreferences[] @relation("onEventCreatedForServices")
|
|
onRootCommentCreatedForServices NotificationPreferences[] @relation("onRootCommentCreatedForServices")
|
|
onVerificationChangeForServices NotificationPreferences[] @relation("onVerificationChangeForServices")
|
|
Notification Notification[]
|
|
affiliatedUsers ServiceUser[] @relation("ServiceUsers")
|
|
|
|
@@index([listedAt])
|
|
@@index([approvedAt])
|
|
@@index([verifiedAt])
|
|
@@index([spamAt])
|
|
@@index([overallScore])
|
|
@@index([privacyScore])
|
|
@@index([trustScore])
|
|
@@index([averageUserRating])
|
|
@@index([name])
|
|
@@index([verificationStatus])
|
|
@@index([kycLevel])
|
|
@@index([createdAt])
|
|
@@index([updatedAt])
|
|
@@index([slug])
|
|
@@index([previousSlugs])
|
|
@@index([serviceVisibility])
|
|
}
|
|
|
|
model ServiceContactMethod {
|
|
id Int @id @default(autoincrement())
|
|
/// Only include it if you want to override the formatted value.
|
|
label String?
|
|
/// Including the protocol (e.g. "mailto:", "tel:", "https://")
|
|
value String
|
|
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @default(now()) @updatedAt
|
|
|
|
services Service @relation("ServiceToContactMethod", fields: [serviceId], references: [id], onDelete: Cascade)
|
|
serviceId Int
|
|
}
|
|
|
|
enum AttributeCategory {
|
|
PRIVACY
|
|
TRUST
|
|
}
|
|
|
|
enum AttributeType {
|
|
GOOD
|
|
BAD
|
|
WARNING
|
|
INFO
|
|
}
|
|
|
|
model Attribute {
|
|
id Int @id @default(autoincrement())
|
|
slug String @unique
|
|
title String
|
|
/// Markdown
|
|
description String
|
|
privacyPoints Int @default(0)
|
|
trustPoints Int @default(0)
|
|
category AttributeCategory
|
|
type AttributeType
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @default(now()) @updatedAt
|
|
services ServiceAttribute[]
|
|
|
|
notificationPreferencesOnServiceVerificationChange NotificationPreferenceOnServiceVerificationChangeFilterFilter[]
|
|
}
|
|
|
|
model InternalUserNote {
|
|
id Int @id @default(autoincrement())
|
|
/// Markdown
|
|
content String
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @default(now()) @updatedAt
|
|
|
|
user User @relation("UserRecievedNotes", fields: [userId], references: [id], onDelete: Cascade)
|
|
userId Int
|
|
addedByUser User? @relation("UserAddedNotes", fields: [addedByUserId], references: [id], onDelete: SetNull)
|
|
addedByUserId Int?
|
|
|
|
@@index([userId])
|
|
@@index([addedByUserId])
|
|
@@index([createdAt])
|
|
}
|
|
|
|
model InternalServiceNote {
|
|
id Int @id @default(autoincrement())
|
|
/// Markdown
|
|
content String
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @default(now()) @updatedAt
|
|
|
|
service Service @relation("ServiceRecievedNotes", fields: [serviceId], references: [id], onDelete: Cascade)
|
|
serviceId Int
|
|
addedByUser User? @relation("UserAddedServiceNotes", fields: [addedByUserId], references: [id], onDelete: SetNull)
|
|
addedByUserId Int?
|
|
|
|
@@index([serviceId])
|
|
@@index([addedByUserId])
|
|
@@index([createdAt])
|
|
}
|
|
|
|
model User {
|
|
id Int @id @default(autoincrement())
|
|
name String @unique
|
|
displayName String?
|
|
link String?
|
|
picture String?
|
|
spammer Boolean @default(false)
|
|
verified Boolean @default(false)
|
|
admin Boolean @default(false)
|
|
moderator Boolean @default(false)
|
|
verifiedLink String?
|
|
secretTokenHash String @unique
|
|
feedId String @unique @default(cuid(2))
|
|
/// Computed via trigger. Do not update through prisma.
|
|
totalKarma Int @default(0)
|
|
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @default(now()) @updatedAt
|
|
lastLoginAt DateTime @default(now())
|
|
comments Comment[]
|
|
karmaTransactions KarmaTransaction[]
|
|
grantedKarmaTransactions KarmaTransaction[] @relation("KarmaGrantedBy")
|
|
commentVotes CommentVote[]
|
|
suggestions ServiceSuggestion[]
|
|
suggestionMessages ServiceSuggestionMessage[]
|
|
internalNotes InternalUserNote[] @relation("UserRecievedNotes")
|
|
addedInternalNotes InternalUserNote[] @relation("UserAddedNotes")
|
|
addedServiceNotes InternalServiceNote[] @relation("UserAddedServiceNotes")
|
|
verificationRequests ServiceVerificationRequest[]
|
|
notifications Notification[] @relation("NotificationOwner")
|
|
notificationPreferences NotificationPreferences?
|
|
serviceAffiliations ServiceUser[] @relation("UserServices")
|
|
pushSubscriptions PushSubscription[]
|
|
|
|
@@index([createdAt])
|
|
@@index([totalKarma])
|
|
}
|
|
|
|
model CommentVote {
|
|
id Int @id @default(autoincrement())
|
|
downvote Boolean @default(false) // false = upvote, true = downvote
|
|
comment Comment @relation(fields: [commentId], references: [id], onDelete: Cascade)
|
|
commentId Int
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
userId Int
|
|
createdAt DateTime @default(now())
|
|
|
|
@@unique([commentId, userId]) // Ensure one vote per user per comment
|
|
@@index([commentId])
|
|
@@index([userId])
|
|
}
|
|
|
|
model ServiceAttribute {
|
|
service Service @relation(fields: [serviceId], references: [id], onDelete: Cascade)
|
|
serviceId Int
|
|
attribute Attribute @relation(fields: [attributeId], references: [id], onDelete: Cascade)
|
|
attributeId Int
|
|
createdAt DateTime @default(now())
|
|
|
|
@@id([serviceId, attributeId])
|
|
}
|
|
|
|
model KarmaTransaction {
|
|
id Int @id @default(autoincrement())
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
userId Int
|
|
action KarmaTransactionAction
|
|
points Int @default(0)
|
|
comment Comment? @relation(fields: [commentId], references: [id], onDelete: Cascade)
|
|
commentId Int?
|
|
suggestion ServiceSuggestion? @relation(fields: [suggestionId], references: [id], onDelete: Cascade)
|
|
suggestionId Int?
|
|
description String
|
|
processed Boolean @default(false)
|
|
createdAt DateTime @default(now())
|
|
grantedBy User? @relation("KarmaGrantedBy", fields: [grantedByUserId], references: [id], onDelete: SetNull)
|
|
grantedByUserId Int?
|
|
Notification Notification[]
|
|
|
|
@@index([createdAt])
|
|
@@index([userId])
|
|
@@index([processed])
|
|
@@index([suggestionId])
|
|
@@index([commentId])
|
|
@@index([grantedByUserId])
|
|
}
|
|
|
|
enum VerificationStepStatus {
|
|
PENDING
|
|
IN_PROGRESS
|
|
PASSED
|
|
FAILED
|
|
WARNING
|
|
}
|
|
|
|
model VerificationStep {
|
|
id Int @id @default(autoincrement())
|
|
title String
|
|
description String
|
|
status VerificationStepStatus @default(PENDING)
|
|
evidenceMd String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @default(now()) @updatedAt
|
|
service Service @relation(fields: [serviceId], references: [id], onDelete: Cascade)
|
|
serviceId Int
|
|
|
|
@@index([serviceId])
|
|
@@index([status])
|
|
@@index([createdAt])
|
|
}
|
|
|
|
model Category {
|
|
id Int @id @default(autoincrement())
|
|
name String @unique
|
|
icon String
|
|
slug String @unique
|
|
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @default(now()) @updatedAt
|
|
services Service[] @relation("ServiceToCategory")
|
|
|
|
notificationPreferencesOnServiceVerificationChange NotificationPreferenceOnServiceVerificationChangeFilterFilter[]
|
|
|
|
@@index([name])
|
|
@@index([slug])
|
|
}
|
|
|
|
model ServiceVerificationRequest {
|
|
id Int @id @default(autoincrement())
|
|
service Service @relation(fields: [serviceId], references: [id], onDelete: Cascade)
|
|
serviceId Int
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
userId Int
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @default(now()) @updatedAt
|
|
|
|
@@unique([serviceId, userId])
|
|
@@index([serviceId])
|
|
@@index([userId])
|
|
@@index([createdAt])
|
|
}
|
|
|
|
model ServiceScoreRecalculationJob {
|
|
id Int @id @default(autoincrement())
|
|
serviceId Int @unique
|
|
createdAt DateTime @default(now())
|
|
processedAt DateTime? @updatedAt
|
|
|
|
@@index([processedAt])
|
|
@@index([createdAt])
|
|
}
|
|
|
|
model ServiceUser {
|
|
id Int @id @default(autoincrement())
|
|
userId Int
|
|
user User @relation("UserServices", fields: [userId], references: [id], onDelete: Cascade)
|
|
serviceId Int
|
|
service Service @relation("ServiceUsers", fields: [serviceId], references: [id], onDelete: Cascade)
|
|
role ServiceUserRole
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@unique([userId, serviceId])
|
|
@@index([userId])
|
|
@@index([serviceId])
|
|
@@index([role])
|
|
}
|
|
|
|
model Announcement {
|
|
id Int @id @default(autoincrement())
|
|
content String
|
|
type AnnouncementType
|
|
link String?
|
|
linkText String?
|
|
startDate DateTime
|
|
endDate DateTime?
|
|
isActive Boolean @default(true)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @default(now()) @updatedAt
|
|
|
|
@@index([isActive, startDate, endDate])
|
|
}
|
|
|
|
model PushSubscription {
|
|
id Int @id @default(autoincrement())
|
|
userId Int
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
endpoint String @unique
|
|
/// Public key for encryption
|
|
p256dh String
|
|
/// Authentication secret
|
|
auth String
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index([userId])
|
|
@@index([endpoint])
|
|
}
|