generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } model Snl { id Int @id @default(autoincrement()) live Boolean @default(false) } model User { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @default(now()) @updatedAt @map("updated_at") name String? @unique(map: "users.name_unique") @db.Citext email String? @unique(map: "users.email_unique") emailVerified DateTime? @map("email_verified") image String? msats BigInt @default(0) freeComments Int @default(5) freePosts Int @default(2) checkedNotesAt DateTime? pubkey String? @unique(map: "users.pubkey_unique") tipDefault Int @default(100) bioId Int? inviteId String? tipPopover Boolean @default(false) upvotePopover Boolean @default(false) trust Float @default(0) lastSeenAt DateTime? stackedMsats BigInt @default(0) noteAllDescendants Boolean @default(true) noteDeposits Boolean @default(true) noteEarning Boolean @default(true) noteInvites Boolean @default(true) noteItemSats Boolean @default(true) noteMentions Boolean @default(true) noteForwardedSats Boolean @default(true) lastCheckedJobs DateTime? noteJobIndicator Boolean @default(true) photoId Int? upvoteTrust Float @default(0) hideInvoiceDesc Boolean @default(false) wildWestMode Boolean @default(false) greeterMode Boolean @default(false) fiatCurrency String @default("USD") hideFromTopUsers Boolean @default(false) turboTipping Boolean @default(false) clickToLoadImg Boolean @default(false) hideWalletBalance Boolean @default(false) referrerId Int? nostrPubkey String? nostrAuthPubkey String? @unique(map: "users.nostrAuthPubkey_unique") slashtagId String? @unique(map: "users.slashtagId_unique") noteCowboyHat Boolean @default(true) streak Int? subs String[] hideCowboyHat Boolean @default(false) Bookmarks Bookmark[] Donation Donation[] Earn Earn[] invites Invite[] @relation("Invites") invoices Invoice[] items Item[] @relation("UserItems") actions ItemAct[] mentions Mention[] messages Message[] PollVote PollVote[] PushSubscriptions PushSubscription[] ReferralAct ReferralAct[] Streak Streak[] Subscriptions Subscription[] ThreadSubscriptions ThreadSubscription[] Upload Upload[] @relation("Uploads") nostrRelays UserNostrRelay[] withdrawls Withdrawl[] bio Item? @relation(fields: [bioId], references: [id]) invite Invite? @relation(fields: [inviteId], references: [id]) photo Upload? @relation(fields: [photoId], references: [id]) referrer User? @relation("referrals", fields: [referrerId], references: [id]) referrees User[] @relation("referrals") Account Account[] Session Session[] itemForwards ItemForward[] hideBookmarks Boolean @default(false) followers UserSubscription[] @relation("follower") followees UserSubscription[] @relation("followee") hideWelcomeBanner Boolean @default(false) diagnostics Boolean @default(false) hideIsContributor Boolean @default(false) muters Mute[] @relation("muter") muteds Mute[] @relation("muted") @@index([createdAt], map: "users.created_at_index") @@index([inviteId], map: "users.inviteId_index") @@map("users") } model Mute { muterId Int mutedId Int createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @default(now()) @updatedAt @map("updated_at") muter User @relation("muter", fields: [muterId], references: [id], onDelete: Cascade) muted User @relation("muted", fields: [mutedId], references: [id], onDelete: Cascade) @@id([muterId, mutedId]) @@index([mutedId, muterId]) } model Streak { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @default(now()) @updatedAt @map("updated_at") startedAt DateTime @db.Date endedAt DateTime? @db.Date userId Int user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@unique([startedAt, userId], map: "Streak.startedAt_userId_unique") @@index([userId], map: "Streak.userId_index") } model NostrRelay { addr String @id createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @default(now()) @updatedAt @map("updated_at") users UserNostrRelay[] } model UserNostrRelay { userId Int nostrRelayAddr String createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @default(now()) @updatedAt @map("updated_at") NostrRelay NostrRelay @relation(fields: [nostrRelayAddr], references: [addr], onDelete: Cascade) User User @relation(fields: [userId], references: [id], onDelete: Cascade) @@id([userId, nostrRelayAddr]) } model Donation { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @default(now()) @updatedAt @map("updated_at") sats Int userId Int user User @relation(fields: [userId], references: [id], onDelete: Cascade) } model Upload { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @default(now()) @updatedAt @map("updated_at") type String size Int width Int? height Int? itemId Int? @unique(map: "Upload.itemId_unique") userId Int item Item? @relation(fields: [itemId], references: [id]) user User @relation("Uploads", fields: [userId], references: [id], onDelete: Cascade) User User[] @@index([createdAt], map: "Upload.created_at_index") @@index([itemId], map: "Upload.itemId_index") @@index([userId], map: "Upload.userId_index") } model Earn { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @default(now()) @updatedAt @map("updated_at") msats BigInt userId Int rank Int? type EarnType? typeId Int? user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@index([createdAt], map: "Earn.created_at_index") @@index([createdAt, userId], map: "Earn.created_at_userId_index") @@index([userId], map: "Earn.userId_index") } model LnAuth { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @default(now()) @updatedAt @map("updated_at") k1 String @unique(map: "LnAuth.k1_unique") pubkey String? } model LnWith { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @default(now()) @updatedAt @map("updated_at") k1 String @unique(map: "LnWith.k1_unique") userId Int withdrawalId Int? } model Invite { id String @id @default(cuid()) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @default(now()) @updatedAt @map("updated_at") userId Int gift Int? limit Int? revoked Boolean @default(false) user User @relation("Invites", fields: [userId], references: [id], onDelete: Cascade) invitees User[] @@index([createdAt], map: "Invite.created_at_index") @@index([userId], map: "Invite.userId_index") } model Message { id Int @id @default(autoincrement()) text String userId Int user User @relation(fields: [userId], references: [id], onDelete: Cascade) } /// This model contains an expression index which requires additional setup for migrations. Visit https://pris.ly/d/expression-indexes for more info. model Item { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @default(now()) @updatedAt @map("updated_at") title String? text String? url String? userId Int parentId Int? path Unsupported("ltree")? pinId Int? latitude Float? location String? longitude Float? maxBid Int? maxSalary Int? minSalary Int? remote Boolean? subName String? @db.Citext statusUpdatedAt DateTime? status Status @default(ACTIVE) company String? weightedVotes Float @default(0) boost Int @default(0) uploadId Int? pollCost Int? paidImgLink Boolean @default(false) commentMsats BigInt @default(0) lastCommentAt DateTime? ncomments Int @default(0) msats BigInt @default(0) weightedDownVotes Float @default(0) bio Boolean @default(false) freebie Boolean @default(false) deletedAt DateTime? otsFile Bytes? otsHash String? imgproxyUrls Json? bounty Int? rootId Int? bountyPaidTo Int[] upvotes Int @default(0) weightedComments Float @default(0) Bookmark Bookmark[] parent Item? @relation("ParentChildren", fields: [parentId], references: [id]) children Item[] @relation("ParentChildren") pin Pin? @relation(fields: [pinId], references: [id]) root Item? @relation("RootDescendant", fields: [rootId], references: [id]) descendants Item[] @relation("RootDescendant") sub Sub? @relation(fields: [subName], references: [name]) user User @relation("UserItems", fields: [userId], references: [id], onDelete: Cascade) actions ItemAct[] mentions Mention[] PollOption PollOption[] PollVote PollVote[] ThreadSubscription ThreadSubscription[] upload Upload? User User[] itemForwards ItemForward[] @@index([bio], map: "Item.bio_index") @@index([createdAt], map: "Item.created_at_index") @@index([freebie], map: "Item.freebie_index") @@index([maxBid], map: "Item.maxBid_index") @@index([parentId], map: "Item.parentId_index") @@index([path], map: "Item.path_index", type: Gist) @@index([path], map: "Item.path_index0", type: Gist) @@index([pinId], map: "Item.pinId_index") @@index([rootId], map: "Item.rootId_index") @@index([statusUpdatedAt], map: "Item.statusUpdatedAt_index") @@index([status], map: "Item.status_index") @@index([subName], map: "Item.subName_index") @@index([userId], map: "Item.userId_index") @@index([weightedDownVotes], map: "Item.weightedDownVotes_index") @@index([weightedVotes], map: "Item.weightedVotes_index") } // TODO: make all Item's forward 100% of sats to the OP by default // so that forwards aren't a special case everywhere model ItemForward { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @default(now()) @updatedAt @map("updated_at") itemId Int // The item from which sats are forwarded userId Int // The recipient of the forwarded sats pct Int // The percentage of sats from the item to forward to this user item Item @relation(fields: [itemId], references: [id], onDelete: Cascade) user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@index([itemId], map: "ItemForward.itemId_index") @@index([userId], map: "ItemForward.userId_index") @@index([createdAt], map: "ItemForward.createdAt_index") } model PollOption { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @default(now()) @updatedAt @map("updated_at") itemId Int option String item Item @relation(fields: [itemId], references: [id], onDelete: Cascade) PollVote PollVote[] @@index([itemId], map: "PollOption.itemId_index") } model PollVote { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @default(now()) @updatedAt @map("updated_at") userId Int itemId Int pollOptionId Int item Item @relation(fields: [itemId], references: [id], onDelete: Cascade) pollOption PollOption @relation(fields: [pollOptionId], references: [id], onDelete: Cascade) user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@unique([itemId, userId], map: "PollVote.itemId_userId_unique") @@index([pollOptionId], map: "PollVote.pollOptionId_index") @@index([userId], map: "PollVote.userId_index") } model Sub { name String @id @db.Citext createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @default(now()) @updatedAt @map("updated_at") postTypes PostType[] rankingType RankingType baseCost Int @default(1) desc String? Item Item[] Subscription Subscription[] } model Subscription { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @default(now()) @updatedAt @map("updated_at") subName String @db.Citext userId Int sub Sub @relation(fields: [subName], references: [name], onDelete: Cascade) user User @relation(fields: [userId], references: [id], onDelete: Cascade) } model Pin { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @default(now()) @updatedAt @map("updated_at") cron String? timezone String? position Int Item Item[] } model ReferralAct { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @default(now()) @updatedAt @map("updated_at") referrerId Int itemActId Int msats BigInt itemAct ItemAct @relation(fields: [itemActId], references: [id], onDelete: Cascade) referrer User @relation(fields: [referrerId], references: [id], onDelete: Cascade) @@index([referrerId]) @@index([itemActId]) } model ItemAct { id Int @id(map: "Vote_pkey") @default(autoincrement()) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @default(now()) @updatedAt @map("updated_at") msats BigInt act ItemActType itemId Int userId Int item Item @relation(fields: [itemId], references: [id], onDelete: Cascade) user User @relation(fields: [userId], references: [id], onDelete: Cascade) ReferralAct ReferralAct[] @@index([act], map: "ItemAct.act_index") @@index([createdAt], map: "ItemAct.created_at_index") @@index([createdAt, itemId, act], map: "ItemAct.created_at_itemId_act_index") @@index([itemId, createdAt, act], map: "ItemAct.itemId_created_at_act_index") @@index([itemId], map: "ItemAct.itemId_index") @@index([itemId, userId, act], map: "ItemAct.itemId_userId_act_index") @@index([userId, createdAt, act], map: "ItemAct.userId_created_at_act_index") @@index([userId], map: "ItemAct.userId_index") @@index([itemId], map: "Vote.itemId_index") @@index([userId], map: "Vote.userId_index") } model Mention { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @default(now()) @updatedAt @map("updated_at") itemId Int userId Int item Item @relation(fields: [itemId], references: [id], onDelete: Cascade) user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@unique([itemId, userId], map: "Mention.itemId_userId_unique") @@index([createdAt], map: "Mention.created_at_index") @@index([itemId], map: "Mention.itemId_index") @@index([userId], map: "Mention.userId_index") } model Invoice { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @default(now()) @updatedAt @map("updated_at") userId Int hash String @unique(map: "Invoice.hash_unique") preimage String? @unique(map: "Invoice.preimage_unique") isHeld Boolean? bolt11 String expiresAt DateTime confirmedAt DateTime? cancelled Boolean @default(false) msatsRequested BigInt msatsReceived BigInt? desc String? comment String? user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@index([createdAt], map: "Invoice.created_at_index") @@index([userId], map: "Invoice.userId_index") } model Withdrawl { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @default(now()) @updatedAt @map("updated_at") userId Int hash String bolt11 String msatsPaying BigInt msatsPaid BigInt? msatsFeePaying BigInt msatsFeePaid BigInt? status WithdrawlStatus? user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@index([createdAt], map: "Withdrawl.created_at_index") @@index([userId], map: "Withdrawl.userId_index") } model Account { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @default(now()) @updatedAt @map("updated_at") userId Int @map("user_id") type String @map("provider_type") provider String @map("provider_id") providerAccountId String @map("provider_account_id") refresh_token String? @map("refresh_token") access_token String? @map("access_token") expires_at String? @map("access_token_expires") token_type String? scope String? id_token String? session_state String? // twitter oauth 1.0 needs these https://authjs.dev/reference/core/providers_twitter#notes oauth_token String? oauth_token_secret String? user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@unique([provider, providerAccountId]) @@index([userId], map: "accounts.user_id_index") @@map("accounts") } model Session { id Int @id @default(autoincrement()) sessionToken String @unique(map: "sessions.session_token_unique") @map("session_token") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @default(now()) @updatedAt @map("updated_at") userId Int @map("user_id") expires DateTime user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@map("sessions") } model VerificationToken { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @default(now()) @updatedAt @map("updated_at") identifier String token String @unique(map: "verification_requests.token_unique") expires DateTime @@unique([identifier, token]) @@map("verification_requests") } model Bookmark { userId Int itemId Int createdAt DateTime @default(now()) @map("created_at") item Item @relation(fields: [itemId], references: [id], onDelete: Cascade) user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@id([userId, itemId]) @@index([createdAt], map: "Bookmark.created_at_index") } // TODO: make thread subscriptions for OP by default so they can // unsubscribe from their own threads and its not a special case model ThreadSubscription { userId Int itemId Int createdAt DateTime @default(now()) @map("created_at") item Item @relation(fields: [itemId], references: [id], onDelete: Cascade) user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@id([userId, itemId]) @@index([createdAt], map: "ThreadSubscription.created_at_index") } model UserSubscription { followerId Int followeeId Int createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @default(now()) @updatedAt @map("updated_at") postsSubscribedAt DateTime? commentsSubscribedAt DateTime? follower User @relation("follower", fields: [followerId], references: [id], onDelete: Cascade) followee User @relation("followee", fields: [followeeId], references: [id], onDelete: Cascade) @@id([followerId, followeeId]) @@index([createdAt], map: "UserSubscription.created_at_index") @@index([followerId], map: "UserSubscription.follower_index") @@index([followeeId], map: "UserSubscription.followee_index") } model PushSubscription { id Int @id @default(autoincrement()) userId Int endpoint String p256dh String auth String createdAt DateTime @default(now()) @map("created_at") user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@index([userId], map: "PushSubscription.userId_index") } model Log { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) @map("created_at") level LogLevel name String message String env Json? context Json? @@index([createdAt, name], map: "Log.name_index") } enum EarnType { POST COMMENT TIP_COMMENT TIP_POST } enum Status { ACTIVE STOPPED NOSATS } enum PostType { LINK DISCUSSION JOB POLL BOUNTY } enum RankingType { WOT RECENT AUCTION } enum ItemActType { VOTE BOOST TIP STREAM POLL DONT_LIKE_THIS FEE } enum WithdrawlStatus { INSUFFICIENT_BALANCE INVALID_PAYMENT PATHFINDING_TIMEOUT ROUTE_NOT_FOUND CONFIRMED UNKNOWN_FAILURE } enum LogLevel { DEBUG INFO WARN ERROR }