## 现状问题 `internal/httpapi/assistant_workbench.go` 的 `prepareWorkbenchContext`(约 208 行)里,「按存储归属读取当前会话」这一步重复了 5 次,另外同文件 `workspaceTurnContext` 还有 1 次,写法完全一致: ```go h.repo.AssistantSession(assistantStorageOwner(h.repo, req.SessionID, user.ID), req.SessionID) ``` 重复带来的问题: - 同一个会话在一次请求里被从库里读取 5–6 次,每处都要再判空一次,读起来像 6 件不同的事,实际是同一份数据。 - 「共享/项目会话按创建者归属存储,调用者自己的槽位只放私有会话」这条规则散落在各处调用点,新增分支时要靠人记住照抄。 - 历史附件收集(`historicalAttachments`)与「会话属于其他项目」校验各自内联一段循环/判断,进一步拉长了函数。 ## 重构方案 1. 在 `internal/httpapi/assistant_shared.go` 紧邻 `assistantStorageOwner` 新增 `(*assistantHandlers).storedAssistantSession(id string, userID int64) (domain.AssistantSession, bool)`:空 ID 直接返回未找到,其余统一经 `assistantStorageOwner` 定位存储槽位后读取;把归属规则收在一处。 2. `prepareWorkbenchContext` 开头读一次存入 `stored, hasStored`,后续项目归属校验、关联需求、讨论分支、附件作者、子 Agent resume 复用全部改用这份结果,`workspaceTurnContext` 同步改用新 helper。 3. 把历史附件收集抽成纯函数 `historicalAttachmentIDs(session, found, projectID)`,把「非共享且同项目才继承」的注释和判断一起搬进去。 行为完全不变:错误文案、判断顺序、附件覆盖规则、共享会话不继承附件的语义都原样保留。 ## 影响范围 - `internal/httpapi/assistant_shared.go`:新增 1 个 helper。 - `internal/httpapi/assistant_workbench.go`:`prepareWorkbenchContext` 内部 6 处读取收敛为 1 处,抽出 `historicalAttachmentIDs`;`workspaceTurnContext` 改调 helper。 - 新增 `internal/httpapi/assistant_workbench_session_test.go`。 - 不改 HTTP 路由、请求/响应结构、存储层与前端。 ## 验证方式 - `gofmt -l internal/httpapi/` 无输出;`go vet ./internal/httpapi/` 通过。 - `go test ./internal/httpapi/ -count=1`(含新增用例:空 ID / 未知 ID 返回未找到、私有会话其他用户不可读、历史附件只继承同项目非共享会话)。 - 重点回归 `Workbench` 前缀用例(引用作用域、附件私密性、run 上下文不被 @ 改变)。
Activity
Robert0622 commentedon Nov 14, 2026
已对照当前 main 代码核实:
internal/httpapi/assistant_workbench.go的prepareWorkbenchContext内h.repo.AssistantSession(assistantStorageOwner(...), req.SessionID)的读取在 189/196/209/220/317/350 行共 6 处重复,与描述匹配;仓库内未发现storedAssistantSession(grep 无命中),方案与验收标准清晰可执行,非重复。已记入本 Loop 候选,backlog 当前已满(5/5),待腾出名额后建单开发。