Files
devops-platform-api/prisma/schema.prisma
T
湛兮 bc3aa31289 feat: 接入真实登录与成员权限
- auth/members/messages: 新增超级管理员登录、成员权限和密码消息流程
- agent-config/agent: 支持服务端保存 Agent 配置并取消未配置 mock 成功结果
- projects/deploy-runs/settings: 按当前用户权限保护真实接口
- prisma: 新增用户、项目权限和平台消息表结构
2026-06-12 00:38:23 +08:00

343 lines
8.7 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
}
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")
}