4a2b2b7d84
build / build (push) Successful in 1m5s
区域配置入口改为区域统计,五列表按当前通讯录整支人员去重;调岗依当前归属、零分母未知、最近真实提问时间和父行收起不重算。仅读治理正式总表,后台单并发/请求合并/60秒缓存,目录与配置版本隔离,客户端失败不伪零。 保留区域自定义目录与预览/双版本锁保存,父部门勾选联选全后代,取消子支清除祖先整支选择,避免隐式覆盖未选子级;允许删除无引用区域,已有引用不静默孤立。统计页与设置共享选择,统计支持累计与北京时间自然月;不新增迁移,不改DobotAI生产、代理、原问答、历史趋势或已有AI任务。 验证已执行:完整make verify退出0,705 Go/340前端通过、120项声明的可选集成跳过且必需0跳过;镜像全量隔离PG race退出0;新增去重/调岗/空分母、后台缓存/并发、HTTP授权/严格请求、真PG目录与配置失效、树选择/收起、五列与删除保护均先红后绿。旧导航测试按新名称更新后全量通过。上线前治理库备份与真实恢复72表/29张QA内容哈希一致,匹配独立主密钥受限备份。 当前尚待精确SHA CI、同镜像真实数据浏览器与正式读回,不把源码验证称为已上线。公司真实区域映射不在本轮擅改;只在隔离库验证保存。
66 lines
2.3 KiB
Go
66 lines
2.3 KiB
Go
package httpapi
|
|
|
|
import (
|
|
"context"
|
|
"knowledge-governance/internal/dobotaiops"
|
|
"knowledge-governance/internal/qaopsquality"
|
|
"net/http"
|
|
"strings"
|
|
)
|
|
|
|
func masterNoStore(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if strings.HasPrefix(r.URL.Path, "/api/v1/qa-ops/master/") || strings.HasPrefix(r.URL.Path, "/api/v1/qa-ops/departments/") {
|
|
w.Header().Set("Cache-Control", "no-store")
|
|
w.Header().Set("Pragma", "no-cache")
|
|
}
|
|
next.ServeHTTP(w, r)
|
|
})
|
|
}
|
|
|
|
// Master reads and reviews own their state; no source client is accepted as fallback.
|
|
type qaMasterStore interface {
|
|
ListMasterRecords(context.Context, dobotaiops.RecordQuery) (dobotaiops.RecordPage, error)
|
|
GetMasterRecord(context.Context, string, string) (dobotaiops.Record, error)
|
|
ReadMasterQualityScope(context.Context, dobotaiops.RecordQuery) (dobotaiops.QualityScope, error)
|
|
MasterQualityStore() *qaopsquality.Store
|
|
}
|
|
type qaMasterReader struct {
|
|
QAOpsReader
|
|
master qaMasterStore
|
|
}
|
|
|
|
func (s qaMasterReader) ListRecords(ctx context.Context, q dobotaiops.RecordQuery) (dobotaiops.RecordPage, error) {
|
|
return s.master.ListMasterRecords(ctx, q)
|
|
}
|
|
func (s qaMasterReader) GetRecord(ctx context.Context, tenant, id string) (dobotaiops.Record, error) {
|
|
return s.master.GetMasterRecord(ctx, tenant, id)
|
|
}
|
|
func (s qaMasterReader) ReadQualityScope(ctx context.Context, q dobotaiops.RecordQuery) (dobotaiops.QualityScope, error) {
|
|
return s.master.ReadMasterQualityScope(ctx, q)
|
|
}
|
|
func (s qaMasterReader) ReadStoredQuality(ctx context.Context, keys []dobotaiops.QualityKey) (map[string]qaopsquality.View, error) {
|
|
if reader, ok := s.master.(interface {
|
|
ReadMasterQualityViews(context.Context, []dobotaiops.QualityKey) (map[string]qaopsquality.View, error)
|
|
}); ok {
|
|
return reader.ReadMasterQualityViews(ctx, keys)
|
|
}
|
|
return s.master.MasterQualityStore().ReadViews(ctx, keys)
|
|
}
|
|
func withQAMaster(w http.ResponseWriter, r *http.Request, c Config, handler func(http.ResponseWriter, *http.Request, Config)) {
|
|
if !authorizeQAOps(w, r) {
|
|
return
|
|
}
|
|
master, ok := c.QAOps.(qaMasterStore)
|
|
if !ok {
|
|
qaOpsError(w, dobotaiops.ErrUnavailable)
|
|
return
|
|
}
|
|
c.QAOps = qaMasterReader{QAOpsReader: c.QAOps, master: master}
|
|
c.QAQuality = master.MasterQualityStore()
|
|
if master.MasterQualityStore() == nil {
|
|
c.QAQuality = nil
|
|
}
|
|
handler(w, r, c)
|
|
}
|