fix(gateway): 报告生成绕过了落库/计费/RBAC —— 生成完就永远找不回
用户实测:报告页输入主题、点生成、看着没反应,切到别的页面再回来,什么都没了。 真相是报告在后端好好地生成完了(26s),是 UI 把它弄丢了、而且永远找不回。 根因:两条提交路径漂移。SubmitTask(POST /tasks) 这一年陆续长出了预算门控/ 计费租户/积分硬拦截/落库/录像五道,而 GenerateReport(POST /reports) 还停在 最初的「发个 NATS」,一道都没有。后果远不止看不到历史: - 不落库 → 运行历史(读 sundynix_task)永远看不到报告。实测修复前该表 report_% 前缀 0 行。 - 无 token/轨迹录像 → SSE 没有回放能力,切走即永久丢失。 - 无 MetaTenantID → 报告用量记不到租户头上 = 漏账。 - 无预算门控/积分硬拦截 → 余额为 0 也能生成,绕过全部成本护栏。 - 路由漏了 RequireTenantRole → **viewer 只读角色能生成报告烧积分**, 而隔壁 /tasks 的注释白纸黑字写着「viewer 只读拦下」。报告一样烧钱。 修法不是把代码抄一份(那只会再漂一次),而是抽两个共用函数: preflight() — 预算 → 计费租户 → 积分硬拦截,返回 billingTenant launch() — 落库 + PublishTask + token/轨迹录像 两条路径都走它们,不可能再各长各的。SubmitTask 行为逐行不变。 live 验证(真账号 blizzardzhang,桌面端实机):生成 report_5dae9155af5cb500 → sundynix_task 建行且带 owner+tenant_id → 出现在运行历史首条 → 点开 完整复盘 8 节点轨迹 + 报告全文。gin 路由表也确认 /reports 中间件数 12 → 13(与 /tasks 齐平)。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -23,6 +23,12 @@ func (h *Handler) GenerateReport(c *gin.Context) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "topic required"})
|
||||
return
|
||||
}
|
||||
// 报告和普通任务一样烧钱,必须过同一道关卡(预算/计费租户/积分硬拦截)。
|
||||
// 此前这里直接 PublishTask,绕过了全部三项。
|
||||
billingTenant, ok := h.preflight(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
id := newReportID()
|
||||
graph, _ := json.Marshal(map[string]any{"topic": body.Topic}) // 占位 DSL,报告编排实际读 Meta
|
||||
task := &contract.Task{
|
||||
@@ -33,10 +39,13 @@ func (h *Handler) GenerateReport(c *gin.Context) {
|
||||
contract.MetaTopic: body.Topic,
|
||||
contract.MetaKB: body.KB,
|
||||
contract.MetaUserID: userID(c),
|
||||
contract.MetaTenantID: billingTenant, // 用量按计费租户扣,此前报告完全没记 → 漏账
|
||||
contract.MetaSessionID: sessionID(c),
|
||||
},
|
||||
}
|
||||
if err := h.bus.PublishTask(c.Request.Context(), task); err != nil {
|
||||
// launch 而非裸 PublishTask:报告也是一次「执行」,要落库(→ 进运行历史、可复盘)
|
||||
// 并开录像(→ SSE 可回放,切走再回来不丢)。
|
||||
if err := h.launch(c, task); err != nil {
|
||||
c.JSON(http.StatusBadGateway, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user