Files
2026-06-12 16:36:11 +08:00

344 lines
8.8 KiB
Plaintext

generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
enum ProjectStatus {
ACTIVE
ARCHIVED
}
enum EnvironmentKind {
TEST
PRODUCTION
}
enum DeployRunStatus {
PENDING
QUEUED
RUNNING
SUCCESS
FAILED
CANCELED
}
enum DeployRunTrigger {
MANUAL
GITEA_WEBHOOK
RETRY
JENKINS_EXTERNAL
}
enum RunStepStatus {
PENDING
RUNNING
SUCCESS
FAILED
SKIPPED
CANCELED
}
enum SecretProvider {
JENKINS
GITEA
WECOM
LLM
INTERNAL
}
enum AgentInvocationPurpose {
RISK_SUMMARY
FAILURE_DIAGNOSIS
RUNBOOK_QA
RELEASE_NOTES
INCIDENT_REVIEW
}
enum OutboxStatus {
PENDING
SENT
FAILED
DEAD
}
enum UserRole {
SUPER_ADMIN
MEMBER
}
enum UserStatus {
ACTIVE
DISABLED
}
enum ProjectPermissionLevel {
READ
BUILD
}
enum PlatformMessageType {
PASSWORD_RESET_REQUEST
}
enum PlatformMessageStatus {
PENDING
HANDLED
}
model Project {
id String @id @default(cuid())
key String @unique
name String
repositoryUrl String? @db.VarChar(512)
defaultBranch String @default("develop")
status ProjectStatus @default(ACTIVE)
metadata Json?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
environments Environment[]
deployJobs DeployJob[]
deployRuns DeployRun[]
permissions ProjectMemberPermission[]
@@map("projects")
}
model Environment {
id String @id @default(cuid())
projectId String
name EnvironmentKind
displayName String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
deployJobs DeployJob[]
deployRuns DeployRun[]
@@unique([projectId, name])
@@index([projectId])
@@map("environments")
}
model DeployJob {
id String @id @default(cuid())
projectId String
environmentId String
jenkinsJobPath String
jenkinsParameters Json?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
environment Environment @relation(fields: [environmentId], references: [id], onDelete: Cascade)
deployRuns DeployRun[]
@@unique([projectId, environmentId])
@@index([environmentId])
@@map("deploy_jobs")
}
model DeployRun {
id String @id @default(cuid())
projectId String
environmentId String
jobId String?
status DeployRunStatus @default(PENDING)
trigger DeployRunTrigger @default(MANUAL)
ref String
operator String
idempotencyKey String @unique
jenkinsQueueId String?
jenkinsBuildNumber Int?
failureSummary String? @db.Text
metadata Json?
version Int @default(1)
startedAt DateTime?
finishedAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
project Project @relation(fields: [projectId], references: [id], onDelete: Restrict)
environment Environment @relation(fields: [environmentId], references: [id], onDelete: Restrict)
job DeployJob? @relation(fields: [jobId], references: [id], onDelete: SetNull)
steps RunStep[]
auditLogs AuditLog[]
agentInvocations AgentInvocation[]
outboxMessages OutboxMessage[]
@@index([projectId, environmentId, createdAt])
@@index([status, createdAt])
@@map("deploy_runs")
}
model RunStep {
id String @id @default(cuid())
deployRunId String
bpmnNodeId String
name String
status RunStepStatus @default(PENDING)
order Int @default(0)
errorSummary String? @db.Text
metadata Json?
startedAt DateTime?
finishedAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deployRun DeployRun @relation(fields: [deployRunId], references: [id], onDelete: Cascade)
@@unique([deployRunId, bpmnNodeId])
@@index([deployRunId, order])
@@map("run_steps")
}
model AuditLog {
id String @id @default(cuid())
deployRunId String?
actorId String?
actorName String?
action String
resourceType String
resourceId String?
requestId String?
sourceIp String?
userAgent String?
before Json?
after Json?
parameterDigest Json?
createdAt DateTime @default(now())
deployRun DeployRun? @relation(fields: [deployRunId], references: [id], onDelete: SetNull)
@@index([resourceType, resourceId, createdAt])
@@index([actorId, createdAt])
@@map("audit_logs")
}
model User {
id String @id @default(cuid())
account String @unique
displayName String
role UserRole @default(MEMBER)
status UserStatus @default(ACTIVE)
passwordHash String @db.Text
mustChangePassword Boolean @default(false)
passwordVersion Int @default(1)
lastLoginAt DateTime?
createdById String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
projectPermissions ProjectMemberPermission[]
requestedMessages PlatformMessage[] @relation("message_requester")
handledMessages PlatformMessage[] @relation("message_handler")
@@index([role, status])
@@map("users")
}
model ProjectMemberPermission {
id String @id @default(cuid())
userId String
projectId String
level ProjectPermissionLevel
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
@@unique([userId, projectId])
@@index([projectId])
@@map("project_member_permissions")
}
model PlatformMessage {
id String @id @default(cuid())
type PlatformMessageType
status PlatformMessageStatus @default(PENDING)
title String
content String @db.Text
requesterId String?
requesterAccount String
targetResourceType String?
targetResourceId String?
metadata Json?
handledById String?
handledAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
requester User? @relation("message_requester", fields: [requesterId], references: [id], onDelete: SetNull)
handler User? @relation("message_handler", fields: [handledById], references: [id], onDelete: SetNull)
@@index([type, status, createdAt])
@@index([requesterId, status])
@@map("platform_messages")
}
model Secret {
id String @id @default(cuid())
provider SecretProvider
scopeType String
scopeId String
name String
encryptedValue String @db.Text
version Int @default(1)
rotatedAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([provider, scopeType, scopeId, name])
@@index([scopeType, scopeId])
@@map("secrets")
}
model AgentInvocation {
id String @id @default(cuid())
deployRunId String?
purpose AgentInvocationPurpose
actorId String?
actorName String?
model String?
promptVersion String
inputDigest Json
outputDigest Json?
tokenEstimate Int?
status String
errorSummary String? @db.Text
createdAt DateTime @default(now())
completedAt DateTime?
deployRun DeployRun? @relation(fields: [deployRunId], references: [id], onDelete: SetNull)
@@index([purpose, createdAt])
@@index([deployRunId, createdAt])
@@map("agent_invocations")
}
model OutboxMessage {
id String @id @default(cuid())
deployRunId String?
channel String
template String
payload Json
status OutboxStatus @default(PENDING)
attemptCount Int @default(0)
nextAttemptAt DateTime?
lastError String? @db.Text
idempotencyKey String @unique
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deployRun DeployRun? @relation(fields: [deployRunId], references: [id], onDelete: SetNull)
@@index([status, nextAttemptAt])
@@map("outbox_messages")
}