Commit Graph
19 Commits
Author SHA1 Message Date
cb0205fcd2 feat(scripts): 跨 owner 懒加载目录树 + 跨用户可见 workspace/public
修两个后端接口问题:
1) /api/v1/workspace-directories 返回为空,目录树结构消失
2) 同 workspace 内脚本/数据互相可见但默认排除 private

后端改动
--------
* list_scripts / list_resources / list_workspace_directories 新增
  owner_user_id 可选 query 参数;缺省 = 当前请求者本人(scope 到
  workspace/{me}/...),传值时 scope 到该 owner 的子树。前端根加载
  默认只见自己一级,其他成员以折叠分组呈现。
* visibility 过滤统一:非 admin 请求者只返回 owner==me 或
  visibility ∈ {workspace, public};admin 跳过。owner=me 含自己
  的 private,owner=other 只剩其 workspace/public,排除他人 private。
* create_workspace_directory 两个分支 visibility 默认 'public'
  (非 private),使跨 owner 目录树可见;响应新增 owner_user_id 字段。
* platform.list_members 鉴权从 system_admin_context 放宽为
  系统管理员或该 workspace 活跃成员(让普通用户也能渲染同
  workspace 成员名册,用于跨 owner 分组)。
* main.py 注册 platform 模块(随 list_members 改动补齐导入)。
* .env.example 同步 common/config.py 26 个字段。

前端改动
--------
* ScriptExplorer.memberScriptGroups 改由 members 列表播种分组,
  display_name 取 members.display_name;inferredDirectories 现在按
  owner_user_id 标记,统一跨 owner 目录渲染。删除脚本目录页头与
  树分组标题的工作副本数量角标。
* WorkspaceTree 新增 ownerUserId 透传到 store.toggleExpanded;
  仅"我"的分组 mount 时 auto-expand,他人分组默认折叠,展开才
  调 loadOwnerGroup / owner-scoped loadScripts / loadChildren。
* scriptWorkspaceStore 引入 namespaced cache key
  (ownerCacheKey = `${ownerUserId ?? me}:${path}`),loadedScriptPaths
  / loadedChildPaths / loadedOwnerGroups 全部按 owner 隔离;
  toggleExpanded 用 loadPath === undefined 区分 group 头与真实
  目录,修"他人子目录点击不触发接口"的 loadPath 前缀误判 bug。
* api.ts / AuthContext 透传 ownerUserId 给 listScripts /
  listResources / listWorkspaceDirectories。

文档
----
* API.md: §3.2 创建目录 visibility 默认 public + 响应加 owner_user_id;
  §3.3.1 GET directories 加 owner_user_id 参数 + 响应字段;
  §3.4 GET scripts 改写为 owner 作用域 + visibility 过滤语义;
  §五.1 GET data-resources 新增,同一套统一语义;
  §7 intro 例外 — GET members 对系统管理员或 workspace 活跃成员开放。
* DEVELOP.md: Code layout 重写以反映 backend api/services/clients/
  schemas 拆分 + schedule domain/scheduling/application/execution/
  infrastructure 拆分 + common 子包(auth/storage/backends);
  Configuration 系统补全 26 个 settings 字段;新增
  "Owner-scoping + visibility (cross-owner browsing)" 小节;
  Per-service dev 注释用 uv run 的源布局要求;Add a new DAG endpoint /
  storage bucket 路径改为 backend/src/backend/api/* 与 services/*。

测试
----
* test_list_scripts_parent_path.py /
  test_resources.py 补充 owner_user_id 参数化直接调用 + LIKE
  前缀断言(workspace/{owner}/... 前缀)。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-02 10:10:41 +08:00
tao.chenandtao.chen a337804700 feat(scripts/data-resources): merge tree + add parent_path filter
- Backend: GET /api/v1/data-resources accepts parent_path; LIKE
  '{ws_id}/%/{escaped}/%' AND NOT LIKE '{ws_id}/%/{escaped}/%/%' on
  StorageObjects.object_key (workspace-wide, escapes _ and %, mirrors
  list_scripts parent_path semantics). 13 new tests in
  test_resources.py (helper unit / SQL compile / SQLite behavioral).
- Frontend: listResources gains parentPath arg, propagated through
  WorkspaceBoundApi + AuthContext binding. WorkspaceTreeGroup title
  count and ScriptExplorer header count now include dataResources.
  memberScriptGroups backfills data-only owners so users with only
  data resources still render a group. loadDataResources accepts an
  optional parentPath, default empty preserves prior behavior.
2026-09-02 10:10:41 +08:00
tao.chenandtao.chen c6ac886133 feat(scripts): GET /api/v1/scripts/count + DashboardRoute wiring
After #34 the workspace store only holds the root-level scripts plus
whatever subfolders the user has expanded. DashboardRoute's
"全部脚本"/"工作副本" counts derived from scripts.length therefore
underreport the workspace total until the user navigates to /scripts
and expands every folder.

Fix: separate count endpoint + dedicated store field, mounted
independently.

Backend — backend/src/backend/scripts.py
- New endpoint GET /api/v1/scripts/count.
- Route declared BEFORE /api/v1/scripts/{script_id}/... so FastAPI's
  declaration-order matching does not interpret "count" as a script_id.
- Returns { data: { total: number }, meta: {} }; SQL is a single
  COUNT(*) on scripts filtered by workspace_id + status='active'.

Frontend — services/api.ts + context/AuthContext.tsx
- countScripts(workspaceId) client; WorkspaceBoundApi gains the field;
  AuthContext binding forwards workspaceId.

Frontend — state/scriptWorkspaceStore.ts
- scriptCount: number | null, scriptCountLoading: boolean.
- loadScriptCount() action: idempotent (no-op while in-flight), silent
  on failure (dashboard tolerates a stale count).
- Initial state and reset() clear both fields.

Frontend — features/platform/DashboardRoute.tsx
- Subscribes to scriptCount; calls loadScriptCount() on mount.
- Falls back to scripts.length until the count resolves so the
  dashboard never blanks.

Tests — backend/tests/test_count_scripts.py (new)
- 3 unit tests: scalar result handling, NULL coercion, route callable.

Verified: pytest 55 passed (52 + 3 new); pnpm typecheck clean.
2026-09-02 10:10:41 +08:00
tao.chenandtao.chen 96aaa7bb64 fix(scripts): AuthContext binding + load() cache invalidation (Codex review)
Codex (deepseek-v4-flash) review of feat(scripts) parent_path filter
surfaced four problems:

1. Critical — AuthContext listScripts binding silently dropped parentPath
   - frontend/app/context/AuthContext.tsx:224 had:
       listScripts: () => rawApi.listScripts(workspaceId)
     so loadScripts("foo/bar") hit GET /api/v1/scripts with no query and
     always received root-level scripts. Typecheck passed because
     `() => ...` is assignable to `(parentPath?: string) => ...`.
   - Fix: forward the parentPath argument.

2. High — load() cache invalidation gap on toolbar refresh / create / delete
   - load() replaced `scripts` with root-only items but never invalidated
     `loadedScriptPaths` for subfolders, so previously-expanded folders
     rendered empty (cached no-op on re-expand) and open tabs pointing
     into subfolders were dropped by the validIds filter.
   - Fix: load() now re-fetches every path currently in
     loadedScriptPaths (and loadedChildPaths for directories), then
     dedups by id/path. On initial mount the cache is empty so this
     degrades to a single root fetch.

3. Low — test docstring overclaimed coverage
   - The "actual ORM roundtrip is covered by the existing integration
     tests" line is false (no other list_scripts test exists).
   - Fix: honest docstring noting the repo has no endpoint integration
     test layer; SQL assertions are brittle to SQLAlchemy/dialect
     formatting.

4. Low — backend docstring overclaimed index role
   - Claimed `idx_storage_workspace_relative_path` "avoided全表扫", but
     the index isn't declared in the ORM model, only exists via the
     baseline migration's upgrade path, and EXPLAIN doesn't drive
     through it (scripts-first plan via idx_scripts_workspace).
   - Fix: accurate description — MySQL drives via idx_scripts_workspace,
     storage_objects PK lookup applies LIKE per row. Notes where to
     optimize if 10万-scale perf becomes a real problem.

Skipped findings (out of scope):
- Medium LIKE escape for `_` / `%` (pre-existing in
  list_workspace_directories; not introduced here).
- Low dashboard `scripts.length` count underreport (separate UI bug,
  pre-existing assumption that broke under the new semantics).

Verified: pytest 50 passed, pnpm typecheck clean.
2026-09-02 10:10:41 +08:00
Winnie bc62034241 feat: improve schedule cleanup and handover 2026-08-20 19:12:44 +08:00
tao.chen 65d14b8610 update: dir tree 2026-08-14 15:02:55 +08:00
tao.chen 480e1cc638 update: data source 2026-08-14 11:59:06 +08:00
tao.chen c6c2481b96 feat: workspace 目录树服务端懒加载
- api.ts: listWorkspaceDirectories 支持 parent_path 查询; WorkspaceDirectory 增加 has_children; 同步 WorkspaceBoundApi 签名
- AuthContext: 绑定透传 parentPath
- scriptWorkspaceStore: 新增 expandedPaths/loadingChildrenPaths/loadedChildPaths, loadChildren/toggleExpanded, 局部刷新 createFolder/deleteDirectory
- WorkspaceTree: 移除 useState, 改为受控展开/加载状态
- ScriptExplorer: 从 store 读取并透传展开状态与 toggle
2026-08-12 18:06:35 +08:00
tao.chen dd6f176ca8 fix: file lock 2026-08-11 21:26:55 +08:00
xiaozhu 064403ad70 fix:新建项目更新项目选项 2026-08-11 18:53:11 +08:00
xiaozhu f90d15bbe9 update:系统管理 2026-08-07 18:08:16 +08:00
Winnie cec6a4468e Merge remote-tracking branch 'origin/develop' into develop 2026-08-05 17:49:29 +08:00
Winnie 2bfe43a63f Merge branch 'develop' of http://8.153.151.51:8888/team_group/model-develop into develop 2026-08-05 17:46:05 +08:00
tao.chen 8519393895 update: admin valid 2026-08-05 17:10:36 +08:00
Winnie 30cde4a56c 添加查看调度运行结果 2026-08-05 16:34:35 +08:00
xiaozhu 394081b613 feat:项目管理 2026-08-05 13:50:24 +08:00
tao.chen 94a1aef7c7 fix: script not found 2026-08-04 14:24:55 +08:00
tao.chen e18a7a34a3 update: save version 2026-08-04 13:35:16 +08:00
Winnie d7bd88335c merge: integrate feat/auth into develop 2026-08-03 17:44:00 +08:00