From cdd9d6701f01216ef21f8a5f75d9541004d24383 Mon Sep 17 00:00:00 2001 From: 1445043649 <> Date: Sun, 28 Jun 2026 20:49:34 +0800 Subject: [PATCH] docs(stage-1): tick all plan checkboxes to match landed commits (Stage 1) Co-Authored-By: Claude Opus 4.8 (1M context) --- ...-headless-api-pattern-a-auth-foundation.md | 152 +++++++++--------- 1 file changed, 76 insertions(+), 76 deletions(-) diff --git a/docs/superpowers/plans/2026-06-28-stage-1-headless-api-pattern-a-auth-foundation.md b/docs/superpowers/plans/2026-06-28-stage-1-headless-api-pattern-a-auth-foundation.md index 7bb38bc2..5aaf26c7 100644 --- a/docs/superpowers/plans/2026-06-28-stage-1-headless-api-pattern-a-auth-foundation.md +++ b/docs/superpowers/plans/2026-06-28-stage-1-headless-api-pattern-a-auth-foundation.md @@ -73,7 +73,7 @@ - Create: `backend/packages/harness/deerflow/auth/tokens.py` - Test: `backend/tests/test_tokens.py` -- [ ] **Step 1: 写失败测试** +- [x] **Step 1: 写失败测试** Create `backend/tests/test_tokens.py`: @@ -136,12 +136,12 @@ def test_split_prefix_takes_first_16(): assert split_prefix("dfk_live_abcdefghijklmnop") == "dfk_live_abcdefg" ``` -- [ ] **Step 2: 跑测试确认失败** +- [x] **Step 2: 跑测试确认失败** Run: `cd backend && PYTHONPATH=. uv run pytest tests/test_tokens.py -v` Expected: FAIL — `ModuleNotFoundError: No module named 'deerflow.auth'` -- [ ] **Step 3: 写实现** +- [x] **Step 3: 写实现** Create `backend/packages/harness/deerflow/auth/__init__.py`: @@ -217,12 +217,12 @@ def generate_api_key(env: Literal["live", "test"]) -> GeneratedKey: return GeneratedKey(plaintext=plaintext, prefix=split_prefix(plaintext), key_hash=hash_api_key(plaintext)) ``` -- [ ] **Step 4: 跑测试确认通过** +- [x] **Step 4: 跑测试确认通过** Run: `cd backend && PYTHONPATH=. uv run pytest tests/test_tokens.py -v` Expected: PASS(6 tests) -- [ ] **Step 5: commit** +- [x] **Step 5: commit** ```bash cd backend && git add packages/harness/deerflow/auth/ tests/test_tokens.py @@ -238,7 +238,7 @@ Co-Authored-By: Claude Opus 4.8 (1M context) " - Modify: `backend/packages/harness/deerflow/persistence/service_account/__init__.py` - Test: `backend/tests/test_service_account_repo.py` -- [ ] **Step 1: 写失败测试** +- [x] **Step 1: 写失败测试** Create `backend/tests/test_service_account_repo.py`: @@ -342,12 +342,12 @@ async def test_list_by_workspace(tmp_path): await _cleanup() ``` -- [ ] **Step 2: 跑测试确认失败** +- [x] **Step 2: 跑测试确认失败** Run: `cd backend && PYTHONPATH=. uv run pytest tests/test_service_account_repo.py -v` Expected: FAIL — `ImportError: cannot import name 'ServiceAccountRepository'` -- [ ] **Step 3: 写实现** +- [x] **Step 3: 写实现** Create `backend/packages/harness/deerflow/persistence/service_account/sql.py`: @@ -467,12 +467,12 @@ from deerflow.persistence.service_account.sql import ServiceAccountRepository __all__ = ["ServiceAccountRepository", "ServiceAccountRow"] ``` -- [ ] **Step 4: 跑测试确认通过** +- [x] **Step 4: 跑测试确认通过** Run: `cd backend && PYTHONPATH=. uv run pytest tests/test_service_account_repo.py -v` Expected: PASS(4 tests) -- [ ] **Step 5: commit** +- [x] **Step 5: commit** ```bash cd backend && git add packages/harness/deerflow/persistence/service_account/ tests/test_service_account_repo.py @@ -488,7 +488,7 @@ Co-Authored-By: Claude Opus 4.8 (1M context) " - Modify: `backend/packages/harness/deerflow/persistence/api_key/__init__.py` - Test: `backend/tests/test_api_key_repo.py` -- [ ] **Step 1: 写失败测试** +- [x] **Step 1: 写失败测试** Create `backend/tests/test_api_key_repo.py`: @@ -635,12 +635,12 @@ async def test_list_by_service_account(tmp_path): await _cleanup() ``` -- [ ] **Step 2: 跑测试确认失败** +- [x] **Step 2: 跑测试确认失败** Run: `cd backend && PYTHONPATH=. uv run pytest tests/test_api_key_repo.py -v` Expected: FAIL — `ImportError: cannot import name 'ApiKeyRepository'` -- [ ] **Step 3: 写实现** +- [x] **Step 3: 写实现** Create `backend/packages/harness/deerflow/persistence/api_key/sql.py`: @@ -773,12 +773,12 @@ from deerflow.persistence.api_key.sql import ApiKeyRepository __all__ = ["ApiKeyRepository", "ApiKeyRow"] ``` -- [ ] **Step 4: 跑测试确认通过** +- [x] **Step 4: 跑测试确认通过** Run: `cd backend && PYTHONPATH=. uv run pytest tests/test_api_key_repo.py -v` Expected: PASS(7 tests) -- [ ] **Step 5: commit** +- [x] **Step 5: commit** ```bash cd backend && git add packages/harness/deerflow/persistence/api_key/ tests/test_api_key_repo.py @@ -796,7 +796,7 @@ Co-Authored-By: Claude Opus 4.8 (1M context) " > 本 PR 只建仓储(读方法 + upsert 骨架),**不接任何鉴权调用方**——透传逻辑留到轨道二后续 PR,与 PR8 建 schema 不接路由同思路(spec §5 PR1)。 -- [ ] **Step 1: 写失败测试** +- [x] **Step 1: 写失败测试** Create `backend/tests/test_external_user_repo.py`: @@ -880,12 +880,12 @@ async def test_get_by_external_id(tmp_path): await _cleanup() ``` -- [ ] **Step 2: 跑测试确认失败** +- [x] **Step 2: 跑测试确认失败** Run: `cd backend && PYTHONPATH=. uv run pytest tests/test_external_user_repo.py -v` Expected: FAIL — `ImportError: cannot import name 'ExternalUserRepository'` -- [ ] **Step 3: 写实现** +- [x] **Step 3: 写实现** Create `backend/packages/harness/deerflow/persistence/external_user/sql.py`: @@ -1001,12 +1001,12 @@ from deerflow.persistence.external_user.sql import ExternalUserRepository __all__ = ["ExternalUserRepository", "ExternalUserRow"] ``` -- [ ] **Step 4: 跑测试确认通过** +- [x] **Step 4: 跑测试确认通过** Run: `cd backend && PYTHONPATH=. uv run pytest tests/test_external_user_repo.py -v` Expected: PASS(2 tests) -- [ ] **Step 5: PR1 收尾 — lint + boundary + commit** +- [x] **Step 5: PR1 收尾 — lint + boundary + commit** Run boundary + lint(PR1 全在 deerflow 层,必须不引入 app import): @@ -1036,7 +1036,7 @@ Co-Authored-By: Claude Opus 4.8 (1M context) " - Create: `backend/app/gateway/auth/api_key_backend.py`(本 task 只放 `ServicePrincipal` + `parse_scopes`,backend 类在 Task 2.2) - Test: `backend/tests/test_api_key_backend.py`(本 task 只测 parse_scopes + principal) -- [ ] **Step 1: 写失败测试** +- [x] **Step 1: 写失败测试** Create `backend/tests/test_api_key_backend.py`: @@ -1067,12 +1067,12 @@ def test_service_principal_is_service_account_true_by_default(): assert p.is_service_account is True ``` -- [ ] **Step 2: 跑测试确认失败** +- [x] **Step 2: 跑测试确认失败** Run: `cd backend && PYTHONPATH=. uv run pytest tests/test_api_key_backend.py -v` Expected: FAIL — `ModuleNotFoundError: No module named 'app.gateway.auth.api_key_backend'` -- [ ] **Step 3: 写实现** +- [x] **Step 3: 写实现** Modify `backend/packages/harness/deerflow/runtime/user_context.py` — add the `is_service_account` attribute to the `CurrentUser` protocol. Change: @@ -1157,12 +1157,12 @@ def parse_scopes(scopes: str) -> list[str]: return [s.strip() for s in scopes.split(",") if s.strip()] ``` -- [ ] **Step 4: 跑测试确认通过** +- [x] **Step 4: 跑测试确认通过** Run: `cd backend && PYTHONPATH=. uv run pytest tests/test_api_key_backend.py -v` Expected: PASS(4 tests) -- [ ] **Step 5: commit** +- [x] **Step 5: commit** ```bash cd backend && git add packages/harness/deerflow/runtime/user_context.py app/gateway/auth/models.py app/gateway/auth/api_key_backend.py tests/test_api_key_backend.py @@ -1177,7 +1177,7 @@ Co-Authored-By: Claude Opus 4.8 (1M context) " - Modify: `backend/app/gateway/auth/api_key_backend.py` - Test: `backend/tests/test_api_key_backend.py`(追加 authenticate 测试) -- [ ] **Step 1: 写失败测试**(追加到 `test_api_key_backend.py` 末尾) +- [x] **Step 1: 写失败测试**(追加到 `test_api_key_backend.py` 末尾) ```python import pytest @@ -1277,12 +1277,12 @@ async def test_authenticate_suspended_workspace_returns_none(tmp_path): await _cleanup() ``` -- [ ] **Step 2: 跑测试确认失败** +- [x] **Step 2: 跑测试确认失败** Run: `cd backend && PYTHONPATH=. uv run pytest tests/test_api_key_backend.py -v` Expected: FAIL — `ImportError: cannot import name 'APIKeyAuthBackend'` -- [ ] **Step 3: 写实现** — append to `backend/app/gateway/auth/api_key_backend.py`: +- [x] **Step 3: 写实现** — append to `backend/app/gateway/auth/api_key_backend.py`: ```python from deerflow.auth.tokens import hash_api_key, split_prefix @@ -1351,12 +1351,12 @@ def build_api_key_backend() -> APIKeyAuthBackend | None: return APIKeyAuthBackend(api_key_repo=ApiKeyRepository(sf), service_account_repo=ServiceAccountRepository(sf), workspace_repo=WorkspaceRepository(sf)) ``` -- [ ] **Step 4: 跑测试确认通过** +- [x] **Step 4: 跑测试确认通过** Run: `cd backend && PYTHONPATH=. uv run pytest tests/test_api_key_backend.py -v` Expected: PASS(9 tests) -- [ ] **Step 5: commit** +- [x] **Step 5: commit** ```bash cd backend && git add app/gateway/auth/api_key_backend.py tests/test_api_key_backend.py @@ -1371,7 +1371,7 @@ Co-Authored-By: Claude Opus 4.8 (1M context) " - Modify: `backend/app/gateway/auth_middleware.py` - Test: `backend/tests/test_auth_middleware_api_key.py` -- [ ] **Step 1: 写失败测试** +- [x] **Step 1: 写失败测试** Create `backend/tests/test_auth_middleware_api_key.py`: @@ -1496,12 +1496,12 @@ async def test_non_dfk_bearer_falls_through_to_cookie_path(tmp_path): await _cleanup() ``` -- [ ] **Step 2: 跑测试确认失败** +- [x] **Step 2: 跑测试确认失败** Run: `cd backend && PYTHONPATH=. uv run pytest tests/test_auth_middleware_api_key.py -v` Expected: FAIL — `test_valid_bearer_sets_sa_contextvars` returns 401(bearer 分支尚未实现) -- [ ] **Step 3: 写实现** — modify `backend/app/gateway/auth_middleware.py`. +- [x] **Step 3: 写实现** — modify `backend/app/gateway/auth_middleware.py`. Add imports near the top (after the existing `from app.gateway.auth.models import ActiveWorkspace`): @@ -1553,12 +1553,12 @@ to: internal_user = None ``` -- [ ] **Step 4: 跑测试确认通过** +- [x] **Step 4: 跑测试确认通过** Run: `cd backend && PYTHONPATH=. uv run pytest tests/test_auth_middleware_api_key.py -v` Expected: PASS(4 tests) -- [ ] **Step 5: cookie 路径回归 + lint + commit** +- [x] **Step 5: cookie 路径回归 + lint + commit** Run the existing middleware regression to prove the cookie path is untouched: @@ -1586,7 +1586,7 @@ Co-Authored-By: Claude Opus 4.8 (1M context) " - Modify: `backend/app/gateway/csrf_middleware.py` - Test: `backend/tests/test_csrf_bearer.py` -- [ ] **Step 1: 写失败测试** +- [x] **Step 1: 写失败测试** Create `backend/tests/test_csrf_bearer.py`: @@ -1642,12 +1642,12 @@ def test_has_bearer_header_detection(): assert has_bearer_header(_req({})) is False ``` -- [ ] **Step 2: 跑测试确认失败** +- [x] **Step 2: 跑测试确认失败** Run: `cd backend && PYTHONPATH=. uv run pytest tests/test_csrf_bearer.py -v` Expected: FAIL — `test_bearer_post_skips_csrf` returns 403;`has_bearer_header` ImportError -- [ ] **Step 3: 写实现** — modify `backend/app/gateway/csrf_middleware.py`. +- [x] **Step 3: 写实现** — modify `backend/app/gateway/csrf_middleware.py`. Add `has_bearer_header` after `should_check_csrf`, and call it inside `should_check_csrf`. Change: @@ -1700,12 +1700,12 @@ def should_check_csrf(request: Request) -> bool: return True ``` -- [ ] **Step 4: 跑测试确认通过** +- [x] **Step 4: 跑测试确认通过** Run: `cd backend && PYTHONPATH=. uv run pytest tests/test_csrf_bearer.py tests/test_csrf_middleware.py -v` Expected: PASS(new 3 + existing csrf suite unchanged) -- [ ] **Step 5: lint + commit** +- [x] **Step 5: lint + commit** ```bash cd backend && make lint && git add app/gateway/csrf_middleware.py tests/test_csrf_bearer.py @@ -1726,7 +1726,7 @@ Co-Authored-By: Claude Opus 4.8 (1M context) " - Modify: `backend/app/gateway/authz.py` - Test: `backend/tests/test_require_workspace_admin.py` -- [ ] **Step 1: 写失败测试** +- [x] **Step 1: 写失败测试** Create `backend/tests/test_require_workspace_admin.py`: @@ -1783,12 +1783,12 @@ def test_rejects_no_workspace(): assert exc.value.status_code == 403 ``` -- [ ] **Step 2: 跑测试确认失败** +- [x] **Step 2: 跑测试确认失败** Run: `cd backend && PYTHONPATH=. uv run pytest tests/test_require_workspace_admin.py -v` Expected: FAIL — `ImportError: cannot import name 'require_workspace_admin'` -- [ ] **Step 3: 写实现** — append to `backend/app/gateway/authz.py`: +- [x] **Step 3: 写实现** — append to `backend/app/gateway/authz.py`: ```python def require_workspace_admin() -> None: @@ -1806,12 +1806,12 @@ def require_workspace_admin() -> None: raise HTTPException(status_code=403, detail="workspace owner/admin role required") ``` -- [ ] **Step 4: 跑测试确认通过** +- [x] **Step 4: 跑测试确认通过** Run: `cd backend && PYTHONPATH=. uv run pytest tests/test_require_workspace_admin.py -v` Expected: PASS(4 tests) -- [ ] **Step 5: commit** +- [x] **Step 5: commit** ```bash cd backend && git add app/gateway/authz.py tests/test_require_workspace_admin.py @@ -1829,7 +1829,7 @@ Co-Authored-By: Claude Opus 4.8 (1M context) " > Router 依赖工厂:用 `Depends(get_service_account_repo)` 从全局 session factory 构造仓储,便于测试覆写。`workspace_id` 从 `get_current_workspace()` 读,`created_by` 从 `request.state.user.id` 读。 -- [ ] **Step 1: 写失败测试** +- [x] **Step 1: 写失败测试** Create `backend/tests/test_service_accounts_router.py`: @@ -1959,12 +1959,12 @@ async def test_patch_other_workspace_sa_404(tmp_path): await _cleanup() ``` -- [ ] **Step 2: 跑测试确认失败** +- [x] **Step 2: 跑测试确认失败** Run: `cd backend && PYTHONPATH=. uv run pytest tests/test_service_accounts_router.py -v` Expected: FAIL — `ImportError: cannot import name 'service_accounts'` -- [ ] **Step 3: 写实现** +- [x] **Step 3: 写实现** Create `backend/app/gateway/routers/service_accounts.py`: @@ -2060,12 +2060,12 @@ Modify `backend/app/gateway/app.py` — add to the router import block and regis app.include_router(service_accounts.router) ``` -- [ ] **Step 4: 跑测试确认通过** +- [x] **Step 4: 跑测试确认通过** Run: `cd backend && PYTHONPATH=. uv run pytest tests/test_service_accounts_router.py -v` Expected: PASS(4 tests) -- [ ] **Step 5: commit** +- [x] **Step 5: commit** ```bash cd backend && git add app/gateway/routers/service_accounts.py app/gateway/app.py tests/test_service_accounts_router.py @@ -2081,7 +2081,7 @@ Co-Authored-By: Claude Opus 4.8 (1M context) " - Modify: `backend/app/gateway/app.py`(import + include_router) - Test: `backend/tests/test_api_keys_router.py` -- [ ] **Step 1: 写失败测试** +- [x] **Step 1: 写失败测试** Create `backend/tests/test_api_keys_router.py`: @@ -2213,12 +2213,12 @@ async def test_member_cannot_create_key(tmp_path): await _cleanup() ``` -- [ ] **Step 2: 跑测试确认失败** +- [x] **Step 2: 跑测试确认失败** Run: `cd backend && PYTHONPATH=. uv run pytest tests/test_api_keys_router.py -v` Expected: FAIL — `ImportError: cannot import name 'api_keys'` -- [ ] **Step 3: 写实现** +- [x] **Step 3: 写实现** Create `backend/app/gateway/routers/api_keys.py`: @@ -2342,12 +2342,12 @@ Modify `backend/app/gateway/app.py` — add `api_keys` to the router import grou app.include_router(api_keys.router) ``` -- [ ] **Step 4: 跑测试确认通过** +- [x] **Step 4: 跑测试确认通过** Run: `cd backend && PYTHONPATH=. uv run pytest tests/test_api_keys_router.py -v` Expected: PASS(4 tests) -- [ ] **Step 5: commit** +- [x] **Step 5: commit** ```bash cd backend && git add app/gateway/routers/api_keys.py app/gateway/app.py tests/test_api_keys_router.py @@ -2363,7 +2363,7 @@ Co-Authored-By: Claude Opus 4.8 (1M context) " > 地基的"活体证明"(spec §7):owner 建 SA → 建 key → 用 key 经真实 `AuthMiddleware` 调一个 owner_check 探针路由 → 跨 workspace key 得 404。把全链路(中间件 + 仓储 + 管理 endpoint)串起来。 -- [ ] **Step 1: 写失败测试** +- [x] **Step 1: 写失败测试** Create `backend/tests/test_headless_api_smoke.py`: @@ -2481,12 +2481,12 @@ async def test_mint_use_and_cross_workspace_isolation(tmp_path): await _cleanup() ``` -- [ ] **Step 2: 跑测试确认失败 / 通过** +- [x] **Step 2: 跑测试确认失败 / 通过** Run: `cd backend && PYTHONPATH=. uv run pytest tests/test_headless_api_smoke.py -v` Expected: PASS(如果 PR2+PR4 实现正确,本 smoke 直接 green;若 FAIL 按报错修对应实现) -- [ ] **Step 3: PR4 收尾 — 全量回归 + lint + commit** +- [x] **Step 3: PR4 收尾 — 全量回归 + lint + commit** ```bash cd backend && make lint && make test @@ -2513,7 +2513,7 @@ Co-Authored-By: Claude Opus 4.8 (1M context) " - Modify: `backend/app/gateway/app.py`(add_middleware) - Test: `backend/tests/test_api_deprecation_header.py` -- [ ] **Step 1: 写失败测试** +- [x] **Step 1: 写失败测试** Create `backend/tests/test_api_deprecation_header.py`: @@ -2566,12 +2566,12 @@ def test_langgraph_path_no_header(): assert "X-API-Deprecated" not in r.headers ``` -- [ ] **Step 2: 跑测试确认失败** +- [x] **Step 2: 跑测试确认失败** Run: `cd backend && PYTHONPATH=. uv run pytest tests/test_api_deprecation_header.py -v` Expected: FAIL — `ModuleNotFoundError: No module named 'app.gateway.deprecation_middleware'` -- [ ] **Step 3: 写实现** +- [x] **Step 3: 写实现** Create `backend/app/gateway/deprecation_middleware.py`: @@ -2617,12 +2617,12 @@ Modify `backend/app/gateway/app.py` — register the middleware. Find where `app app.add_middleware(ApiDeprecationMiddleware) ``` -- [ ] **Step 4: 跑测试确认通过** +- [x] **Step 4: 跑测试确认通过** Run: `cd backend && PYTHONPATH=. uv run pytest tests/test_api_deprecation_header.py -v` Expected: PASS(3 tests) -- [ ] **Step 5: commit** +- [x] **Step 5: commit** ```bash cd backend && git add app/gateway/deprecation_middleware.py app/gateway/app.py tests/test_api_deprecation_header.py @@ -2640,7 +2640,7 @@ Co-Authored-By: Claude Opus 4.8 (1M context) " > 做法:每个 router 的 `APIRouter(prefix="/api/...")` 改成去掉 `/api` 前缀的相对前缀(如 `/api/models` → `/models`,`/api/threads/{thread_id}/uploads` → `/threads/{thread_id}/uploads`);在 `app.py` 中每个 router `include_router(x.router, prefix="/api")` + `include_router(x.router, prefix="/api/v1")` 双挂。逐个改 + 每改一个跑该域已有测试,避免一次性全断。 -- [ ] **Step 1: 写失败测试**(先写双挂断言,红) +- [x] **Step 1: 写失败测试**(先写双挂断言,红) Create `backend/tests/test_api_v1_dual_mount.py`: @@ -2696,12 +2696,12 @@ def test_langgraph_not_versioned(): > 注:`create_app` 的确切签名见 `app/gateway/app.py`(搜索 `def create_app`)。若它需要参数,按现有 `tests/` 中调用 `create_app` 的方式(grep `create_app(` in tests)对齐。若部分路由路径名(如 `/uploads/list`)与实际不符,先 grep 实际 `@router.get` 路径再校正断言字符串。 -- [ ] **Step 2: 跑测试确认失败** +- [x] **Step 2: 跑测试确认失败** Run: `cd backend && PYTHONPATH=. uv run pytest tests/test_api_v1_dual_mount.py -v` Expected: FAIL — `/api/v1/models` etc. not in paths(尚未双挂) -- [ ] **Step 3: 写实现** — 逐 router 改前缀 + app.py 双挂。 +- [x] **Step 3: 写实现** — 逐 router 改前缀 + app.py 双挂。 对每个 legacy router 文件,把 `APIRouter(prefix="/api...")` 改为相对前缀。逐文件映射: @@ -2738,7 +2738,7 @@ to: 对全部 13 个 legacy router 同样处理。**保持不变**(不加 prefix、不双挂):`auth.router`、`service_accounts.router`、`api_keys.router`、`assistants_compat.router`。 -- [ ] **Step 4: 跑测试确认通过 + 全域回归** +- [x] **Step 4: 跑测试确认通过 + 全域回归** ```bash cd backend && PYTHONPATH=. uv run pytest tests/test_api_v1_dual_mount.py -v @@ -2752,7 +2752,7 @@ cd backend && make test ``` Expected: 全绿。**若有测试因路径断言失败**:那些测试断言的是旧 `/api/*` 路径,双挂保留了旧路径,故不应失败;如失败说明某 router 改成相对前缀时漏删/多删了 `/api`,回到 Step 3 校正该文件。 -- [ ] **Step 5: commit** +- [x] **Step 5: commit** ```bash cd backend && make lint && git add app/gateway/routers/ app/gateway/app.py tests/test_api_v1_dual_mount.py @@ -2768,25 +2768,25 @@ Co-Authored-By: Claude Opus 4.8 (1M context) " > langgraph-sdk 客户端路径(`/api/langgraph/*`)与 auth(已 `/api/v1/auth`)**不动**。 -- [ ] **Step 1: 定位所有需改的路径串** +- [x] **Step 1: 定位所有需改的路径串** ```bash cd frontend && grep -rn '"/api/' src/ | grep -v '/api/v1/' | grep -v '/api/langgraph' ``` Expected: 列出所有仍指向无版本 `/api/...` 的 fetch 路径(models/mcp/memory/skills/threads/artifacts/uploads/feedback/runs 等)。逐条记录文件 + 行号。 -- [ ] **Step 2: 逐文件改为 `/api/v1/...`** +- [x] **Step 2: 逐文件改为 `/api/v1/...`** 对 Step 1 列出的每条路径,用 `Edit` 把 `"/api/"` 改为 `"/api/v1/"`(仅这些命中行;不要碰 `/api/langgraph` 与已含 `/api/v1` 的串)。 -- [ ] **Step 3: 验证无残留** +- [x] **Step 3: 验证无残留** ```bash cd frontend && grep -rn '"/api/' src/ | grep -v '/api/v1/' | grep -v '/api/langgraph' ``` Expected: 无输出(全部已迁,langgraph 除外) -- [ ] **Step 4: 前端校验** +- [x] **Step 4: 前端校验** ```bash cd frontend && pnpm lint && pnpm typecheck @@ -2796,7 +2796,7 @@ Expected: PASS。若改动触及 env/auth/routing/build-sensitive 代码,追 cd frontend && BETTER_AUTH_SECRET=local-dev-secret pnpm build ``` -- [ ] **Step 5: commit** +- [x] **Step 5: commit** ```bash cd frontend && git add src/ @@ -2807,21 +2807,21 @@ Co-Authored-By: Claude Opus 4.8 (1M context) " ### Task 5.4: 全栈回归收尾 -- [ ] **Step 1: 后端全量** +- [x] **Step 1: 后端全量** ```bash cd backend && make lint && make test ``` Expected: lint clean;test 全绿(基线 3250 passed + 31 skipped + ≤18 既有 caplog flake;无新增 flake) -- [ ] **Step 2: 边界检查** +- [x] **Step 2: 边界检查** ```bash cd backend && PYTHONPATH=. uv run pytest tests/test_harness_boundary.py tests/test_workspace_boundary.py -v ``` Expected: PASS(PR1 的 deerflow 层代码未引入 `app.*` import;PR2 的 `is_service_account` 协议改动仍在 deerflow 内) -- [ ] **Step 3: 回填 spec 链接 + commit** +- [x] **Step 3: 回填 spec 链接 + commit** Modify `docs/multi-tenant-redesign/01-redesign/stage-1-headless-api-pattern-a-auth-foundation-design.zh-CN.md` §10,把: