feat: 展示真实运维审计日志

This commit is contained in:
湛兮
2026-06-11 23:06:49 +08:00
parent c89118ee00
commit 88836590cd
5 changed files with 155 additions and 1 deletions
+41
View File
@@ -4,6 +4,7 @@
import type {
AgentCard,
AgentInvocation,
AuditLogEntry,
CreateAgentInvocationPayload,
CreateDeployRunPayload,
DashboardSummary,
@@ -267,6 +268,12 @@ export const devopsApi = {
return toJenkinsSyncSummary(data, projectList)
},
async getAuditLogs(): Promise<AuditLogEntry[]> {
const { data } = await http.get<AuditLogEntry[]>('/audit-logs')
lastDataSource = 'backend'
return Array.isArray(data) ? data.map(sanitizeAuditLogEntry) : []
},
async getAgentCards(): Promise<AgentCard[]> {
return agentCards
},
@@ -416,6 +423,22 @@ function sanitizeIntegrationNote(note?: string): string | undefined {
.replace(/key=[^&\s]+/g, 'key=[已隐藏]')
}
function safeText(value: unknown, fallback: string): string {
return typeof value === 'string' && value.trim() ? value : fallback
}
function optionalSafeText(value: unknown): string | undefined {
return typeof value === 'string' && value.trim() ? value : undefined
}
function safeRecord(value: unknown): Record<string, unknown> | undefined {
if (!value || typeof value !== 'object' || Array.isArray(value)) {
return undefined
}
return value as Record<string, unknown>
}
function toProjectConfigs(backendProjects: BackendProject[]): ProjectConfig[] {
return backendProjects.map((project) => {
const repo = parseRepository(project.repositoryUrl, project.key)
@@ -498,6 +521,24 @@ function toJenkinsSyncSummary(
}
}
function sanitizeAuditLogEntry(record: AuditLogEntry): AuditLogEntry {
return {
id: safeText(record.id, 'audit-unknown'),
action: safeText(record.action, 'UNKNOWN_ACTION'),
resourceType: safeText(record.resourceType, 'unknown'),
resourceId: optionalSafeText(record.resourceId),
actorId: optionalSafeText(record.actorId),
actorName: optionalSafeText(record.actorName),
requestId: optionalSafeText(record.requestId),
sourceIp: optionalSafeText(record.sourceIp),
userAgent: optionalSafeText(record.userAgent),
before: safeRecord(record.before),
after: safeRecord(record.after),
parameterDigest: safeRecord(record.parameterDigest),
createdAt: safeText(record.createdAt, ''),
}
}
function toPipelineStep(step: BackendDeployRunStep): PipelineStep {
const bpmnNodeId = step.bpmnNodeId || step.id || 'unknown-step'
const name = step.name || bpmnNodeId