[P0] list_scripts 空数组回归:workspace-wide 前缀漏 user_id 通配 #34

Closed
opened 2026-08-21 16:20:06 +08:00 by tao.chen · 3 comments
Owner

症状

  • 脚本目录里所有 scripts 消失;GET /api/v1/scripts 返回空数组
  • GET /api/v1/scripts/count 正常(数据库 16 个 active,非 0)
  • 数据库无问题:16 active scripts,current_object_id 全部合法

根因(已用真实 DB 验证)

提交 d68055a(2026-08-21, align list_scripts visibility with list_resources)把
list_scripts 改成 workspace-wide,但漏了 owner 段通配。

  • 物理布局:storage_objects.relative_path = workspace/{user_id}/{parent}/{basename}
    (写入侧 create_script_record 确认;DB 实测 16 条全部符合)
  • 新 helper _build_list_scripts_workspace_descendant_prefix("") 返回 workspace/
  • 查询:LIKE 'workspace/%' AND NOT LIKE 'workspace/%/%'(取直接子节点)
  • 真实脚本是 workspace/{user_id}/xxx(workspace 下第 2 层),全部命中
    workspace/%/% 被 NOT 排除 → 16 active 返回 0

对照组 list_resources(69a9a48,正确实现)用的是
LIKE '{ws_id}/%/{parent}/%' — 中间的 % 通配 owner_user_id 段。
scripts 端抄的时候把这段通配丢了。

测试为何没拦住

  • SQL 契约测试只断言编译后的 SQL 字符串包含 like 'workspace/foo/bar/%'
    (检查"前缀被发出",不检查真实数据能否命中)
  • 无任何测试用真实物理布局 workspace/{user_id}/basename(2 层孙节点)
    验证根目录 list 能返回

修复(镜像 list_resources)

  • helper 改为返回 parent-relative 转义前缀(与 resources 对称)
  • list_scripts: LIKE 'workspace/%/{parent}/%' AND NOT LIKE 'workspace/%/{parent}/%/%'
  • count_scripts: 保持全量后代统计,更新为 workspace/%/%
  • 补回归测试:真实物理布局根目录能列出

验收

  • 16 个 active scripts 全部回到 /scripts
  • 根目录只列直接子节点;subdir parent_path 正确
  • pytest 全绿;编译零错
  • 不破坏 #34 懒加载语义、不破坏 list_resources

Task: pcu5nn8xbxtno5w7cb5zzaj6

## 症状 - 脚本目录里所有 scripts 消失;`GET /api/v1/scripts` 返回空数组 - `GET /api/v1/scripts/count` 正常(数据库 16 个 active,非 0) - 数据库无问题:16 active scripts,current_object_id 全部合法 ## 根因(已用真实 DB 验证) 提交 `d68055a`(2026-08-21, align list_scripts visibility with list_resources)把 `list_scripts` 改成 workspace-wide,但漏了 owner 段通配。 - 物理布局:`storage_objects.relative_path = workspace/{user_id}/{parent}/{basename}` (写入侧 create_script_record 确认;DB 实测 16 条全部符合) - 新 helper `_build_list_scripts_workspace_descendant_prefix("")` 返回 `workspace/` - 查询:`LIKE 'workspace/%'` AND NOT `LIKE 'workspace/%/%'`(取直接子节点) - 真实脚本是 `workspace/{user_id}/xxx`(workspace 下第 2 层),全部命中 `workspace/%/%` 被 NOT 排除 → 16 active 返回 0 对照组 `list_resources`(69a9a48,正确实现)用的是 `LIKE '{ws_id}/%/{parent}/%'` — 中间的 `%` 通配 owner_user_id 段。 scripts 端抄的时候把这段通配丢了。 ## 测试为何没拦住 - SQL 契约测试只断言编译后的 SQL 字符串包含 `like 'workspace/foo/bar/%'` (检查"前缀被发出",不检查真实数据能否命中) - 无任何测试用真实物理布局 `workspace/{user_id}/basename`(2 层孙节点) 验证根目录 list 能返回 ## 修复(镜像 list_resources) - helper 改为返回 parent-relative 转义前缀(与 resources 对称) - list_scripts: `LIKE 'workspace/%/{parent}/%'` AND NOT `LIKE 'workspace/%/{parent}/%/%'` - count_scripts: 保持全量后代统计,更新为 `workspace/%/%` - 补回归测试:真实物理布局根目录能列出 ## 验收 - 16 个 active scripts 全部回到 /scripts - 根目录只列直接子节点;subdir parent_path 正确 - pytest 全绿;编译零错 - 不破坏 #34 懒加载语义、不破坏 list_resources --- <sub>Task: pcu5nn8xbxtno5w7cb5zzaj6</sub>
Author
Owner
[MODEL-DEVELOP-PLATFORM-58](https://kaneo.maimaicuizhiji.top/dashboard/workspace/UVjqrB68D9jAIx4sh6ucRfsPbbUCj97c/project/hna942mjy8cwyv1o77mw0cnv/task/zslzs60lp5g1l20yuxwmooym)
tao.chen added the priority:urgentstatus:in-progress labels 2026-08-21 16:20:09 +08:00
Author
Owner

tao.chen commented:

修复完成 — Codex 实现 + CC review + 真实 DB 端到端验证

改动(3 文件,镜像 list_resources 69a9a48% owner 通配):

  • api/scripts.py:_build_list_scripts_workspace_descendant_prefix 改回 parent-relative;list_scripts LIKE 改 workspace/%/{parent}/% AND NOT .../%/%;count_scriptsworkspace/%/%
  • test_list_scripts_parent_path.py / test_count_scripts.py:helper 单测 + SQL 契约断言更新,新增行为回归测试(真实物理布局 workspace/{uid}/root.py 根目录能列出、排除 sub/deep.py)

验证:

  • pytest 触达文件 32 passed;全量 123 passed;compileall 零错误
  • 真实 DB(workspace ...02)端到端:根目录 list 0 → 10,count 12(含子目录 2 个,符合懒加载语义);旧模式 0
  • 未提交(按 CLAUDE.md,等用户指示)

为什么测试之前没拦住:SQL 契约测试只断言编译后字符串包含 workspace/foo/bar/%(检查前缀被发出,不检查真实数据命中);无测试用真实 2 层孙节点布局验证根目录。已补。

**tao.chen** commented: > ## 修复完成 — Codex 实现 + CC review + 真实 DB 端到端验证 **改动**(3 文件,镜像 list_resources 69a9a48 的 `%` owner 通配): - `api/scripts.py`:`_build_list_scripts_workspace_descendant_prefix` 改回 parent-relative;`list_scripts` LIKE 改 `workspace/%/{parent}/%` AND NOT `.../%/%`;`count_scripts` 改 `workspace/%/%` - `test_list_scripts_parent_path.py` / `test_count_scripts.py`:helper 单测 + SQL 契约断言更新,新增行为回归测试(真实物理布局 `workspace/{uid}/root.py` 根目录能列出、排除 `sub/deep.py`) **验证**: - pytest 触达文件 32 passed;全量 123 passed;compileall 零错误 - 真实 DB(workspace ...02)端到端:根目录 list 0 → **10**,count 12(含子目录 2 个,符合懒加载语义);旧模式 0 - 未提交(按 CLAUDE.md,等用户指示) **为什么测试之前没拦住**:SQL 契约测试只断言编译后字符串包含 `workspace/foo/bar/%`(检查前缀被发出,不检查真实数据命中);无测试用真实 2 层孙节点布局验证根目录。已补。
tao.chen added status:done and removed status:in-progress labels 2026-08-21 16:25:59 +08:00
tao.chen added the status:in-review label 2026-08-21 16:26:05 +08:00
tao.chen added status:archived and removed status:done labels 2026-08-24 10:09:09 +08:00
tao.chen reopened this issue 2026-08-24 10:09:14 +08:00
tao.chen added the status:to-do label 2026-08-24 10:09:35 +08:00
Author
Owner

tao.chen commented:

Archived as duplicate

This task is a duplicate of #57 (same gitea #34). #57 stays in to-do as the canonical tracker; this copy is archived.

**tao.chen** commented: > ## Archived as duplicate This task is a duplicate of **#57** (same gitea #34). #57 stays in to-do as the canonical tracker; this copy is archived.
tao.chen removed the status:to-do label 2026-08-24 14:23:31 +08:00
tao.chen added status:done and removed status:in-review labels 2026-08-24 14:24:56 +08:00
tao.chen reopened this issue 2026-08-24 14:25:31 +08:00
tao.chen added the status:to-do label 2026-08-24 14:25:44 +08:00
tao.chen removed the status:to-do label 2026-08-24 14:51:01 +08:00
Sign in to join this conversation.