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

generator client {
  provider      = "prisma-client-py"
  binaryTargets = ["native", "debian-openssl-1.1.x", "debian-openssl-3.0.x", "linux-musl", "linux-musl-openssl-3.0.x"]
}

// Budget / Rate Limits for an org
model LiteLLM_BudgetTable {
  budget_id               String                           @id @default(uuid())
  max_budget              Float?
  soft_budget             Float?
  max_parallel_requests   Int?
  tpm_limit               BigInt?
  rpm_limit               BigInt?
  model_max_budget        Json?
  budget_duration         String?
  budget_reset_at         DateTime?
  created_at              DateTime                         @default(now()) @map("created_at")
  created_by              String
  updated_at              DateTime                         @default(now()) @updatedAt @map("updated_at")
  updated_by              String
  organization            LiteLLM_OrganizationTable[] // multiple orgs can have the same budget
  projects                LiteLLM_ProjectTable[] // multiple projects can have the same budget
  keys                    LiteLLM_VerificationToken[] // multiple keys can have the same budget
  end_users               LiteLLM_EndUserTable[] // multiple end-users can have the same budget
  tags                    LiteLLM_TagTable[] // multiple tags can have the same budget
  team_membership         LiteLLM_TeamMembership[] // budgets of Users within a Team 
  organization_membership LiteLLM_OrganizationMembership[] // budgets of Users within a Organization 
}

// Models on proxy
model LiteLLM_CredentialsTable {
  credential_id     String   @id @default(uuid())
  credential_name   String   @unique
  credential_values Json
  credential_info   Json?
  created_at        DateTime @default(now()) @map("created_at")
  created_by        String
  updated_at        DateTime @default(now()) @updatedAt @map("updated_at")
  updated_by        String
}

// Models on proxy
model LiteLLM_ProxyModelTable {
  model_id       String   @id @default(uuid())
  model_name     String
  litellm_params Json
  model_info     Json?
  created_at     DateTime @default(now()) @map("created_at")
  created_by     String
  updated_at     DateTime @default(now()) @updatedAt @map("updated_at")
  updated_by     String
}

// Agents on proxy
model LiteLLM_AgentsTable {
  agent_id             String                         @id @default(uuid())
  agent_name           String                         @unique
  litellm_params       Json?
  agent_card_params    Json
  static_headers       Json?                          @default("{}")
  extra_headers        String[]                       @default([])
  agent_access_groups  String[]                       @default([])
  object_permission_id String?
  object_permission    LiteLLM_ObjectPermissionTable? @relation(fields: [object_permission_id], references: [object_permission_id])
  spend                Float                          @default(0.0)
  tpm_limit            Int?
  rpm_limit            Int?
  session_tpm_limit    Int?
  session_rpm_limit    Int?
  created_at           DateTime                       @default(now()) @map("created_at")
  created_by           String
  updated_at           DateTime                       @default(now()) @updatedAt @map("updated_at")
  updated_by           String
}

model LiteLLM_OrganizationTable {
  organization_id      String                           @id @default(uuid())
  organization_alias   String
  budget_id            String
  metadata             Json                             @default("{}")
  models               String[]
  spend                Float                            @default(0.0)
  model_spend          Json                             @default("{}")
  object_permission_id String?
  created_at           DateTime                         @default(now()) @map("created_at")
  created_by           String
  updated_at           DateTime                         @default(now()) @updatedAt @map("updated_at")
  updated_by           String
  litellm_budget_table LiteLLM_BudgetTable?             @relation(fields: [budget_id], references: [budget_id])
  teams                LiteLLM_TeamTable[]
  users                LiteLLM_UserTable[]
  keys                 LiteLLM_VerificationToken[]
  members              LiteLLM_OrganizationMembership[] @relation("OrganizationToMembership")
  object_permission    LiteLLM_ObjectPermissionTable?   @relation(fields: [object_permission_id], references: [object_permission_id])
}

// Model info for teams, just has model aliases for now.
model LiteLLM_ModelTable {
  id            Int                @id @default(autoincrement())
  model_aliases Json?              @map("aliases")
  created_at    DateTime           @default(now()) @map("created_at")
  created_by    String
  updated_at    DateTime           @default(now()) @updatedAt @map("updated_at")
  updated_by    String
  team          LiteLLM_TeamTable?
}

// Assign prod keys to groups, not individuals 
model LiteLLM_TeamTable {
  team_id                     String                         @id @default(uuid())
  team_alias                  String?
  organization_id             String?
  object_permission_id        String?
  admins                      String[]
  members                     String[]
  members_with_roles          Json                           @default("{}")
  metadata                    Json                           @default("{}")
  max_budget                  Float?
  soft_budget                 Float?
  spend                       Float                          @default(0.0)
  models                      String[]
  max_parallel_requests       Int?
  tpm_limit                   BigInt?
  rpm_limit                   BigInt?
  budget_duration             String?
  budget_reset_at             DateTime?
  blocked                     Boolean                        @default(false)
  created_at                  DateTime                       @default(now()) @map("created_at")
  updated_at                  DateTime                       @default(now()) @updatedAt @map("updated_at")
  model_spend                 Json                           @default("{}")
  model_max_budget            Json                           @default("{}")
  router_settings             Json?                          @default("{}")
  team_member_permissions     String[]                       @default([])
  access_group_ids            String[]                       @default([])
  policies                    String[]                       @default([])
  model_id                    Int?                           @unique // id for LiteLLM_ModelTable -> stores team-level model aliases
  allow_team_guardrail_config Boolean                        @default(false) // if true, team admin can configure guardrails for this team
  litellm_organization_table  LiteLLM_OrganizationTable?     @relation(fields: [organization_id], references: [organization_id])
  litellm_model_table         LiteLLM_ModelTable?            @relation(fields: [model_id], references: [id])
  object_permission           LiteLLM_ObjectPermissionTable? @relation(fields: [object_permission_id], references: [object_permission_id])
  projects                    LiteLLM_ProjectTable[]
}

// Projects sit between teams and keys for use-case management
model LiteLLM_ProjectTable {
  project_id           String   @id @default(uuid())
  project_alias        String?
  description          String?
  team_id              String?
  budget_id            String?
  metadata             Json     @default("{}")
  models               String[]
  spend                Float    @default(0.0)
  model_spend          Json     @default("{}")
  model_rpm_limit      Json     @default("{}")
  model_tpm_limit      Json     @default("{}")
  blocked              Boolean  @default(false)
  object_permission_id String?
  created_at           DateTime @default(now()) @map("created_at")
  created_by           String
  updated_at           DateTime @default(now()) @updatedAt @map("updated_at")
  updated_by           String

  // Relations
  litellm_team_table   LiteLLM_TeamTable?             @relation(fields: [team_id], references: [team_id])
  litellm_budget_table LiteLLM_BudgetTable?           @relation(fields: [budget_id], references: [budget_id])
  keys                 LiteLLM_VerificationToken[]
  object_permission    LiteLLM_ObjectPermissionTable? @relation(fields: [object_permission_id], references: [object_permission_id])
}

// Audit table for deleted teams - preserves spend and team information for historical tracking
model LiteLLM_DeletedTeamTable {
  id                          String    @id @default(uuid())
  team_id                     String // Original team_id
  team_alias                  String?
  organization_id             String?
  object_permission_id        String?
  admins                      String[]
  members                     String[]
  members_with_roles          Json      @default("{}")
  metadata                    Json      @default("{}")
  max_budget                  Float?
  soft_budget                 Float?
  spend                       Float     @default(0.0)
  models                      String[]
  max_parallel_requests       Int?
  tpm_limit                   BigInt?
  rpm_limit                   BigInt?
  budget_duration             String?
  budget_reset_at             DateTime?
  blocked                     Boolean   @default(false)
  model_spend                 Json      @default("{}")
  model_max_budget            Json      @default("{}")
  router_settings             Json?     @default("{}")
  team_member_permissions     String[]  @default([])
  access_group_ids            String[]  @default([])
  policies                    String[]  @default([])
  model_id                    Int? // id for LiteLLM_ModelTable -> stores team-level model aliases
  allow_team_guardrail_config Boolean   @default(false)

  // Original timestamps from team creation/updates
  created_at DateTime? @map("created_at")
  updated_at DateTime? @map("updated_at")

  // Deletion metadata
  deleted_at         DateTime @default(now()) @map("deleted_at")
  deleted_by         String?  @map("deleted_by") // User who deleted the team
  deleted_by_api_key String?  @map("deleted_by_api_key") // API key hash that performed the deletion
  litellm_changed_by String?  @map("litellm_changed_by") // From litellm-changed-by header if provided

  @@index([team_id])
  @@index([deleted_at])
  @@index([organization_id])
  @@index([team_alias])
  @@index([created_at])
}

// Track spend, rate limit, budget Users
model LiteLLM_UserTable {
  user_id                String    @id
  user_alias             String?
  team_id                String?
  sso_user_id            String?   @unique
  organization_id        String?
  object_permission_id   String?
  password               String?
  teams                  String[]  @default([])
  user_role              String?
  max_budget             Float?
  spend                  Float     @default(0.0)
  user_email             String?
  models                 String[]
  metadata               Json      @default("{}")
  max_parallel_requests  Int?
  tpm_limit              BigInt?
  rpm_limit              BigInt?
  budget_duration        String?
  budget_reset_at        DateTime?
  allowed_cache_controls String[]  @default([])
  policies               String[]  @default([])
  model_spend            Json      @default("{}")
  model_max_budget       Json      @default("{}")
  created_at             DateTime? @default(now()) @map("created_at")
  updated_at             DateTime? @default(now()) @updatedAt @map("updated_at")

  // relations
  litellm_organization_table LiteLLM_OrganizationTable?       @relation(fields: [organization_id], references: [organization_id])
  organization_memberships   LiteLLM_OrganizationMembership[]
  invitations_created        LiteLLM_InvitationLink[]         @relation("CreatedBy")
  invitations_updated        LiteLLM_InvitationLink[]         @relation("UpdatedBy")
  invitations_user           LiteLLM_InvitationLink[]         @relation("UserId")
  object_permission          LiteLLM_ObjectPermissionTable?   @relation(fields: [object_permission_id], references: [object_permission_id])
}

model LiteLLM_ObjectPermissionTable {
  object_permission_id String                      @id @default(uuid())
  mcp_servers          String[]                    @default([])
  mcp_access_groups    String[]                    @default([])
  mcp_tool_permissions Json? // Tool-level permissions for MCP servers. Format: {"server_id": ["tool_name_1", "tool_name_2"]}
  vector_stores        String[]                    @default([])
  agents               String[]                    @default([])
  agent_access_groups  String[]                    @default([])
  blocked_tools        String[]                    @default([]) // Tool names blocked for any key/team/user with this permission
  teams                LiteLLM_TeamTable[]
  projects             LiteLLM_ProjectTable[]
  verification_tokens  LiteLLM_VerificationToken[]
  organizations        LiteLLM_OrganizationTable[]
  users                LiteLLM_UserTable[]
  end_users            LiteLLM_EndUserTable[]
  agents_table         LiteLLM_AgentsTable[]
}

// Holds the MCP server configuration 
model LiteLLM_MCPServerTable {
  server_id                    String    @id @default(uuid())
  server_name                  String?
  alias                        String?
  description                  String?
  url                          String?
  spec_path                    String?
  transport                    String    @default("sse")
  auth_type                    String?
  credentials                  Json?     @default("{}")
  created_at                   DateTime? @default(now()) @map("created_at")
  created_by                   String?
  updated_at                   DateTime? @default(now()) @updatedAt @map("updated_at")
  updated_by                   String?
  mcp_info                     Json?     @default("{}")
  mcp_access_groups            String[]
  allowed_tools                String[]  @default([])
  tool_name_to_display_name    Json?     @default("{}")
  tool_name_to_description     Json?     @default("{}")
  extra_headers                String[]  @default([])
  static_headers               Json?     @default("{}")
  // Health check status
  status                       String?   @default("unknown")
  last_health_check            DateTime?
  health_check_error           String?
  // Stdio-specific fields
  command                      String?
  args                         String[]  @default([])
  env                          Json?     @default("{}")
  authorization_url            String?
  token_url                    String?
  registration_url             String?
  allow_all_keys               Boolean   @default(false)
  available_on_public_internet Boolean   @default(true)
  is_byok                      Boolean   @default(false)
  byok_description             String[]  @default([])
  byok_api_key_help_url        String?
}

// Per-user BYOK credentials for MCP servers
model LiteLLM_MCPUserCredentials {
  id             String   @id @default(uuid())
  user_id        String
  server_id      String
  credential_b64 String
  created_at     DateTime @default(now()) @map("created_at")
  updated_at     DateTime @default(now()) @updatedAt @map("updated_at")

  @@unique([user_id, server_id])
}

// Generate Tokens for Proxy
model LiteLLM_VerificationToken {
  token                      String                         @id
  key_name                   String?
  key_alias                  String?
  soft_budget_cooldown       Boolean                        @default(false) // key-level state on if budget alerts need to be cooled down
  spend                      Float                          @default(0.0)
  expires                    DateTime?
  models                     String[]
  aliases                    Json                           @default("{}")
  config                     Json                           @default("{}")
  router_settings            Json?                          @default("{}")
  user_id                    String?
  team_id                    String?
  agent_id                   String?
  project_id                 String?
  permissions                Json                           @default("{}")
  max_parallel_requests      Int?
  metadata                   Json                           @default("{}")
  blocked                    Boolean?
  tpm_limit                  BigInt?
  rpm_limit                  BigInt?
  max_budget                 Float?
  budget_duration            String?
  budget_reset_at            DateTime?
  allowed_cache_controls     String[]                       @default([])
  allowed_routes             String[]                       @default([])
  policies                   String[]                       @default([])
  access_group_ids           String[]                       @default([])
  model_spend                Json                           @default("{}")
  model_max_budget           Json                           @default("{}")
  budget_id                  String?
  organization_id            String?
  object_permission_id       String?
  created_at                 DateTime?                      @default(now()) @map("created_at")
  created_by                 String?
  updated_at                 DateTime?                      @default(now()) @updatedAt @map("updated_at")
  updated_by                 String?
  last_active                DateTime? // When this key was last used
  rotation_count             Int?                           @default(0) // Number of times key has been rotated
  auto_rotate                Boolean?                       @default(false) // Whether this key should be auto-rotated
  rotation_interval          String? // How often to rotate (e.g., "30d", "90d")
  last_rotation_at           DateTime? // When this key was last rotated
  key_rotation_at            DateTime? // When this key should next be rotated
  litellm_budget_table       LiteLLM_BudgetTable?           @relation(fields: [budget_id], references: [budget_id])
  litellm_organization_table LiteLLM_OrganizationTable?     @relation(fields: [organization_id], references: [organization_id])
  litellm_project_table      LiteLLM_ProjectTable?          @relation(fields: [project_id], references: [project_id])
  object_permission          LiteLLM_ObjectPermissionTable? @relation(fields: [object_permission_id], references: [object_permission_id])
  jwt_key_mappings           LiteLLM_JWTKeyMapping[]

  // SELECT COUNT(*) FROM (SELECT "public"."LiteLLM_VerificationToken"."token" FROM "public"."LiteLLM_VerificationToken" WHERE ("public"."LiteLLM_VerificationToken"."user_id" = $1 AND ("public"."LiteLLM_VerificationToken"."team_id" IS NULL OR "public"."LiteLLM_VerificationToken"."team_id" <> $2)) OFFSET $3 ) AS "sub"
  // SELECT ... FROM "public"."LiteLLM_VerificationToken" WHERE "public"."LiteLLM_VerificationToken"."user_id" = $1 OFFSET $2
  @@index([user_id, team_id])
  // SELECT ... FROM "public"."LiteLLM_VerificationToken" WHERE "public"."LiteLLM_VerificationToken"."team_id" = $1 OFFSET $2
  @@index([team_id])
  // SELECT ... FROM "public"."LiteLLM_VerificationToken" WHERE (("public"."LiteLLM_VerificationToken"."expires" IS NULL OR "public"."LiteLLM_VerificationToken"."expires" > $1) AND "public"."LiteLLM_VerificationToken"."budget_reset_at" < $2) OFFSET $3
  @@index([budget_reset_at, expires])
}

model LiteLLM_JWTKeyMapping {
  id              String   @id @default(uuid())
  jwt_claim_name  String // e.g. "sub", "email"
  jwt_claim_value String // The claim value to match
  token           String // Hashed virtual key (FK)
  description     String?
  is_active       Boolean  @default(true)
  created_at      DateTime @default(now())
  created_by      String?
  updated_at      DateTime @default(now()) @updatedAt
  updated_by      String?

  litellm_verification_token LiteLLM_VerificationToken @relation(fields: [token], references: [token])

  @@unique([jwt_claim_name, jwt_claim_value])
  @@index([jwt_claim_name, jwt_claim_value, is_active])
}

// Deprecated keys during grace period - allows old key to work until revoke_at
model LiteLLM_DeprecatedVerificationToken {
  id              String   @id @default(uuid())
  token           String // Hashed old key
  active_token_id String // Current token hash in LiteLLM_VerificationToken
  revoke_at       DateTime // When the old key stops working
  created_at      DateTime @default(now()) @map("created_at")

  @@unique([token])
  @@index([token, revoke_at])
  @@index([revoke_at])
}

// Audit table for deleted keys - preserves spend and key information for historical tracking
model LiteLLM_DeletedVerificationToken {
  id                     String    @id @default(uuid())
  token                  String // Original token (hashed)
  key_name               String?
  key_alias              String?
  soft_budget_cooldown   Boolean   @default(false)
  spend                  Float     @default(0.0)
  expires                DateTime?
  models                 String[]
  aliases                Json      @default("{}")
  config                 Json      @default("{}")
  user_id                String?
  team_id                String?
  agent_id               String?
  project_id             String?
  permissions            Json      @default("{}")
  max_parallel_requests  Int?
  metadata               Json      @default("{}")
  blocked                Boolean?
  tpm_limit              BigInt?
  rpm_limit              BigInt?
  max_budget             Float?
  budget_duration        String?
  budget_reset_at        DateTime?
  allowed_cache_controls String[]  @default([])
  allowed_routes         String[]  @default([])
  policies               String[]  @default([])
  access_group_ids       String[]  @default([])
  model_spend            Json      @default("{}")
  model_max_budget       Json      @default("{}")
  router_settings        Json?     @default("{}")
  budget_id              String?
  organization_id        String?
  object_permission_id   String?
  created_at             DateTime? // Original creation timestamp
  created_by             String? // Original creator
  updated_at             DateTime? // Last update timestamp before deletion
  updated_by             String? // Last user who updated before deletion
  last_active            DateTime? // When this key was last used before deletion
  rotation_count         Int?      @default(0)
  auto_rotate            Boolean?  @default(false)
  rotation_interval      String?
  last_rotation_at       DateTime?
  key_rotation_at        DateTime?

  // Deletion metadata
  deleted_at         DateTime @default(now()) @map("deleted_at")
  deleted_by         String?  @map("deleted_by") // User who deleted the key
  deleted_by_api_key String?  @map("deleted_by_api_key") // API key hash that performed the deletion
  litellm_changed_by String?  @map("litellm_changed_by") // From litellm-changed-by header if provided

  @@index([token])
  @@index([deleted_at])
  @@index([user_id])
  @@index([team_id])
  @@index([organization_id])
  @@index([key_alias])
  @@index([created_at])
}

model LiteLLM_EndUserTable {
  user_id              String                         @id
  alias                String? // admin-facing alias
  spend                Float                          @default(0.0)
  allowed_model_region String? // require all user requests to use models in this specific region
  default_model        String? // use along with 'allowed_model_region'. if no available model in region, default to this model.
  budget_id            String?
  object_permission_id String?
  litellm_budget_table LiteLLM_BudgetTable?           @relation(fields: [budget_id], references: [budget_id])
  object_permission    LiteLLM_ObjectPermissionTable? @relation(fields: [object_permission_id], references: [object_permission_id])
  blocked              Boolean                        @default(false)
}

// Track tags with budgets and spend
model LiteLLM_TagTable {
  tag_name             String               @id
  description          String?
  models               String[]
  model_info           Json? // maps model_id to model_name
  spend                Float                @default(0.0)
  budget_id            String?
  litellm_budget_table LiteLLM_BudgetTable? @relation(fields: [budget_id], references: [budget_id])
  created_at           DateTime             @default(now()) @map("created_at")
  created_by           String?
  updated_at           DateTime             @default(now()) @updatedAt @map("updated_at")
}

// store proxy config.yaml
model LiteLLM_Config {
  param_name  String @id
  param_value Json?
}

// View spend, model, api_key per request
model LiteLLM_SpendLogs {
  request_id               String    @id
  call_type                String
  api_key                  String    @default("") // Hashed API Token. Not the actual Virtual Key. Equivalent to 'token' column in LiteLLM_VerificationToken
  spend                    Float     @default(0.0)
  total_tokens             Int       @default(0)
  prompt_tokens            Int       @default(0)
  completion_tokens        Int       @default(0)
  startTime                DateTime // Assuming start_time is a DateTime field
  endTime                  DateTime // Assuming end_time is a DateTime field
  request_duration_ms      Int?
  completionStartTime      DateTime? // Assuming completionStartTime is a DateTime field
  model                    String    @default("")
  model_id                 String?   @default("") // the model id stored in proxy model db
  model_group              String?   @default("") // public model_name / model_group
  custom_llm_provider      String?   @default("") // litellm used custom_llm_provider
  api_base                 String?   @default("")
  user                     String?   @default("")
  metadata                 Json?     @default("{}") // project_id stored here
  cache_hit                String?   @default("")
  cache_key                String?   @default("")
  request_tags             Json?     @default("[]")
  team_id                  String?
  organization_id          String?
  end_user                 String?
  requester_ip_address     String?
  messages                 Json?     @default("{}")
  response                 Json?     @default("{}")
  session_id               String?
  status                   String?
  mcp_namespaced_tool_name String?
  agent_id                 String?
  proxy_server_request     Json?     @default("{}")

  @@index([startTime])
  @@index([startTime, request_id])
  @@index([end_user])
  @@index([session_id])
}

// View spend, model, api_key per request
model LiteLLM_ErrorLogs {
  request_id         String   @id @default(uuid())
  startTime          DateTime // Assuming start_time is a DateTime field
  endTime            DateTime // Assuming end_time is a DateTime field
  api_base           String   @default("")
  model_group        String   @default("") // public model_name / model_group
  litellm_model_name String   @default("") // model passed to litellm
  model_id           String   @default("") // ID of model in ProxyModelTable
  request_kwargs     Json     @default("{}")
  exception_type     String   @default("")
  exception_string   String   @default("")
  status_code        String   @default("")
}

// Beta - allow team members to request access to a model
model LiteLLM_UserNotifications {
  request_id    String   @id
  user_id       String
  models        String[]
  justification String
  status        String // approved, disapproved, pending
}

model LiteLLM_TeamMembership {
  // Use this table to track the Internal User's Spend within a Team + Set Budgets, rpm limits for the user within the team
  user_id              String
  team_id              String
  spend                Float                @default(0.0)
  budget_id            String?
  litellm_budget_table LiteLLM_BudgetTable? @relation(fields: [budget_id], references: [budget_id])

  @@id([user_id, team_id])
}

model LiteLLM_OrganizationMembership {
  // Use this table to track Internal User and Organization membership. Helps tracking a users role within an Organization
  user_id         String
  organization_id String
  user_role       String?
  spend           Float?    @default(0.0)
  budget_id       String?
  created_at      DateTime? @default(now()) @map("created_at")
  updated_at      DateTime? @default(now()) @updatedAt @map("updated_at")

  // relations
  user                 LiteLLM_UserTable         @relation(fields: [user_id], references: [user_id])
  organization         LiteLLM_OrganizationTable @relation("OrganizationToMembership", fields: [organization_id], references: [organization_id])
  litellm_budget_table LiteLLM_BudgetTable?      @relation(fields: [budget_id], references: [budget_id])

  @@id([user_id, organization_id])
  @@unique([user_id, organization_id])
}

model LiteLLM_InvitationLink {
  // use this table to track invite links sent by admin for people to join the proxy
  id          String    @id @default(uuid())
  user_id     String
  is_accepted Boolean   @default(false)
  accepted_at DateTime? // when link is claimed (user successfully onboards via link)
  expires_at  DateTime // till when is link valid
  created_at  DateTime // when did admin create the link
  created_by  String // who created the link
  updated_at  DateTime // when was invite status updated
  updated_by  String // who updated the status (admin/user who accepted invite)

  // Relations
  liteLLM_user_table_user    LiteLLM_UserTable @relation("UserId", fields: [user_id], references: [user_id])
  liteLLM_user_table_created LiteLLM_UserTable @relation("CreatedBy", fields: [created_by], references: [user_id])
  liteLLM_user_table_updated LiteLLM_UserTable @relation("UpdatedBy", fields: [updated_by], references: [user_id])
}

model LiteLLM_AuditLog {
  id                 String   @id @default(uuid())
  updated_at         DateTime @default(now())
  changed_by         String   @default("") // user or system that performed the action
  changed_by_api_key String   @default("") // api key hash that performed the action
  action             String // create, update, delete
  table_name         String // on of  LitellmTableNames.TEAM_TABLE_NAME, LitellmTableNames.USER_TABLE_NAME, LitellmTableNames.PROXY_MODEL_TABLE_NAME,
  object_id          String // id of the object being audited. This can be the key id, team id, user id, model id
  before_value       Json? // value of the row 
  updated_values     Json? // value of the row after change
}

// Track daily user spend metrics per model and key
model LiteLLM_DailyUserSpend {
  id                          String   @id @default(uuid())
  user_id                     String?
  date                        String
  api_key                     String
  model                       String?
  model_group                 String?
  custom_llm_provider         String?
  mcp_namespaced_tool_name    String?
  endpoint                    String?
  prompt_tokens               BigInt   @default(0)
  completion_tokens           BigInt   @default(0)
  cache_read_input_tokens     BigInt   @default(0)
  cache_creation_input_tokens BigInt   @default(0)
  spend                       Float    @default(0.0)
  api_requests                BigInt   @default(0)
  successful_requests         BigInt   @default(0)
  failed_requests             BigInt   @default(0)
  created_at                  DateTime @default(now())
  updated_at                  DateTime @updatedAt

  @@unique([user_id, date, api_key, model, custom_llm_provider, mcp_namespaced_tool_name, endpoint])
  @@index([date])
  @@index([user_id, date])
  @@index([api_key])
  @@index([model])
  @@index([mcp_namespaced_tool_name])
  @@index([endpoint])
}

// Track daily organization spend metrics per model and key
model LiteLLM_DailyOrganizationSpend {
  id                          String   @id @default(uuid())
  organization_id             String?
  date                        String
  api_key                     String
  model                       String?
  model_group                 String?
  custom_llm_provider         String?
  mcp_namespaced_tool_name    String?
  endpoint                    String?
  prompt_tokens               BigInt   @default(0)
  completion_tokens           BigInt   @default(0)
  cache_read_input_tokens     BigInt   @default(0)
  cache_creation_input_tokens BigInt   @default(0)
  spend                       Float    @default(0.0)
  api_requests                BigInt   @default(0)
  successful_requests         BigInt   @default(0)
  failed_requests             BigInt   @default(0)
  created_at                  DateTime @default(now())
  updated_at                  DateTime @updatedAt

  @@unique([organization_id, date, api_key, model, custom_llm_provider, mcp_namespaced_tool_name, endpoint])
  @@index([date])
  @@index([organization_id, date])
  @@index([api_key])
  @@index([model])
  @@index([mcp_namespaced_tool_name])
  @@index([endpoint])
}

// Track daily end user (customer) spend metrics per model and key
model LiteLLM_DailyEndUserSpend {
  id                          String   @id @default(uuid())
  end_user_id                 String?
  date                        String
  api_key                     String
  model                       String?
  model_group                 String?
  custom_llm_provider         String?
  mcp_namespaced_tool_name    String?
  endpoint                    String?
  prompt_tokens               BigInt   @default(0)
  completion_tokens           BigInt   @default(0)
  cache_read_input_tokens     BigInt   @default(0)
  cache_creation_input_tokens BigInt   @default(0)
  spend                       Float    @default(0.0)
  api_requests                BigInt   @default(0)
  successful_requests         BigInt   @default(0)
  failed_requests             BigInt   @default(0)
  created_at                  DateTime @default(now())
  updated_at                  DateTime @updatedAt

  @@unique([end_user_id, date, api_key, model, custom_llm_provider, mcp_namespaced_tool_name, endpoint])
  @@index([date])
  @@index([end_user_id, date])
  @@index([api_key])
  @@index([model])
  @@index([mcp_namespaced_tool_name])
  @@index([endpoint])
}

// Track daily agent spend metrics per model and key
model LiteLLM_DailyAgentSpend {
  id                          String   @id @default(uuid())
  agent_id                    String?
  date                        String
  api_key                     String
  model                       String?
  model_group                 String?
  custom_llm_provider         String?
  mcp_namespaced_tool_name    String?
  endpoint                    String?
  prompt_tokens               BigInt   @default(0)
  completion_tokens           BigInt   @default(0)
  cache_read_input_tokens     BigInt   @default(0)
  cache_creation_input_tokens BigInt   @default(0)
  spend                       Float    @default(0.0)
  api_requests                BigInt   @default(0)
  successful_requests         BigInt   @default(0)
  failed_requests             BigInt   @default(0)
  created_at                  DateTime @default(now())
  updated_at                  DateTime @updatedAt

  @@unique([agent_id, date, api_key, model, custom_llm_provider, mcp_namespaced_tool_name, endpoint])
  @@index([date])
  @@index([agent_id, date])
  @@index([api_key])
  @@index([model])
  @@index([mcp_namespaced_tool_name])
  @@index([endpoint])
}

// Track daily team spend metrics per model and key
model LiteLLM_DailyTeamSpend {
  id                          String   @id @default(uuid())
  team_id                     String?
  date                        String
  api_key                     String
  model                       String?
  model_group                 String?
  custom_llm_provider         String?
  mcp_namespaced_tool_name    String?
  endpoint                    String?
  prompt_tokens               BigInt   @default(0)
  completion_tokens           BigInt   @default(0)
  cache_read_input_tokens     BigInt   @default(0)
  cache_creation_input_tokens BigInt   @default(0)
  spend                       Float    @default(0.0)
  api_requests                BigInt   @default(0)
  successful_requests         BigInt   @default(0)
  failed_requests             BigInt   @default(0)
  created_at                  DateTime @default(now())
  updated_at                  DateTime @updatedAt

  @@unique([team_id, date, api_key, model, custom_llm_provider, mcp_namespaced_tool_name, endpoint])
  @@index([date])
  @@index([team_id, date])
  @@index([api_key])
  @@index([model])
  @@index([mcp_namespaced_tool_name])
  @@index([endpoint])
}

// Track daily team spend metrics per model and key
model LiteLLM_DailyTagSpend {
  id                          String   @id @default(uuid())
  request_id                  String?
  tag                         String?
  date                        String
  api_key                     String
  model                       String?
  model_group                 String?
  custom_llm_provider         String?
  mcp_namespaced_tool_name    String?
  endpoint                    String?
  prompt_tokens               BigInt   @default(0)
  completion_tokens           BigInt   @default(0)
  cache_read_input_tokens     BigInt   @default(0)
  cache_creation_input_tokens BigInt   @default(0)
  spend                       Float    @default(0.0)
  api_requests                BigInt   @default(0)
  successful_requests         BigInt   @default(0)
  failed_requests             BigInt   @default(0)
  created_at                  DateTime @default(now())
  updated_at                  DateTime @updatedAt

  @@unique([tag, date, api_key, model, custom_llm_provider, mcp_namespaced_tool_name, endpoint])
  @@index([date])
  @@index([tag, date])
  @@index([api_key])
  @@index([model])
  @@index([mcp_namespaced_tool_name])
  @@index([endpoint])
}

// Track the status of cron jobs running. Only allow one pod to run the job at a time
model LiteLLM_CronJob {
  cronjob_id   String    @id @default(cuid()) // Unique ID for the record
  pod_id       String // Unique identifier for the pod acting as the leader
  status       JobStatus @default(INACTIVE) // Status of the cron job (active or inactive)
  last_updated DateTime  @default(now()) // Timestamp for the last update of the cron job record
  ttl          DateTime // Time when the leader's lease expires
}

enum JobStatus {
  ACTIVE
  INACTIVE
}

model LiteLLM_ManagedFileTable {
  id                  String   @id @default(uuid())
  unified_file_id     String   @unique // The base64 encoded unified file ID
  file_object         Json? // Stores the OpenAIFileObject
  model_mappings      Json
  flat_model_file_ids String[] @default([]) // Flat list of model file id's - for faster querying of model id -> unified file id
  storage_backend     String? // Storage backend name (e.g., "azure_storage", "gcs", "default")
  storage_url         String? // The actual storage URL where the file is stored
  created_at          DateTime @default(now())
  created_by          String?
  updated_at          DateTime @updatedAt
  updated_by          String?

  @@index([unified_file_id])
}

model LiteLLM_ManagedObjectTable {
  id                String   @id @default(uuid())
  unified_object_id String   @unique // The base64 encoded unified file ID
  model_object_id   String   @unique // the id returned by the backend API provider 
  file_object       Json // Stores the OpenAIFileObject
  file_purpose      String // either 'batch' or 'fine-tune'
  status            String? // check if batch cost has been tracked  
  batch_processed   Boolean  @default(false) // set to true by CheckBatchCost after cost is computed
  created_at        DateTime @default(now())
  created_by        String?
  updated_at        DateTime @updatedAt
  updated_by        String?

  @@index([unified_object_id])
  @@index([model_object_id])
}

model LiteLLM_ManagedVectorStoreTable {
  id                      String   @id @default(uuid())
  unified_resource_id     String   @unique // The base64 encoded unified vector store ID
  resource_object         Json? // Stores the VectorStoreCreateResponse
  model_mappings          Json // Maps model_id -> provider_vector_store_id
  flat_model_resource_ids String[] @default([]) // Flat list of provider vector store IDs for faster querying
  storage_backend         String? // Storage backend name (if applicable)
  storage_url             String? // Storage URL (if applicable)
  created_at              DateTime @default(now())
  created_by              String?
  updated_at              DateTime @updatedAt
  updated_by              String?

  @@index([unified_resource_id])
}

model LiteLLM_ManagedVectorStoresTable {
  vector_store_id          String   @id
  custom_llm_provider      String
  vector_store_name        String?
  vector_store_description String?
  vector_store_metadata    Json?
  created_at               DateTime @default(now())
  updated_at               DateTime @updatedAt
  litellm_credential_name  String?
  litellm_params           Json?
  team_id                  String?
  user_id                  String?

  @@index([team_id])
  @@index([user_id])
}

// Guardrails table for storing guardrail configurations
model LiteLLM_GuardrailsTable {
  guardrail_id   String    @id @default(uuid())
  guardrail_name String    @unique
  litellm_params Json
  guardrail_info Json?
  team_id        String?
  created_at     DateTime  @default(now())
  updated_at     DateTime  @updatedAt
  // Submission lifecycle. Possible values: pending_review (team-registered, awaiting approval), active (approved), rejected
  status         String    @default("active")
  submitted_at   DateTime?
  reviewed_at    DateTime?
  // submitted_by_user_id and submitted_by_email live in guardrail_info JSON

  @@index([status])
}

// Daily guardrail metrics for usage dashboard (one row per guardrail per day)
model LiteLLM_DailyGuardrailMetrics {
  guardrail_id       String // logical id; may not FK if guardrail from config
  date               String // YYYY-MM-DD
  requests_evaluated BigInt   @default(0)
  passed_count       BigInt   @default(0)
  blocked_count      BigInt   @default(0)
  flagged_count      BigInt   @default(0)
  avg_score          Float?
  avg_latency_ms     Float?
  created_at         DateTime @default(now())
  updated_at         DateTime @updatedAt

  @@id([guardrail_id, date])
  @@index([date])
  @@index([guardrail_id])
}

// Daily policy metrics for usage dashboard (one row per policy per day)
model LiteLLM_DailyPolicyMetrics {
  policy_id          String
  date               String // YYYY-MM-DD
  requests_evaluated BigInt   @default(0)
  passed_count       BigInt   @default(0)
  blocked_count      BigInt   @default(0)
  flagged_count      BigInt   @default(0)
  avg_score          Float?
  avg_latency_ms     Float?
  created_at         DateTime @default(now())
  updated_at         DateTime @updatedAt

  @@id([policy_id, date])
  @@index([date])
  @@index([policy_id])
}

// Index for fast "last N logs for guardrail/policy" from SpendLogs
model LiteLLM_SpendLogGuardrailIndex {
  request_id   String
  guardrail_id String
  policy_id    String? // set when run as part of a policy pipeline
  start_time   DateTime

  @@id([request_id, guardrail_id])
  @@index([guardrail_id, start_time])
  @@index([policy_id, start_time])
}

// Index for fast "last N logs for tool" from SpendLogs – see how a tool is called in production
model LiteLLM_SpendLogToolIndex {
  request_id String
  tool_name  String // matches LiteLLM_ToolTable.tool_name; join for input_policy/output_policy etc.
  start_time DateTime

  @@id([request_id, tool_name])
  @@index([tool_name, start_time])
}

// Prompt table for storing prompt configurations
model LiteLLM_PromptTable {
  id             String   @id @default(uuid())
  prompt_id      String
  version        Int      @default(1)
  litellm_params Json
  prompt_info    Json?
  created_at     DateTime @default(now())
  updated_at     DateTime @updatedAt

  @@unique([prompt_id, version])
  @@index([prompt_id])
}

model LiteLLM_HealthCheckTable {
  health_check_id  String   @id @default(uuid())
  model_name       String
  model_id         String?
  status           String
  healthy_count    Int      @default(0)
  unhealthy_count  Int      @default(0)
  error_message    String?
  response_time_ms Float?
  details          Json?
  checked_by       String?
  checked_at       DateTime @default(now())
  created_at       DateTime @default(now())
  updated_at       DateTime @updatedAt

  @@index([model_name])
  @@index([checked_at])
  @@index([status])
}

// Search Tools table for storing search tool configurations
model LiteLLM_SearchToolsTable {
  search_tool_id   String   @id @default(uuid())
  search_tool_name String   @unique
  litellm_params   Json
  search_tool_info Json?
  created_at       DateTime @default(now())
  updated_at       DateTime @updatedAt
}

// SSO configuration table
model LiteLLM_SSOConfig {
  id           String   @id @default("sso_config")
  sso_settings Json
  created_at   DateTime @default(now())
  updated_at   DateTime @updatedAt
}

model LiteLLM_ManagedVectorStoreIndexTable {
  id             String   @id @default(uuid())
  index_name     String   @unique
  litellm_params Json
  index_info     Json?
  created_at     DateTime @default(now())
  created_by     String?
  updated_at     DateTime @updatedAt
  updated_by     String?
}

// Cache configuration table
model LiteLLM_CacheConfig {
  id             String   @id @default("cache_config")
  cache_settings Json
  created_at     DateTime @default(now())
  updated_at     DateTime @updatedAt
}

// UI Settings configuration table
model LiteLLM_UISettings {
  id          String   @id @default("ui_settings")
  ui_settings Json
  created_at  DateTime @default(now())
  updated_at  DateTime @updatedAt
}

// Generic config overrides table - one row per config_type
model LiteLLM_ConfigOverrides {
  config_type  String   @id
  config_value Json
  created_at   DateTime @default(now())
  updated_at   DateTime @updatedAt
}

// Skills table for storing LiteLLM-managed skills
model LiteLLM_SkillsTable {
  skill_id       String   @id @default(uuid())
  display_title  String?
  description    String?
  instructions   String? // The skill instructions/prompt (from SKILL.md)
  source         String   @default("custom") // "custom" or "anthropic"
  latest_version String?
  file_content   Bytes? // Binary content of the skill files (zip)
  file_name      String? // Original filename
  file_type      String? // MIME type (e.g., "application/zip")
  metadata       Json?    @default("{}")
  created_at     DateTime @default(now())
  created_by     String?
  updated_at     DateTime @default(now()) @updatedAt
  updated_by     String?
}

// Policy table for storing guardrail policies (versioned)
model LiteLLM_PolicyTable {
  policy_id         String    @id @default(uuid())
  policy_name       String // No longer @unique; use @@unique([policy_name, version_number])
  version_number    Int       @default(1)
  version_status    String    @default("production") // "draft" | "published" | "production"
  parent_version_id String?
  is_latest         Boolean   @default(true)
  published_at      DateTime?
  production_at     DateTime?
  inherit           String? // Name of parent policy to inherit from
  description       String?
  guardrails_add    String[]  @default([])
  guardrails_remove String[]  @default([])
  condition         Json?     @default("{}") // Policy conditions (e.g., model matching)
  pipeline          Json? // Optional guardrail pipeline (mode + steps[])
  created_at        DateTime  @default(now())
  created_by        String?
  updated_at        DateTime  @default(now()) @updatedAt
  updated_by        String?

  @@unique([policy_name, version_number])
  @@index([policy_name, version_status])
}

// Policy attachment table for defining where policies apply
model LiteLLM_PolicyAttachmentTable {
  attachment_id String   @id @default(uuid())
  policy_name   String // Name of the policy to attach
  scope         String? // Use '*' for global scope
  teams         String[] @default([]) // Team aliases or patterns
  keys          String[] @default([]) // Key aliases or patterns
  models        String[] @default([]) // Model names or patterns
  tags          String[] @default([]) // Tag patterns (e.g., ["healthcare", "prod-*"])
  created_at    DateTime @default(now())
  created_by    String?
  updated_at    DateTime @default(now()) @updatedAt
  updated_by    String?
}

// Global tool registry - auto-discovered from LLM responses; admins set input/output policies here
model LiteLLM_ToolTable {
  tool_id       String    @id @default(uuid())
  tool_name     String    @unique // e.g. "huggingface_remote-mcp__dynamic_space"
  origin        String? // MCP server name or "user_defined"
  input_policy  String    @default("untrusted") // "trusted" | "untrusted" | "blocked"
  output_policy String    @default("untrusted") // "trusted" | "untrusted"
  call_count    Int       @default(0) // cumulative number of times this tool was seen
  assignments   Json?     @default("{}")
  key_hash      String? // hash of the virtual key that first called this tool
  team_id       String? // team that first called this tool
  key_alias     String? // human-readable alias of the virtual key
  user_agent    String? // user-agent of the first request that discovered this tool
  last_used_at  DateTime? // timestamp of the most recent call
  created_at    DateTime  @default(now())
  created_by    String?
  updated_at    DateTime  @default(now()) @updatedAt
  updated_by    String?

  @@index([input_policy])
  @@index([output_policy])
  @@index([team_id])
}

// Per-(tool, team/key) policy overrides. When present, override replaces global tool policy for that scope.
//Unified Access Groups table for storing unified access groups
model LiteLLM_AccessGroupTable {
  access_group_id   String  @id @default(uuid())
  access_group_name String  @unique
  description       String?

  // Resource memberships - explicit arrays per type
  access_model_names    String[] @default([])
  access_mcp_server_ids String[] @default([])
  access_agent_ids      String[] @default([])

  assigned_team_ids String[] @default([])
  assigned_key_ids  String[] @default([])

  created_at DateTime @default(now())
  created_by String?
  updated_at DateTime @default(now()) @updatedAt
  updated_by String?
}

// Claude Code Plugin Marketplace table
model LiteLLM_ClaudeCodePluginTable {
  id            String    @id @default(uuid())
  name          String    @unique
  version       String?
  description   String?
  manifest_json String?
  files_json    String?   @default("{}")
  enabled       Boolean   @default(true)
  created_at    DateTime? @default(now())
  updated_at    DateTime? @default(now()) @updatedAt
  created_by    String?

  @@map("LiteLLM_ClaudeCodePluginTable")
}
