.prisma
Prisma
(text/prisma)
generator client {
  provider        = "prisma-client-js"
  previewFeatures = ["fullTextSearch", "interactiveTransactions", "orderByNulls"]
  binaryTargets   = ["native", "linux-musl", "debian-openssl-1.1.x", "debian-openssl-3.0.x"]
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

model Organization {
  id      String @id @default(cuid())
  
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  slug    String @unique

  owner   User   @relation("ManyOwnedOrganizationsToOneOwnerUser", fields: [ownerId], references: [id])
  ownerId String

  kind        OrganizationKind   @default(PERSONAL)
  visibility  ResourceVisibility @default(PRIVATE)
  avatarUri   String?
  displayName String?
  websiteUrl  String?

  memberships  OrganizationMembership[] @relation("OneOrganizationMembershipToOneOrganization")
  repositories Repository[]             @relation("ManyRepositoriesToOneOrganization")
}

model OrganizationMembership {
  id             String @id @default(cuid())
  organizationId String
  userId         String

  createdAt DateTime  @default(now())
  updatedAt DateTime  @updatedAt
  expiresAt DateTime?
  revokedAt DateTime?

  role OrganizationRole @default(REVIEWER)

  organization Organization @relation("OneOrganizationMembershipToOneOrganization", fields: [organizationId], references: [id])
  user         User         @relation("OneOrganizationMembershipToOneUser", fields: [userId], references: [id])
}

model PullRequest {
  id                 String @id @default(cuid())
  uid                Int    @default(autoincrement())
  authorId           String
  sourceRepositoryId String
  targetRepositoryId String

  createdAt DateTime  @default(now())
  updatedAt DateTime  @updatedAt
  closedAt  DateTime?

  state        PullRequestState @default(OPEN)
  sourceBranch String
  targetBranch String

  summary String
  textMd  String

  author           User                 @relation("OnePullRequestToOneUser", fields: [authorId], references: [id])
  comments         PullRequestComment[] @relation("OnePullRequestCommentToOnePullRequest")
  sourceRepository Repository           @relation("OneSourceRepositoryToManyPullRequests", fields: [sourceRepositoryId], references: [id])
  targetRepository Repository           @relation("OneTargetRepositoryToManyPullRequests", fields: [targetRepositoryId], references: [id])

  @@unique([uid, targetRepositoryId])
  @@unique([sourceRepositoryId, sourceBranch, targetRepositoryId, targetBranch])
}

model PullRequestComment {
  id            String @id @default(cuid())
  authorId      String
  pullRequestId String

  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  textMd String

  author      User        @relation("OnePullRequestToOnePRCommenterUser", fields: [authorId], references: [id])
  pullRequest PullRequest @relation("OnePullRequestCommentToOnePullRequest", fields: [pullRequestId], references: [id])
}

model Repository {
  id               String  @id @default(cuid())
  forkedFromRepoId String?
  organizationId   String
  slug             String

  createdAt    DateTime  @default(now())
  updatedAt    DateTime  @updatedAt
  lastPushedAt DateTime?

  visibility       ResourceVisibility @default(PRIVATE)
  isFork           Boolean            @default(false)
  keywords         String[]
  avatarUri        String?
  displayName      String?
  shortDescription String?
  websiteUrl       String?

  forkedFromRepo          Repository?   @relation("OneParentRepositoryToManyForkRepository", fields: [forkedFromRepoId], references: [id])
  forks                   Repository[]  @relation("OneParentRepositoryToManyForkRepository")
  organization            Organization  @relation("ManyRepositoriesToOneOrganization", fields: [organizationId], references: [id])
  pullRequestsWhereSource PullRequest[] @relation("OneSourceRepositoryToManyPullRequests")
  pullRequestsWhereTarget PullRequest[] @relation("OneTargetRepositoryToManyPullRequests")

  @@unique([slug, organizationId])
}

model Session {
  id        String @id @default(cuid())
  sessionId String @unique

  createdAt DateTime  @default(now())
  updatedAt DateTime  @updatedAt
  expiresAt DateTime?

  data Json?

  detectedIPAddress String @default("")
  detectedUserAgent String @default("")
}

model User {
  id String @id @default(cuid())
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  role           GlobalRole @default(CUSTOMER)
  username       String     @unique
  email          String     @unique
  hashedPassword String
  displayName    String?
  avatarUri      String?

  sshKeys UserSSHKey[] @relation("ManyUserSSHKeyToOneUser")

  organizations                  Organization[]           @relation("ManyOwnedOrganizationsToOneOwnerUser")
  organizationMemberships        OrganizationMembership[] @relation("OneOrganizationMembershipToOneUser")
  pullRequestsWhereAuthor        PullRequest[]            @relation("OnePullRequestToOneUser")
  pullRequestCommentsWhereAuthor PullRequestComment[]     @relation("OnePullRequestToOnePRCommenterUser")
}

model UserSSHKey {
  id String @id @default(cuid())
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  user   User   @relation("ManyUserSSHKeyToOneUser", fields: [userId], references: [id])
  userId String

  name String
  key String

  revoked Boolean @default(false)
}

enum GlobalRole {
  GUEST
  CUSTOMER
  ADMIN
  SUPER_ADMIN
}

enum OrganizationKind {
  PERSONAL
  COMPANY
}

enum OrganizationRole {
  REVIEWER
  COMITTER
  ADMIN
  OWNER
}

enum PullRequestState {
  OPEN
  CLOSE_MERGED
  CLOSE_DENIED
}

enum ResourceVisibility {
  PUBLIC
  UNLISTED
  PRIVATE
}