Files
knowledge-governance/internal/httpapi/qa_dashboard.go
T
姚章浩 6e67034fbd
build / build (push) Successful in 1m10s
feat(qa-ops): 交付十一项统计看板与完整图片导出
以治理库单一只读事务分开聚合累计、自然周、截止月及当前通讯录使用分母;浏览器不再读取全量长答案来构建看板。

新增迁移52与普通worker周质量冻结,保留真实冻结时点、规则和标量贡献;缺少当时快照留空。提交后冻结头与贡献不可修改、删除或追加;只读接口保留管理员、固定租户、严格JSON与输入冲突保护。

已验证:make verify退出0,686个Go用例和305个前端用例通过,必需跳过0;镜像与组织隔离PostgreSQL竞态回归退出0。真实治理副本浏览器核对第41周累计1885与新增471、十一项和完整PNG下载,390px无外溢、JS异常0;明确模拟503后不伪零且重试恢复。没有修改DobotAI原始问答、真实区域规则或生产发布门禁。
2026-10-18 23:26:55 +08:00

51 lines
1.3 KiB
Go

package httpapi
import (
"context"
"errors"
"knowledge-governance/internal/dobotaiops"
"knowledge-governance/internal/qaopsmirror"
"knowledge-governance/internal/qaopsquality"
"net/http"
"time"
)
type qaDashboardReader interface {
ReadDashboard(context.Context, dobotaiops.RecordQuery) (qaopsmirror.Dashboard, error)
}
func qaOperationsDashboard(w http.ResponseWriter, r *http.Request, c Config) {
if !authorizeQAOps(w, r) || !authorizeQAIntent(w, r, "qa-dashboard") {
return
}
var request struct {
Start string `json:"start"`
End string `json:"end"`
Keyword string `json:"keyword"`
}
if decodeQualityJSON(w, r, &request, "start", "end") != nil {
qaOpsError(w, dobotaiops.ErrInvalidQuery)
return
}
reader, ok := c.QAOps.(qaDashboardReader)
if !ok || c.QAOpsTenantKey == "" {
qaOpsError(w, dobotaiops.ErrUnavailable)
return
}
window, e := dobotaiops.NewWindow(c.QAOpsTenantKey, request.Start, request.End, 90*24*time.Hour, c.Now())
if e != nil {
qaOpsError(w, e)
return
}
dashboard, e := reader.ReadDashboard(r.Context(), dobotaiops.RecordQuery{Window: window, Keyword: request.Keyword})
if e != nil {
if errors.Is(e, qaopsquality.ErrConflict) {
writeQualityError(w, e)
return
}
qaOpsError(w, e)
return
}
writeJSON(w, 200, map[string]any{"data": dashboard})
}