feat: F019 AI monitoring layer — output transparency & governance workspace
Full 2-panel workspace at /ops/ai-monitoring: metrics strip (total, failed, pending, approval rate, top prompt version, active model), filterable output table by type/status/error, and detail panel with output preview, prompt versioning, error details, and role-aware review actions. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
import type { AIOutput, AIOutputType } from '../domain/aiOutput'
|
||||
import type { ReviewStatus } from '../domain/enums'
|
||||
|
||||
export interface AIMonitoringFilters {
|
||||
type?: AIOutputType
|
||||
reviewStatus?: ReviewStatus
|
||||
hasError?: boolean
|
||||
model?: string
|
||||
}
|
||||
|
||||
export interface IAIMonitoringProvider {
|
||||
getOutputs(filters?: AIMonitoringFilters): Promise<AIOutput[]>
|
||||
getOutput(id: string): Promise<AIOutput | null>
|
||||
updateReviewStatus(id: string, status: ReviewStatus): Promise<AIOutput>
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import type { IAIMonitoringProvider, AIMonitoringFilters } from './IAIMonitoringProvider'
|
||||
import type { AIOutput } from '../domain/aiOutput'
|
||||
import type { ReviewStatus } from '../domain/enums'
|
||||
import { mockAIOutputs } from '../mock-data/aiOutputs'
|
||||
|
||||
const store: AIOutput[] = [...mockAIOutputs]
|
||||
|
||||
export const MockupAIMonitoringProvider: IAIMonitoringProvider = {
|
||||
async getOutputs(filters?: AIMonitoringFilters) {
|
||||
let results = [...store]
|
||||
if (filters?.type) results = results.filter(o => o.type === filters.type)
|
||||
if (filters?.reviewStatus) results = results.filter(o => o.reviewStatus === filters.reviewStatus)
|
||||
if (filters?.hasError === true) results = results.filter(o => !!o.error)
|
||||
if (filters?.hasError === false) results = results.filter(o => !o.error)
|
||||
if (filters?.model) results = results.filter(o => o.model === filters.model)
|
||||
return results.sort((a, b) => b.createdAt.localeCompare(a.createdAt))
|
||||
},
|
||||
|
||||
async getOutput(id: string) {
|
||||
return store.find(o => o.id === id) ?? null
|
||||
},
|
||||
|
||||
async updateReviewStatus(id: string, status: ReviewStatus): Promise<AIOutput> {
|
||||
const idx = store.findIndex(o => o.id === id)
|
||||
if (idx === -1) throw new Error(`AIOutput ${id} not found`)
|
||||
store[idx] = { ...store[idx], reviewStatus: status }
|
||||
return store[idx]
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user