generator client {
  provider = "prisma-client"
  output   = "../src/generated/prisma"
}

datasource db {
  provider = "postgresql"
}

model Team {
  id              String            @id @default(cuid())
  name            String
  TeamCollection  TeamCollection[]
  TeamEnvironment TeamEnvironment[]
  TeamInvitation  TeamInvitation[]
  members         TeamMember[]
  TeamRequest     TeamRequest[]
}

model TeamMember {
  id      String         @id @default(uuid())
  role    TeamAccessRole
  userUid String
  teamID  String
  team    Team           @relation(fields: [teamID], references: [id], onDelete: Cascade)

  @@unique([teamID, userUid])
}

model TeamInvitation {
  id           String         @id @default(cuid())
  teamID       String
  creatorUid   String
  inviteeEmail String
  inviteeRole  TeamAccessRole
  team         Team           @relation(fields: [teamID], references: [id], onDelete: Cascade)

  @@unique([teamID, inviteeEmail])
  @@index([teamID])
}

model TeamCollection {
  id         String           @id @default(cuid())
  parentID   String?
  teamID     String
  title      String
  orderIndex Int
  createdOn  DateTime         @default(now()) @db.Timestamptz(3)
  updatedOn  DateTime         @updatedAt @db.Timestamptz(3)
  data       Json?
  parent     TeamCollection?  @relation("TeamCollectionChildParent", fields: [parentID], references: [id], onDelete: Cascade)
  children   TeamCollection[] @relation("TeamCollectionChildParent")
  team       Team             @relation(fields: [teamID], references: [id], onDelete: Cascade)
  requests   TeamRequest[]

  @@unique([teamID, parentID, orderIndex])
}

model TeamRequest {
  id           String         @id @default(cuid())
  collectionID String
  teamID       String
  title        String
  request      Json
  mockExamples Json?
  orderIndex   Int
  createdOn    DateTime       @default(now()) @db.Timestamptz(3)
  updatedOn    DateTime       @updatedAt @db.Timestamptz(3)
  collection   TeamCollection @relation(fields: [collectionID], references: [id], onDelete: Cascade)
  team         Team           @relation(fields: [teamID], references: [id], onDelete: Cascade)

  @@unique([teamID, collectionID, orderIndex])
}

model Shortcode {
  id              String   @id @unique
  request         Json
  creatorUid      String?
  createdOn       DateTime @default(now()) @db.Timestamptz(3)
  embedProperties Json?
  updatedOn       DateTime @default(now()) @updatedAt @db.Timestamptz(3)
  User            User?    @relation(fields: [creatorUid], references: [uid])

  @@unique([id, creatorUid], name: "creator_uid_shortcode_unique")
}

model TeamEnvironment {
  id        String @id @default(cuid())
  teamID    String
  name      String
  variables Json
  team      Team   @relation(fields: [teamID], references: [id], onDelete: Cascade)
}

model User {
  uid                  String                @id @default(cuid())
  displayName          String?
  email                String?               @unique
  photoURL             String?
  isAdmin              Boolean               @default(false)
  refreshToken         String?
  currentRESTSession   Json?
  currentGQLSession    Json?
  createdOn            DateTime              @default(now()) @db.Timestamptz(3)
  lastLoggedOn         DateTime?             @db.Timestamptz(3)
  lastActiveOn         DateTime?             @db.Timestamptz(3)
  providerAccounts     Account[]
  invitedUsers         InvitedUsers[]
  mockServers          MockServer[]
  personalAccessTokens PersonalAccessToken[]
  shortcodes           Shortcode[]
  userCollections      UserCollection[]
  UserEnvironments     UserEnvironment[]
  UserHistory          UserHistory[]
  userRequests         UserRequest[]
  settings             UserSettings?
  VerificationToken    VerificationToken[]
}

model Account {
  id                   String   @id @default(cuid())
  userId               String
  provider             String
  providerAccountId    String
  providerRefreshToken String?
  providerAccessToken  String?
  providerScope        String?
  loggedIn             DateTime @default(now()) @db.Timestamptz(3)
  user                 User     @relation(fields: [userId], references: [uid], onDelete: Cascade)

  @@unique([provider, providerAccountId], name: "verifyProviderAccount")
}

model VerificationToken {
  deviceIdentifier String
  token            String   @unique @default(cuid())
  userUid          String
  expiresOn        DateTime @db.Timestamptz(3)
  user             User     @relation(fields: [userUid], references: [uid], onDelete: Cascade)

  @@unique([deviceIdentifier, token], name: "passwordless_deviceIdentifier_tokens")
}

model UserSettings {
  id         String   @id @default(cuid())
  userUid    String   @unique
  properties Json
  updatedOn  DateTime @updatedAt @db.Timestamptz(3)
  user       User     @relation(fields: [userUid], references: [uid], onDelete: Cascade)
}

model UserHistory {
  id               String   @id @default(cuid())
  userUid          String
  reqType          ReqType
  request          Json
  responseMetadata Json
  isStarred        Boolean
  executedOn       DateTime @default(now()) @db.Timestamptz(3)
  user             User     @relation(fields: [userUid], references: [uid], onDelete: Cascade)
}

model UserEnvironment {
  id        String  @id @default(cuid())
  userUid   String
  name      String?
  variables Json
  isGlobal  Boolean
  user      User    @relation(fields: [userUid], references: [uid], onDelete: Cascade)
}

model InvitedUsers {
  adminUid     String
  adminEmail   String
  inviteeEmail String   @unique
  invitedOn    DateTime @default(now()) @db.Timestamptz(3)
  user         User     @relation(fields: [adminUid], references: [uid], onDelete: Cascade)
}

model UserRequest {
  id             String         @id @default(cuid())
  collectionID   String
  userUid        String
  title          String
  request        Json
  mockExamples   Json?
  type           ReqType
  orderIndex     Int
  createdOn      DateTime       @default(now()) @db.Timestamptz(3)
  updatedOn      DateTime       @updatedAt @db.Timestamptz(3)
  userCollection UserCollection @relation(fields: [collectionID], references: [id], onDelete: Cascade)
  user           User           @relation(fields: [userUid], references: [uid], onDelete: Cascade)

  @@unique([userUid, collectionID, orderIndex])
}

model UserCollection {
  id         String           @id @default(cuid())
  parentID   String?
  userUid    String
  title      String
  orderIndex Int
  type       ReqType
  createdOn  DateTime         @default(now()) @db.Timestamptz(3)
  updatedOn  DateTime         @updatedAt @db.Timestamptz(3)
  data       Json?
  parent     UserCollection?  @relation("ParentUserCollection", fields: [parentID], references: [id], onDelete: Cascade)
  children   UserCollection[] @relation("ParentUserCollection")
  user       User             @relation(fields: [userUid], references: [uid], onDelete: Cascade)
  requests   UserRequest[]

  @@unique([userUid, parentID, orderIndex])
}

model InfraConfig {
  id                     String   @id @default(cuid())
  name                   String   @unique
  value                  String?
  createdOn              DateTime @default(now()) @db.Timestamptz(3)
  updatedOn              DateTime @updatedAt @db.Timestamptz(3)
  isEncrypted            Boolean  @default(false)
  lastSyncedEnvFileValue String?
}

model PersonalAccessToken {
  id        String    @id @default(cuid())
  userUid   String
  label     String
  token     String    @unique @default(uuid())
  expiresOn DateTime? @db.Timestamptz(3)
  createdOn DateTime  @default(now()) @db.Timestamptz(3)
  updatedOn DateTime  @updatedAt @db.Timestamptz(3)
  user      User      @relation(fields: [userUid], references: [uid], onDelete: Cascade)
}

model InfraToken {
  id         String    @id @default(cuid())
  creatorUid String
  label      String
  token      String    @unique @default(uuid())
  expiresOn  DateTime? @db.Timestamptz(3)
  createdOn  DateTime  @default(now()) @db.Timestamptz(3)
  updatedOn  DateTime  @default(now()) @db.Timestamptz(3)
}

model MockServer {
  id              String               @id @default(cuid())
  name            String
  subdomain       String               @unique
  creatorUid      String?
  collectionID    String
  workspaceType   WorkspaceType
  workspaceID     String
  delayInMs       Int                  @default(0)
  isPublic        Boolean              @default(true)
  isActive        Boolean              @default(true)
  hitCount        Int                  @default(0)
  lastHitAt       DateTime?            @db.Timestamptz(3)
  createdOn       DateTime             @default(now()) @db.Timestamptz(3)
  updatedOn       DateTime             @updatedAt @db.Timestamptz(3)
  deletedAt       DateTime?            @db.Timestamptz(3)
  user            User?                @relation(fields: [creatorUid], references: [uid], onDelete: SetNull)
  requestLogs     MockServerLog[]
  activityHistory MockServerActivity[]
}

model MockServerLog {
  id              String     @id @default(cuid())
  mockServerID    String
  requestMethod   String
  requestPath     String
  requestHeaders  Json
  requestBody     Json?
  requestQuery    Json?
  responseStatus  Int
  responseHeaders Json
  responseBody    Json?
  responseTime    Int
  ipAddress       String?
  userAgent       String?
  executedAt      DateTime   @default(now()) @db.Timestamptz(3)
  mockServer      MockServer @relation(fields: [mockServerID], references: [id], onDelete: Cascade)

  @@index([mockServerID])
  @@index([mockServerID, executedAt])
}

model MockServerActivity {
  id           String           @id @default(cuid())
  mockServerID String
  action       MockServerAction
  performedBy  String?
  performedAt  DateTime         @default(now()) @db.Timestamptz(3)
  mockServer   MockServer       @relation(fields: [mockServerID], references: [id], onDelete: Cascade)

  @@index([mockServerID])
}

model PublishedDocs {
  id            String        @id @default(cuid())
  title         String
  collectionID  String
  creatorUid    String
  version       String
  autoSync      Boolean
  documentTree  Json? // Optional if autoSync is true
  workspaceType WorkspaceType
  workspaceID   String
  metadata      Json?
  createdOn     DateTime      @default(now()) @db.Timestamptz(3)
  updatedOn     DateTime      @updatedAt @db.Timestamptz(3)
}

enum WorkspaceType {
  USER
  TEAM
}

enum ReqType {
  REST
  GQL
}

enum TeamAccessRole {
  OWNER
  VIEWER
  EDITOR
}

enum MockServerAction {
  CREATED
  DELETED
  ACTIVATED
  DEACTIVATED
}
