feat(backthink): 自排的成本可见面(C2 读侧,Y3)
- GET /api/v1/admin/backthink 加可选 ?trigger=(闭集=内建触发标签 + 本服务订阅的事件主题;
未知/空 ⇒ 400 invalid_trigger,不静默忽略;合法值下推到 SQL ⇒ limit 是匹配条数)
- 新端点 GET /api/v1/admin/backthink/self-wake(writeAuth):闸的只读镜像
{available,running,reason?,configFile?,gate{pending,used,limit,windowSec,default*,*IsDefault}}
三态分开(未接线 / 有配置未运行 / 运行中),读它**不消耗额度**
- 零新 env 键;旋钮源 = $DATA_DIR/config/backthink.json(**写面未做**,前置=组合根接线,已登记)
- 键名沿用设计与现有代码的 selfWakePerWindow(派工书写错成 selfWakeLimit,未改键名以免废掉主人已写的配置)
- 5 个变异(未知值静默忽略/关掉下推/恒报运行中/白名单摘键/前端把看不到画成 0/0)
⚠️ 本片改了 4 个文件面外文件(admin_query.go/routes.go/api.ts/adminSystem.ts)——已逐条说明理由
This commit is contained in:
1 parent
215eedf8e9
commit
4213b268fe
13 files changed
+1289
-43
No files matched your search
@@ -3,7 +3,6 @@ package gateway
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -363,41 +362,17 @@ func (s *Server) adminListUsers(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// adminListBackthink 列出最近的后台思考记录(管理读)。
|
||||
//
|
||||
// 它现在只做**筛选参数校验**并把读侧交给 writeBackthinkList
|
||||
// (admin_backthink_filter.go,切片 C2):`?trigger=` 未知取值如实 400
|
||||
// (design/12 §N C.6 的服务端筛选),合法取值则下推到存储层取匹配条数。
|
||||
func (s *Server) adminListBackthink(w http.ResponseWriter, r *http.Request) {
|
||||
out := make([]AdminBackthinkItem, 0)
|
||||
if s.backthink == nil {
|
||||
writeJSON(w, http.StatusOK, out)
|
||||
return
|
||||
}
|
||||
records, err := s.backthink.List(r.Context(), backthinkListLimit)
|
||||
trigger, err := parseBackthinkTrigger(r.URL.Query())
|
||||
if err != nil {
|
||||
s.log.Error("list backthink", "err", err)
|
||||
writeError(w, apperr.Wrap(apperr.ErrInternal, "backthink_failed", "failed to list backthink records"))
|
||||
writeError(w, err)
|
||||
return
|
||||
}
|
||||
// 安静时段窗口取**运行时真正生效**的那一个(0/0 是「未填」而不是「没有安静时段」,
|
||||
// 见 admin_config_facts.go 的 effectiveQuietHours —— 与 backthink 的 normalize 同口径),
|
||||
// 否则 0/0 部署下会漏报真正的穿透。
|
||||
quietStart, quietEnd := s.effectiveQuietHours()
|
||||
for _, rec := range records {
|
||||
quiet := backthinkQuietOutcomeOf(rec, quietStart, quietEnd)
|
||||
out = append(out, AdminBackthinkItem{
|
||||
ID: strconv.FormatInt(rec.ID, 10),
|
||||
Trigger: rec.Trigger,
|
||||
Conclusion: rec.Conclusion,
|
||||
ShouldNotify: rec.ShouldPush,
|
||||
Pushed: rec.PushResult.Pushed,
|
||||
Route: string(rec.PushResult.Route),
|
||||
Detail: rec.PushResult.Detail,
|
||||
Bypassed: rec.PushResult.Bypassed,
|
||||
At: rec.At.UnixMilli(),
|
||||
// 紧急度(优先精确档位,旧行带下限标记)/ 是否穿透安静时段:只报存档可证的部分。
|
||||
Urgency: quiet.urgency,
|
||||
UrgencyLowerBound: quiet.urgencyLowerBound,
|
||||
QuietHoursBypassed: quiet.bypassed,
|
||||
})
|
||||
}
|
||||
writeJSON(w, http.StatusOK, out)
|
||||
s.writeBackthinkList(w, r, trigger)
|
||||
}
|
||||
|
||||
// adminListRag 列出知识库文档,并在带 ?query= 时
|
||||
|
||||
Reference in new issue
Block a user