generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } model Node { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt title String cid String @default("") state NodeState @default(NEW) isFeatured Boolean @default(false) manifestUrl String restBody Json @default("{}") replicationFactor Int ownerId Int uuid String? @unique @default(uuid()) manifestDocumentId String @default("") privateShare PrivateShare? owner User @relation(fields: [ownerId], references: [id]) authorInvites AuthorInvite[] transactions ChainTransaction[] interactionLogs InteractionLog[] authors NodeAuthor[] versions NodeVersion[] votes NodeVote[] DataReference DataReference[] PublicDataReference PublicDataReference[] CidPruneList CidPruneList[] NodeCover NodeCover[] isDeleted Boolean @default(false) deletedAt DateTime? UploadJobs UploadJobs[] DraftNodeTree DraftNodeTree[] @@index([ownerId]) @@index([uuid]) } model NodeVersion { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt manifestUrl String cid String @default("") transactionId String? nodeId Int? node Node? @relation(fields: [nodeId], references: [id]) PublicDataReference PublicDataReference[] DataReference DataReference[] } model InteractionLog { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt ip String? userAgent String? extra String? action ActionType? userId Int? rep Int? nodeId Int? waitlistId Int? node Node? @relation(fields: [nodeId], references: [id]) user User? @relation(fields: [userId], references: [id]) waitlist Waitlist? @relation(fields: [waitlistId], references: [id]) } model Session { id String @id sid String @unique data String expiresAt DateTime } model AuthToken { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt accessToken String? refreshToken String? expiresIn Int? tokenId String? source AuthTokenSource? userId Int user User @relation(fields: [userId], references: [id]) } model Waitlist { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt email String @unique userId Int? user User? @relation(fields: [userId], references: [id]) interactionLogs InteractionLog[] } model Wallet { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt address String network String? chainId String? msgSignature String? msgPlain String? userId Int? nickname String? giftTransaction String? usedFaucet Boolean? @default(false) user User? @relation(fields: [userId], references: [id]) @@index([address]) @@index([userId]) } model User { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt email String @unique phoneNumber String? @unique name String? website String? googleScholarUrl String? researchInterests String? gitcoinPassport String? @unique walletAddress String? @unique isPatron Boolean @default(false) isWarden Boolean @default(false) isKeeper Boolean @default(false) pseudonym String? @unique orcid String? @unique // rorPid String[] @default([]) // organization String[] @default([]) isAdmin Boolean @default(false) isVerified Boolean @default(false) verificationCode String @default("") siweNonce String @default("") authTokens AuthToken[] authorInvitesReceived AuthorInvite[] @relation("ReceivedAuthorInvites") authorInvitesSent AuthorInvite[] @relation("SentAuthorInvites") receivedTransactions ChainTransaction[] @relation("ReceivedTransactions") sentTransactions ChainTransaction[] @relation("SentTransactions") interactionLogs InteractionLog[] invitesReceived Invite[] @relation("ReceivedInvites") invitesSent Invite[] @relation("SentInvites") ownedNodes Node[] authoredNodes NodeAuthor[] nodeVotes NodeVote[] accessGrants OauthAccessGrant[] accessTokens OauthAccessToken[] identities UserIdentity[] Waitlist Waitlist[] wallets Wallet[] canRunCode Boolean? @default(false) DataReference DataReference[] CidPruneList CidPruneList[] PublicDataReference PublicDataReference[] FriendReferral FriendReferral[] currentDriveStorageLimitGb Int @default(100) maxDriveStorageLimitGb Int @default(500) userOrganizations UserOrganizations[] UploadJobs UploadJobs[] // DraftNodeTree DraftNodeTree[] NodeFeedItemEndorsement NodeFeedItemEndorsement[] DesciCommunity DesciCommunity? @relation(fields: [desciCommunityId], references: [id]) desciCommunityId Int? @@index([orcid]) @@index([walletAddress]) @@index([pseudonym]) } model Invite { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt email String? phoneNumber String? senderId Int receiverId Int? inviteCode String? @default("desci") expired Boolean @default(false) expiredAt DateTime @default(dbgenerated("'2001-01-01 00:00:00'::timestamp without time zone")) receiver User? @relation("ReceivedInvites", fields: [receiverId], references: [id]) sender User @relation("SentInvites", fields: [senderId], references: [id]) } model AuthorInvite { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt email String @unique phoneNumber String @unique senderId Int receiverId Int nodeId Int node Node @relation(fields: [nodeId], references: [id]) receiver User @relation("ReceivedAuthorInvites", fields: [receiverId], references: [id]) sender User @relation("SentAuthorInvites", fields: [senderId], references: [id]) } model NodeAuthor { createdAt DateTime @default(now()) updatedAt DateTime @updatedAt shares Int userId Int nodeId Int node Node @relation(fields: [nodeId], references: [id]) user User @relation(fields: [userId], references: [id]) @@id([userId, nodeId]) } model NodeVote { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt voteWeight Int userId Int nodeId Int node Node @relation(fields: [nodeId], references: [id]) user User @relation(fields: [userId], references: [id]) transaction ChainTransaction? } model ChainTransaction { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt hash String type ChainTransactionType userId Int? targetUserId Int? nodeId Int? nodeVoteId Int? @unique node Node? @relation(fields: [nodeId], references: [id]) nodeVote NodeVote? @relation(fields: [nodeVoteId], references: [id]) targetUser User? @relation("ReceivedTransactions", fields: [targetUserId], references: [id]) user User? @relation("SentTransactions", fields: [userId], references: [id]) } model MagicLink { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt expiresAt DateTime @default(dbgenerated("(now() + '01:00:00'::interval)")) failedAttempts Int @default(0) token String email String } model OauthAccessToken { id String @id userId Int applicationId String token String @unique refreshToken String? @unique tokenExpiresAt DateTime? refreshTokenExpiresAt DateTime? scopes Json @default("[]") createdAt DateTime @default(now()) updatedAt DateTime @default(now()) @updatedAt application OauthApplication @relation(fields: [applicationId], references: [id]) user User @relation(fields: [userId], references: [id]) @@index([applicationId]) @@index([userId]) } model OauthAccessGrant { id String @id userId Int applicationId String token String @unique expiresAt DateTime redirectUri String codeChallengeMethod String? codeChallenge String? scopes Json @default("[]") createdAt DateTime @default(now()) updatedAt DateTime @default(now()) @updatedAt application OauthApplication @relation(fields: [applicationId], references: [id]) user User @relation(fields: [userId], references: [id]) @@index([applicationId]) @@index([userId]) } model OauthApplication { id String @id name String clientId String @unique clientSecret String redirectUris Json @default("[]") scopes Json @default("[]") createdAt DateTime @default(now()) updatedAt DateTime @default(now()) @updatedAt grants Json @default("[]") accessGrants OauthAccessGrant[] accessTokens OauthAccessToken[] } model UserIdentity { id String @id userId Int provider String uid String name String? email String? createdAt DateTime @default(now()) updatedAt DateTime @default(now()) @updatedAt user User @relation(fields: [userId], references: [id]) @@unique([provider, uid]) @@index([userId]) } model DataReference { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt name String? description String? cid String root Boolean rootCid String? path String? directory Boolean size Int type DataType external Boolean? nodeId Int userId Int versionId Int? node Node @relation(fields: [nodeId], references: [id]) user User @relation(fields: [userId], references: [id]) nodeVersion NodeVersion? @relation(fields: [versionId], references: [id]) } model CidPruneList { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt description String cid String size Int type DataType duration Int @default(30) deleted Boolean @default(false) directory Boolean nodeId Int userId Int node Node @relation(fields: [nodeId], references: [id]) user User @relation(fields: [userId], references: [id]) } model PublicDataReference { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt name String? description String? cid String root Boolean rootCid String? path String? directory Boolean size Int type DataType nodeId Int userId Int? versionId Int? external Boolean? mirrors PublicDataReferenceOnIpfsMirror[] node Node @relation(fields: [nodeId], references: [id]) user User? @relation(fields: [userId], references: [id]) nodeVersion NodeVersion? @relation(fields: [versionId], references: [id]) @@unique([path, versionId]) } model IpfsMirror { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt name String @unique description String? website String PublicDataReference PublicDataReferenceOnIpfsMirror[] } model PublicDataReferenceOnIpfsMirror { dataReferenceId Int PublicDataReference PublicDataReference @relation(fields: [dataReferenceId], references: [id]) mirrorId Int mirror IpfsMirror @relation(fields: [mirrorId], references: [id]) status PublishState @default(WAITING) retryCount Int @default(0) providerCount Int @default(0) @@id([dataReferenceId, mirrorId]) } model PrivateShare { id Int @id @default(autoincrement()) shareId String @unique nodeUUID String @unique node Node @relation(fields: [nodeUUID], references: [uuid]) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([shareId]) } model NodeCover { id Int @id @default(autoincrement()) url String nodeUuid String cid String? version Int? @default(0) name String? node Node @relation(fields: [nodeUuid], references: [uuid]) @@unique([nodeUuid, version]) } model FriendReferral { id Int @id @default(autoincrement()) uuid String @unique @default(uuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt senderUserId Int senderUser User? @relation(fields: [senderUserId], references: [id]) receiverEmail String status FriendReferralStatus awardedStorage Boolean @default(false) amountAwardedStorageGb Int @default(0) } model ResearchFields { id Int @id @default(autoincrement()) name String @unique } model Organization { id String @unique name String userOrganizations UserOrganizations[] @@id([id]) } model UserOrganizations { organizationId String organization Organization @relation(fields: [organizationId], references: [id]) userId Int user User @relation(fields: [userId], references: [id]) @@id([userId, organizationId]) } model OrcidProfile { id Int @id @default(autoincrement()) orcidId String @unique updatedAt DateTime @updatedAt expiresIn DateTime profile Json @@index([orcidId]) } model UploadJobs { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt uploadType UploadType uploadPayload Json contextPath String storageReference String? // If using S3, this would be the storage key used totalSize Int? totalFiles Int? totalDirs Int? proccessingStartTime DateTime? processingEndTime DateTime? processingState ProcessingState? nodeId Int userId Int node Node @relation(fields: [nodeId], references: [id]) user User @relation(fields: [userId], references: [id]) } model DocumentStore { key String @id value Bytes } model DraftNodeTree { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt path String cid String directory Boolean size Int external Boolean nodeId Int // userId Int node Node @relation(fields: [nodeId], references: [id]) // user User @relation(fields: [userId], references: [id]) @@unique([nodeId, path]) } // create a model for Node UUIDs, titles, dates, authors, and abstracts model NodeFeedItem { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt nodeUuid String nodeUuidHex String nodeDpid10 String @unique manifestCid String title String date DateTime authors String abstract String nodeFeedItemEndorsement NodeFeedItemEndorsement[] } model NodeFeedItemEndorsement { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt nodeDpid10 String type String userId Int nodeFeedItemId Int desciCommunityId Int user User @relation(fields: [userId], references: [id]) nodeFeedItem NodeFeedItem @relation(fields: [nodeFeedItemId], references: [id]) desciCommunity DesciCommunity @relation(fields: [desciCommunityId], references: [id]) } // an organization that endorses work and has members model DesciCommunity { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt name String @unique description String members User[] endorsements NodeFeedItemEndorsement[] } enum UploadType { REGULAR EXTERNAL_URL EXTERNAL_CID } enum ProcessingState { STARTED FAILED COMPLETED } enum FriendReferralStatus { PENDING ACCEPTED } // datasetId Int? // dataset Dataset? @relation(fields: [datasetId], references: [id]) enum ActionType { ORCID_RETRIEVE USER_LOGIN USER_WALLET_ASSOCIATE USER_WALLET_CONNECT USER_NODE_VOTE WAITLIST_ADD RETRIEVE_URL RETRIEVE_URL_FAIL RETREIVE_URL_SUCCESS USER_TERMS_CONSENT PUBLISH_NODE_CID_SUCCESS PUBLISH_NODE_CID_FAIL PUBLISH_NODE_RESEARCH_OBJECT_SUCCESS PUBLISH_NODE_RESEARCH_OBJECT_FAIL USER_ACTION NEW_REFERRAL ACCEPTED_REFERRAL } enum ChainTransactionType { NODE_MINT NODE_UPDATE NODE_VOTE } enum NodeState { NEW PENDING_DAO_APPROVAL DAO_APPROVED PENDING_VALIDATION VALIDATED WITHDRAWN } enum DataType { DATA_BUCKET MANIFEST UNKNOWN DATASET IMAGES VIDEOS CODE_REPOS DOCUMENT } enum PublishState { WAITING PENDING SUCCESS FAILED } enum AuthTokenSource { ORCID }