docs(mt): 统一 multi-tenant-redesign 命名约定 + README 补执行层索引
命名统一为 .zh-CN.md 后缀(与既有 17 个文件 + README 一致):
- 03-impl/{pr1-8,STATUS}.md → *.zh-CN.md
- Stage 1 spec 去日期前缀、加 .zh-CN,对齐 01-redesign 语义命名
README.zh-CN.md 修复 4 处不统一:
- 顶部加进度指引(现状只信 STATUS,本文是设计/路线导航)
- §0 文档总图补 03-impl 层 + Stage 1 spec + 命名约定注
- §1 表加 Stage 1 spec 行;新增 §1.1 执行记录层(STATUS + 8 impl note 索引)
- §7 阅读路径首次进项目/Stage 1 均加 STATUS + spec 入口
同步更新所有交叉链接(STATUS/pr/spec 自引用、database-schema-as-built、
根 README_zh.md、Stage 0 master plan);全树相对链接校验可达。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+2
-2
@@ -53,7 +53,7 @@ DeerFlow 原本面向"单机可信环境、单用户"。本分支按"以个人
|
||||
- **决策(7 份 ADR + spike + 审计)**:[`01-redesign/`](docs/multi-tenant-redesign/01-redesign/)
|
||||
- **Stage 0 schema 锁定版 / 落地版**:[`workspace-schema-design`](docs/multi-tenant-redesign/01-redesign/workspace-schema-design.zh-CN.md) · [`database-schema-as-built`](docs/multi-tenant-redesign/01-redesign/database-schema-as-built.zh-CN.md)
|
||||
- **落地路线 + 集成轨道**:[`02-rollout/`](docs/multi-tenant-redesign/02-rollout/)
|
||||
- **Stage 0 进度面板(权威"现在到哪了")**:[`03-impl/STATUS.md`](docs/multi-tenant-redesign/03-impl/STATUS.md)
|
||||
- **Stage 0 进度面板(权威"现在到哪了")**:[`03-impl/STATUS.zh-CN.md`](docs/multi-tenant-redesign/03-impl/STATUS.zh-CN.md)
|
||||
|
||||
## 官网
|
||||
|
||||
@@ -656,7 +656,7 @@ DeerFlow 对模型没有强绑定,只要实现了 OpenAI 兼容 API 的 LLM,
|
||||
## 文档
|
||||
|
||||
- [多租户改造汇总索引](docs/multi-tenant-redesign/README.zh-CN.md) - workspace / Postgres / RLS / Headless API 的决策与路线
|
||||
- [Stage 0 进度面板](docs/multi-tenant-redesign/03-impl/STATUS.md) - "现在到哪了"的权威来源
|
||||
- [Stage 0 进度面板](docs/multi-tenant-redesign/03-impl/STATUS.zh-CN.md) - "现在到哪了"的权威来源
|
||||
- [数据库设计落地版](docs/multi-tenant-redesign/01-redesign/database-schema-as-built.zh-CN.md) - 10 张表全字段 / 外键 / 索引参考
|
||||
- [贡献指南](CONTRIBUTING.md) - 开发环境搭建与协作流程
|
||||
- [配置指南](backend/docs/CONFIGURATION.md) - 安装与配置说明
|
||||
|
||||
@@ -305,4 +305,4 @@ erDiagram
|
||||
- [adr-001-data-isolation.zh-CN.md](./adr-001-data-isolation.zh-CN.md) — 行级 `workspace_id` + Postgres RLS + LangGraph 表两层模型
|
||||
- [adr-004-tenant-rbac.zh-CN.md](./adr-004-tenant-rbac.zh-CN.md) — RBAC + JWT 设计
|
||||
- [adr-spike-langgraph-postgres.zh-CN.md](./adr-spike-langgraph-postgres.zh-CN.md) — 为何 LangGraph 表不归 ORM 管
|
||||
- [03-impl/STATUS.md](../03-impl/STATUS.md) + `03-impl/pr8-headless-api-schema.md` — PR 级实现进度
|
||||
- [03-impl/STATUS.zh-CN.md](../03-impl/STATUS.zh-CN.md) + `03-impl/pr8-headless-api-schema.zh-CN.md` — PR 级实现进度
|
||||
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
# Stage 1 · Headless API Pattern A 鉴权地基 — 设计
|
||||
|
||||
> 设计稿。日期 2026-06-28。承接 Stage 0(PR1-PR8 全部 merge,见 [STATUS.md](../03-impl/STATUS.md))与 headless API 轨道设计 [headless-api-track.zh-CN.md](../02-rollout/headless-api-track.zh-CN.md)。
|
||||
> 设计稿。日期 2026-06-28。承接 Stage 0(PR1-PR8 全部 merge,见 [STATUS.zh-CN.md](../03-impl/STATUS.zh-CN.md))与 headless API 轨道设计 [headless-api-track.zh-CN.md](../02-rollout/headless-api-track.zh-CN.md)。
|
||||
>
|
||||
> 范围:headless-api-track **轨道二(Pattern A)** 的鉴权地基。让业务系统 backend 能用 API key(`Authorization: Bearer dfk_...`)调通 DeerFlow Gateway——server-to-server。Pattern B(浏览器直连 + 短期 JWT)、external_user 透传、identity_mode 三态行为、rate limit 不在本 spec 范围(轨道二后续 PR / 轨道三)。
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
| 授权装饰器 | `backend/app/gateway/authz.py` | `require_permission`(L197)、`AuthContext`(L62,含 `permissions: list[str]` + `has_permission`) |
|
||||
| 仓储样板 | `backend/packages/harness/deerflow/persistence/workspace/sql.py` | `WorkspaceRepository`(构造收 `session_factory`,每方法开 fresh session,`_row_to_dict`) |
|
||||
| session 工厂 | `backend/packages/harness/deerflow/persistence/engine.py` | `get_session_factory()` |
|
||||
| PR8 ORM | `persistence/{service_account,api_key,external_user}/model.py` | `ServiceAccountRow` / `ApiKeyRow` / `ExternalUserRow`(schema 已落,见 [pr8 impl note](../03-impl/pr8-headless-api-schema.md)) |
|
||||
| PR8 ORM | `persistence/{service_account,api_key,external_user}/model.py` | `ServiceAccountRow` / `ApiKeyRow` / `ExternalUserRow`(schema 已落,见 [pr8 impl note](../03-impl/pr8-headless-api-schema.zh-CN.md)) |
|
||||
| 路由挂载 | `backend/app/gateway/app.py` | `create_app()` 内 15 个 `include_router`(L379-421) |
|
||||
| 路由前缀约定 | `backend/app/gateway/routers/*.py` | 前缀**写死在 `APIRouter(prefix=...)`**;`auth.py` 已用 `/api/v1/auth`,证明 v1 与旧前缀共存 |
|
||||
| 前端 API 路径 | `frontend/src/core/*/api.ts`、`src/core/threads/hooks.ts` 等 | `getBackendBaseURL()` + 路径串;auth 已用 `/api/v1/auth`;langgraph-sdk 走 `/api/langgraph/*` |
|
||||
@@ -175,6 +175,6 @@
|
||||
## 10. 阅读路径
|
||||
|
||||
- 宏观背景 → [headless-api-track.zh-CN.md](../02-rollout/headless-api-track.zh-CN.md)
|
||||
- Stage 0 现状 / 测试基线 → [STATUS.md](../03-impl/STATUS.md)
|
||||
- PR8 三表 schema → [pr8-headless-api-schema.md](../03-impl/pr8-headless-api-schema.md)
|
||||
- Stage 0 现状 / 测试基线 → [STATUS.zh-CN.md](../03-impl/STATUS.zh-CN.md)
|
||||
- PR8 三表 schema → [pr8-headless-api-schema.zh-CN.md](../03-impl/pr8-headless-api-schema.zh-CN.md)
|
||||
- 本 spec 的实现计划 → (writing-plans 生成后回填链接)
|
||||
+11
-11
@@ -28,14 +28,14 @@
|
||||
| PR | 状态 | Commits | 分支 / 落点 | impl note |
|
||||
|---|---|---|---|---|
|
||||
| **PR0** | ✅ merged | 1 | `a74b88a4` on docs branch | — |
|
||||
| **PR1** | ✅ merged | 8 (T1.1-T1.10) | merged into docs branch (`fab85b14..85a14f4c`) | [pr1-postgres-setup.md](./pr1-postgres-setup.md) |
|
||||
| **PR2** | ✅ merged | 8 (T2.1-T2.10) | merged into docs branch (`404135a1..1112a197`) | [pr2-postgres-default.md](./pr2-postgres-default.md) |
|
||||
| **PR3** | ✅ merged | 7 (T3.1-T3.10) | merged into docs branch (`f63089ae..dda82640`) | [pr3-workspaces.md](./pr3-workspaces.md) |
|
||||
| **PR4** | ✅ merged | 14 (T4.1-T4.14) | merged into docs branch (`d98498b7..5c7753c0`) | [pr4-auth-workspace.md](./pr4-auth-workspace.md) |
|
||||
| **PR5** | ✅ merged | 11 (T5.1-T5.10 + T5.12) | merged into docs branch (`a7326978..30f2bd00`) | [pr5-business-workspace-id.md](./pr5-business-workspace-id.md) |
|
||||
| **PR6** | ✅ merged | 13 (T5.11 + T6.1-T6.15) | merged into docs branch (`361e653d..87ea715c`) | [pr6-routes-paths-workspace.md](./pr6-routes-paths-workspace.md) |
|
||||
| **PR7** | ✅ merged | 4 (T7.1-T7.3 + T7.5; T7.4 是反注入验证无代码改动) | merged into docs branch (`1a6ccc9a..d8b13afc`) | [pr7-ci-boundary-scan.md](./pr7-ci-boundary-scan.md) |
|
||||
| **PR8** | ✅ merged | 5 (T8.1 + T8.2/T8.3 合并 + T8.4 + T8.5 + T8.6) | merged into docs branch (`1fb07e48..f803f393`) | [pr8-headless-api-schema.md](./pr8-headless-api-schema.md) |
|
||||
| **PR1** | ✅ merged | 8 (T1.1-T1.10) | merged into docs branch (`fab85b14..85a14f4c`) | [pr1-postgres-setup.zh-CN.md](./pr1-postgres-setup.zh-CN.md) |
|
||||
| **PR2** | ✅ merged | 8 (T2.1-T2.10) | merged into docs branch (`404135a1..1112a197`) | [pr2-postgres-default.zh-CN.md](./pr2-postgres-default.zh-CN.md) |
|
||||
| **PR3** | ✅ merged | 7 (T3.1-T3.10) | merged into docs branch (`f63089ae..dda82640`) | [pr3-workspaces.zh-CN.md](./pr3-workspaces.zh-CN.md) |
|
||||
| **PR4** | ✅ merged | 14 (T4.1-T4.14) | merged into docs branch (`d98498b7..5c7753c0`) | [pr4-auth-workspace.zh-CN.md](./pr4-auth-workspace.zh-CN.md) |
|
||||
| **PR5** | ✅ merged | 11 (T5.1-T5.10 + T5.12) | merged into docs branch (`a7326978..30f2bd00`) | [pr5-business-workspace-id.zh-CN.md](./pr5-business-workspace-id.zh-CN.md) |
|
||||
| **PR6** | ✅ merged | 13 (T5.11 + T6.1-T6.15) | merged into docs branch (`361e653d..87ea715c`) | [pr6-routes-paths-workspace.zh-CN.md](./pr6-routes-paths-workspace.zh-CN.md) |
|
||||
| **PR7** | ✅ merged | 4 (T7.1-T7.3 + T7.5; T7.4 是反注入验证无代码改动) | merged into docs branch (`1a6ccc9a..d8b13afc`) | [pr7-ci-boundary-scan.zh-CN.md](./pr7-ci-boundary-scan.zh-CN.md) |
|
||||
| **PR8** | ✅ merged | 5 (T8.1 + T8.2/T8.3 合并 + T8.4 + T8.5 + T8.6) | merged into docs branch (`1fb07e48..f803f393`) | [pr8-headless-api-schema.zh-CN.md](./pr8-headless-api-schema.zh-CN.md) |
|
||||
|
||||
**测试基线**:**PR8 末 3250 passed + 31 skipped**(PR7 末 3241 + 31;+9 passed,PR8 新增 3 + 3 + 2 + 1 = 9 个 schema 测试)。PR6 末 3214 + 30;PR5 末 3150 + 30;PR4 末 3136 + 26;PR3 末 3134 + 25;PR2 末 3087。**18 个 caplog 排序 flake 持续存在**(17 个 pre-existing + 1 PR6 引入,PR7/PR8 均未引入新 flake)→ isolate 跑全 PASS,与 stage 无关;集中清理仍推迟到 follow-up。
|
||||
|
||||
@@ -66,9 +66,9 @@ PR1 起到 PR8 末,从既有 ~3087 增到 3250 passed(+163 测试,覆盖
|
||||
| PR4 follow-up | Regular user pre-PR4 backfill 脚本 | login 路径已 lazy backfill 覆盖;如果生产有大量预存 regular user,可补 batch 脚本 | 等真出现这个场景再写 |
|
||||
| PR4 follow-up | 17 个 pre-existing caplog flake 集中清理 | 跨多个 test 文件的 propagation 问题,与 PR4/5/6 无关 | 单独 follow-up 处理 |
|
||||
| ~~PR5 T5.11~~ | ~~ORM model.py `nullable=False` 翻转~~ | **PR6 已落** (commit `87ea715c`) | — |
|
||||
| PR5 T5.12 真机 PG smoke | `alembic 0002 → backfill → 0003` 端到端 | agent 不能起 RDS 操作 | 用户跟进;命令清单见 [pr5-business-workspace-id.md "Live smoke 命令"](./pr5-business-workspace-id.md#live-smoke-命令用户跟进) |
|
||||
| PR6 T6.15 真机迁移 smoke | `make migrate-paths --dry-run` → 真迁移 → lifespan warning 消失 → 双账户互访 404 | agent 起不了 dev 服务 | 🟡 部分 done——「双账户互访 404」✅ 由 `multi_tenant.py`(2026-06-27 PASS)覆盖;文件迁移 `make migrate-paths` 部分仍 ⏳。命令清单见 [pr6-routes-paths-workspace.md "Live smoke 命令"](./pr6-routes-paths-workspace.md#live-smoke-命令用户跟进) |
|
||||
| PR8 RDS 三张表存在 | `psql "$DATABASE_URL" -c "\dt service_accounts api_keys external_users"` 看 3 行;`\d+ api_keys` 看 `idx_api_keys_active ... WHERE revoked_at IS NULL` | agent 没 RDS 凭证 | 用户跟进;命令清单见 [pr8-headless-api-schema.md "Live smoke 命令"](./pr8-headless-api-schema.md#live-smoke-命令用户跟进) |
|
||||
| PR5 T5.12 真机 PG smoke | `alembic 0002 → backfill → 0003` 端到端 | agent 不能起 RDS 操作 | 用户跟进;命令清单见 [pr5-business-workspace-id.zh-CN.md "Live smoke 命令"](./pr5-business-workspace-id.zh-CN.md#live-smoke-命令用户跟进) |
|
||||
| PR6 T6.15 真机迁移 smoke | `make migrate-paths --dry-run` → 真迁移 → lifespan warning 消失 → 双账户互访 404 | agent 起不了 dev 服务 | 🟡 部分 done——「双账户互访 404」✅ 由 `multi_tenant.py`(2026-06-27 PASS)覆盖;文件迁移 `make migrate-paths` 部分仍 ⏳。命令清单见 [pr6-routes-paths-workspace.zh-CN.md "Live smoke 命令"](./pr6-routes-paths-workspace.zh-CN.md#live-smoke-命令用户跟进) |
|
||||
| PR8 RDS 三张表存在 | `psql "$DATABASE_URL" -c "\dt service_accounts api_keys external_users"` 看 3 行;`\d+ api_keys` 看 `idx_api_keys_active ... WHERE revoked_at IS NULL` | agent 没 RDS 凭证 | 用户跟进;命令清单见 [pr8-headless-api-schema.zh-CN.md "Live smoke 命令"](./pr8-headless-api-schema.zh-CN.md#live-smoke-命令用户跟进) |
|
||||
|
||||
## 即将遇到的开放问题(plan 末尾列的,下个 session 处理)
|
||||
|
||||
+1
-1
@@ -145,4 +145,4 @@ make stop && make dev
|
||||
- 跨 workspace 必 404 怎么实现的 → 看 `check_access` 改造(commit `05be7f9a`)+ `@require_permission` 装饰器
|
||||
- 路径新形态 → `Paths.thread_dir` 三档优先级(commit `f013fc1a`)
|
||||
- 仓储 workspace_id 哨兵模式 → 任一 `*/sql.py` 看 create/get/search 签名
|
||||
- 迁移脚本与 PR5 backfill 的边界 → 本文件 "迁移路径" 段,外加 `pr5-business-workspace-id.md`
|
||||
- 迁移脚本与 PR5 backfill 的边界 → 本文件 "迁移路径" 段,外加 `pr5-business-workspace-id.zh-CN.md`
|
||||
+2
-2
@@ -37,7 +37,7 @@
|
||||
- [x] **scanner 红→绿循环**:empty allowlist → 14 violations across 4 files(threads / async_provider / provider / worker,TYPE_CHECKING-only 的 factory.py 正确不在内);填入 4 entry → PASS
|
||||
- [x] **scanner self-test 9 个全过**(防静默空跑)
|
||||
- [x] **T7.4 反注入实验**:往 `feedback.py:13` 加一行违规 import → `pytest tests/test_workspace_boundary.py` 单条 fail,error 精准指 `app/gateway/routers/feedback.py:13 imports langgraph.checkpoint.postgres`;revert 后立即返绿
|
||||
- [x] **全套 `make test` 3241 passed + 31 skipped + 18 caplog flake**(PR6 末 3214 + 30 + 17;+27 passed / +1 skip / +1 flake — passed delta 包含 PR7 新增 10 个测试以及环境差异导致的 17 个之前 flake 这次稳过,flake 列表形态与 STATUS.md 既有 17 项 + PR6 引入的 `test_path_migration_pending_warning` 一致,与 PR7 改动无关)
|
||||
- [x] **全套 `make test` 3241 passed + 31 skipped + 18 caplog flake**(PR6 末 3214 + 30 + 17;+27 passed / +1 skip / +1 flake — passed delta 包含 PR7 新增 10 个测试以及环境差异导致的 17 个之前 flake 这次稳过,flake 列表形态与 STATUS.zh-CN.md 既有 17 项 + PR6 引入的 `test_path_migration_pending_warning` 一致,与 PR7 改动无关)
|
||||
- [x] **CI workflow 接入**:扫描器是普通 pytest,已被 `.github/workflows/backend-unit-tests.yml` 全套 run 覆盖;无需新 workflow
|
||||
|
||||
## 文件结构
|
||||
@@ -46,7 +46,7 @@
|
||||
- `backend/tests/test_workspace_boundary.py` — AST 扫描器(127 行)
|
||||
- `backend/tests/test_workspace_boundary_self.py` — 扫描器 self-test(93 行)
|
||||
- `backend/tests/boundary_allowlist.toml` — 4 个合法 importer + 每行注释(28 行)
|
||||
- `docs/multi-tenant-redesign/03-impl/pr7-ci-boundary-scan.md` — 本文件
|
||||
- `docs/multi-tenant-redesign/03-impl/pr7-ci-boundary-scan.zh-CN.md` — 本文件
|
||||
|
||||
**修改**:
|
||||
- `backend/CLAUDE.md` — Boundary check 段 +2 行
|
||||
+2
-2
@@ -47,7 +47,7 @@
|
||||
- `backend/tests/test_api_key_schema.py`(3 cases)
|
||||
- `backend/tests/test_external_user_schema.py`(2 cases)
|
||||
- `backend/tests/test_pr8_metadata_registration.py`(1 case)
|
||||
- `docs/multi-tenant-redesign/03-impl/pr8-headless-api-schema.md` — 本文件
|
||||
- `docs/multi-tenant-redesign/03-impl/pr8-headless-api-schema.zh-CN.md` — 本文件
|
||||
|
||||
**修改**:
|
||||
- `backend/packages/harness/deerflow/persistence/models/__init__.py` — 加 3 行 import + `__all__` 注册
|
||||
@@ -89,7 +89,7 @@ PYTHONPATH=. uv run pytest -m postgres -v
|
||||
|
||||
## Stage 0 退出门
|
||||
|
||||
PR8 是 Stage 0 工程层面最后一个 PR。剩余 Stage 0 退出条件见 [STATUS.md](./STATUS.md)"用户必须跟进的事":
|
||||
PR8 是 Stage 0 工程层面最后一个 PR。剩余 Stage 0 退出条件见 [STATUS.zh-CN.md](./STATUS.zh-CN.md)"用户必须跟进的事":
|
||||
- [ ] RDS 上 `service_accounts` / `api_keys` / `external_users` 三张表 `\dt` 见
|
||||
- [ ] `make migrate-paths --dry-run` 在 fresh DB 上输出空
|
||||
- [ ] testcontainers ephemeral PG smoke 跑过一次
|
||||
@@ -1,6 +1,8 @@
|
||||
# 多租户改造 · 总览与汇总索引
|
||||
|
||||
> 写于 2026-05-10。把 7 份 ADR + 2 份 spike/审计 + 4 份 rollout / schema 文档,按"ADR 状态 + 5 阶段(Stage 0–4)的业务目标 / 技术路径 / 验证方式"重新串一遍,让团队从任何角度切入都能找到对应位置。
|
||||
> ⚠️ **本文是「设计 / 路线」导航,不反映执行进度**(写于 2026-05-10 设计期)。**想知道「现在到哪了」永远先读 [`03-impl/STATUS.zh-CN.md`](./03-impl/STATUS.zh-CN.md)**——那是唯一动态的进度权威。本 README 后续小节里 Stage 0/1 多以 forward-looking 口径描述,与 STATUS 的"已完成"口径并存属正常分工。
|
||||
>
|
||||
> 写于 2026-05-10。把 7 份 ADR + 2 份 spike/审计 + 4 份 rollout / schema 文档 + 1 份 Stage 1 spec,按"ADR 状态 + 5 阶段(Stage 0–4)的业务目标 / 技术路径 / 验证方式"重新串一遍,让团队从任何角度切入都能找到对应位置。执行记录(STATUS + 各 PR impl note)见 `03-impl/`。
|
||||
>
|
||||
> **范围**:仅汇总与导航,不引入新决策。具体决策正文在各自的 ADR / rollout 文档里。
|
||||
>
|
||||
@@ -27,13 +29,19 @@ docs/multi-tenant-redesign/
|
||||
│ ├── adr-vs-code-audit 审计:ADR vs 现状代码
|
||||
│ ├── multi-tenant-phase-0-plan Phase-0 时间盒 / 产出物
|
||||
│ ├── workspace-schema-design **Stage 0 schema 锁定版**(不可逆决策点)
|
||||
│ └── database-schema-as-built **数据库设计落地版**(对照实现代码的事实参考)
|
||||
└── 02-rollout/ 落地路线 + 集成轨道
|
||||
├── phased-rollout-by-scale **Stage 0–4 主线** 路线图
|
||||
├── stage-0-code-map Stage 0 现状代码地图(行号锚点)
|
||||
└── headless-api-track 业务系统集成轨道(Pattern A / B)
|
||||
│ ├── database-schema-as-built **数据库设计落地版**(对照实现代码的事实参考)
|
||||
│ └── stage-1-headless-api-pattern-a-auth-foundation-design **Stage 1 鉴权地基设计**(Pattern A)
|
||||
├── 02-rollout/ 落地路线 + 集成轨道
|
||||
│ ├── phased-rollout-by-scale **Stage 0–4 主线** 路线图
|
||||
│ ├── stage-0-code-map Stage 0 现状代码地图(行号锚点)
|
||||
│ └── headless-api-track 业务系统集成轨道(Pattern A / B)
|
||||
└── 03-impl/ **执行记录层**(进度 + 各 PR 落地笔记)
|
||||
├── STATUS ★ **唯一进度权威**("现在到哪了")
|
||||
└── pr1..pr8 Stage 0 各 PR impl note(postgres / workspaces / auth / 业务表 / 路由 / boundary / 三表 schema)
|
||||
```
|
||||
|
||||
> 命名约定:全部 `.zh-CN.md` 后缀;`01-redesign` 用语义名(`adr-*` / `*-design`),`03-impl` 用 `prN-*` / `STATUS` 顺序名。
|
||||
|
||||
---
|
||||
|
||||
## 1. ADR 与配套文档状态表
|
||||
@@ -51,6 +59,7 @@ docs/multi-tenant-redesign/
|
||||
| 审计 | [ADR vs 代码](./01-redesign/adr-vs-code-audit.zh-CN.md) | 已结论 | 2026-05-09 | 代码库 0 处 `tenant`;Better Auth 不存在;ObjectStorage / KMS / Postgres 测试夹具全缺;底座先行 §3.5 |
|
||||
| 锁定 | [workspace-schema-design](./01-redesign/workspace-schema-design.zh-CN.md) | **Stage 0 锁定版** | 2026-05-10 | `workspace_id` 命名 + 7 项不可逆决策;Stage 0 PR1 动手前必读 |
|
||||
| 参考 | [database-schema-as-built](./01-redesign/database-schema-as-built.zh-CN.md) | **落地版(as-built)** | 2026-06-27 | 对照实现代码的 10 张表全字段 / 外键 / 索引 / 迁移参考;与锁定版冲突以本文为准 |
|
||||
| 设计 | [stage-1-headless-api-…-design](./01-redesign/stage-1-headless-api-pattern-a-auth-foundation-design.zh-CN.md) | **Stage 1 设计稿** | 2026-06-28 | Pattern A 鉴权地基 5 PR(三表仓储+token / APIKeyAuthBackend 双路径 / CSRF skip on bearer / 管理 endpoint / `/api/v1` 全量迁移)+ 5 项决策(D1-D5) |
|
||||
| 计划 | [phase-0-plan](./01-redesign/multi-tenant-phase-0-plan.zh-CN.md) | 计划 | 2026-05-09 | Phase-0 时间盒 3 周;含底座先行(§3.5) |
|
||||
| 路线 | [phased-rollout-by-scale](./02-rollout/phased-rollout-by-scale.zh-CN.md) | **当前主线路线图** | 2026-05-09 | Stage 0–4 + 触发/退出/时间盒/Go-No-Go |
|
||||
| 锚点 | [stage-0-code-map](./02-rollout/stage-0-code-map.zh-CN.md) | Stage 0 用 | 2026-05-09 | 当前代码文件:行号锚点 + Stage 0 改动落点 |
|
||||
@@ -58,6 +67,26 @@ docs/multi-tenant-redesign/
|
||||
|
||||
---
|
||||
|
||||
## 1.1 执行记录层(`03-impl/`)
|
||||
|
||||
> 上面 §1 是"设计 / 路线"(相对静态);本层是"实际落了什么"(随执行更新)。**进度只信 STATUS,本表只是 impl note 索引。**
|
||||
|
||||
| 文档 | 类型 | 作用 |
|
||||
|---|---|---|
|
||||
| [STATUS](./03-impl/STATUS.zh-CN.md) | ★ 进度权威 | "现在到哪了"唯一来源:8 PR 状态表、测试基线、用户必跟进项、跳过/推迟项、下一步建议。**进新 session 第一件事读它** |
|
||||
| [pr1-postgres-setup](./03-impl/pr1-postgres-setup.zh-CN.md) | impl note | Postgres 接入 + testcontainers fixture |
|
||||
| [pr2-postgres-default](./03-impl/pr2-postgres-default.zh-CN.md) | impl note | 默认 backend 切 Postgres |
|
||||
| [pr3-workspaces](./03-impl/pr3-workspaces.zh-CN.md) | impl note | `workspaces` + `workspace_memberships` 表 + 仓储 |
|
||||
| [pr4-auth-workspace](./03-impl/pr4-auth-workspace.zh-CN.md) | impl note | 注册自建 workspace + JWT 扩 `wid`/`role` |
|
||||
| [pr5-business-workspace-id](./03-impl/pr5-business-workspace-id.zh-CN.md) | impl note | 业务表加 `workspace_id` + alembic + 回填 |
|
||||
| [pr6-routes-paths-workspace](./03-impl/pr6-routes-paths-workspace.zh-CN.md) | impl note | 入口路由 + Paths 系统 workspace 化 |
|
||||
| [pr7-ci-boundary-scan](./03-impl/pr7-ci-boundary-scan.zh-CN.md) | impl note | langgraph.checkpoint boundary CI 围栏 |
|
||||
| [pr8-headless-api-schema](./03-impl/pr8-headless-api-schema.zh-CN.md) | impl note | `service_accounts`/`api_keys`/`external_users` schema only(Stage 1 地基) |
|
||||
|
||||
> Stage 1 的逐 task **实现计划**(writing-plans 产出)将落在 `docs/superpowers/plans/`,与 Stage 0 master plan 一致;其设计稿见 §1 的 stage-1 spec 行。
|
||||
|
||||
---
|
||||
|
||||
## 2. Stage 0–4 速览矩阵
|
||||
|
||||
| Stage | 触发 | 退出 | 时间盒 | 主要 ADR 章节 |
|
||||
@@ -256,9 +285,10 @@ docs/multi-tenant-redesign/
|
||||
## 7. 阅读路径建议
|
||||
|
||||
**第一次进项目(30 min)**:
|
||||
1. 本 README
|
||||
2. [00-current-state/architecture-overview](./00-current-state/architecture-overview.zh-CN.md) — 现状是什么样的
|
||||
3. [phased-rollout-by-scale](./02-rollout/phased-rollout-by-scale.zh-CN.md) §0 + §总览 + §Stage 0 — 现在在哪、下一步做什么
|
||||
1. 本 README(设计 / 路线导航)
|
||||
2. [03-impl/STATUS](./03-impl/STATUS.zh-CN.md) — **现在到哪了**(先看这个,再看下面的"为什么")
|
||||
3. [00-current-state/architecture-overview](./00-current-state/architecture-overview.zh-CN.md) — 现状是什么样的
|
||||
4. [phased-rollout-by-scale](./02-rollout/phased-rollout-by-scale.zh-CN.md) §0 + §总览 + §Stage 0 — 整体路线
|
||||
|
||||
**准备动手做 Stage 0(半天)**:
|
||||
1. [workspace-schema-design](./01-redesign/workspace-schema-design.zh-CN.md) **全文** — 不可逆决策、PR 拆分
|
||||
@@ -267,10 +297,12 @@ docs/multi-tenant-redesign/
|
||||
4. [ADR-006 §2.1](./01-redesign/adr-006-runtime-channel-tenancy.zh-CN.md) + [adr-spike-langgraph-postgres](./01-redesign/adr-spike-langgraph-postgres.zh-CN.md) — 为什么 LangGraph 表不挂 RLS
|
||||
|
||||
**准备动手做 Stage 1(一天)**:
|
||||
1. [phased-rollout Stage 1](./02-rollout/phased-rollout-by-scale.zh-CN.md) — 双轨并行
|
||||
2. [headless-api-track](./02-rollout/headless-api-track.zh-CN.md) **全文** — Pattern A/B 完整设计
|
||||
3. [ADR-003 §4.3-§4.4](./01-redesign/adr-003-llm-key-billing.zh-CN.md) — quota + 悲观预扣
|
||||
4. [ADR-002 §3](./01-redesign/adr-002-sandbox-isolation.zh-CN.md) — Stage 1 用 §3 轻量版(**不**读 §5 K8s 完整版)
|
||||
1. [03-impl/STATUS](./03-impl/STATUS.zh-CN.md) — Stage 0 收尾现状 + Stage 1 可启动方向
|
||||
2. [phased-rollout Stage 1](./02-rollout/phased-rollout-by-scale.zh-CN.md) — 双轨并行
|
||||
3. [headless-api-track](./02-rollout/headless-api-track.zh-CN.md) **全文** — Pattern A/B 完整设计
|
||||
4. [stage-1-headless-api-…-design](./01-redesign/stage-1-headless-api-pattern-a-auth-foundation-design.zh-CN.md) **全文** — Pattern A 鉴权地基设计稿(动手前必读,含 5 PR + 不可逆决策)
|
||||
5. [ADR-003 §4.3-§4.4](./01-redesign/adr-003-llm-key-billing.zh-CN.md) — quota + 悲观预扣(付费 SaaS 轨道)
|
||||
6. [ADR-002 §3](./01-redesign/adr-002-sandbox-isolation.zh-CN.md) — Stage 1 用 §3 轻量版(**不**读 §5 K8s 完整版)
|
||||
|
||||
**做安全/合规评审**:
|
||||
1. ADR-001 / ADR-002 / ADR-003 §4.6(BYO)/ ADR-004 §5.4(strict 装饰器)
|
||||
|
||||
@@ -196,7 +196,7 @@ async def postgres_url(postgres_container):
|
||||
- [ ] **T1.7 doctor.py 加 PG 探测**:仅在 `database.backend == 'postgres'` 时调 `asyncpg.connect(url)` + 报 PG version;测试 `database.backend: sqlite` 时不查 PG(regression);commit
|
||||
- [ ] **T1.8 setup_wizard.py 加交互**:选数据库后端时新增 postgres 选项 + DATABASE_URL 引导;commit
|
||||
- [ ] **T1.9 加 CI workflow**:新建 `.github/workflows/backend-postgres-tests.yml`(用 docker service 或让 testcontainers 在 GitHub runner 起 PG)跑 `pytest -m postgres -v`;本地推到 fork 验证 CI 绿;commit
|
||||
- [ ] **T1.10 验收 + 文档**:跑全套 `cd backend && make test` 验证既有 277 测试不破;`docs/multi-tenant-redesign/03-impl/pr1-postgres-setup.md` 记录 PG 版本对齐结论 + fixture 用法;commit
|
||||
- [ ] **T1.10 验收 + 文档**:跑全套 `cd backend && make test` 验证既有 277 测试不破;`docs/multi-tenant-redesign/03-impl/pr1-postgres-setup.zh-CN.md` 记录 PG 版本对齐结论 + fixture 用法;commit
|
||||
|
||||
---
|
||||
|
||||
@@ -217,7 +217,7 @@ async def postgres_url(postgres_container):
|
||||
|
||||
**新增**:
|
||||
- `scripts/migrate_sqlite_to_postgres.py` — SQLAlchemy reflection 把现有 4 张表数据搬过去
|
||||
- `docs/multi-tenant-redesign/03-impl/pr2-postgres-default.md`(implementation note,可选)
|
||||
- `docs/multi-tenant-redesign/03-impl/pr2-postgres-default.zh-CN.md`(implementation note,可选)
|
||||
|
||||
**修改**:
|
||||
- `config.example.yaml` — `database` 段默认 postgres
|
||||
@@ -1028,7 +1028,7 @@ class ExternalUserRow(Base):
|
||||
## Stage 0 退出 Go/No-Go(来自 phased-rollout-by-scale)
|
||||
|
||||
工程层面:
|
||||
- [x] PR1-PR8 全部合入 ✅(见 STATUS.md 8 PR 状态表,全 merged 进分支)
|
||||
- [x] PR1-PR8 全部合入 ✅(见 STATUS.zh-CN.md 8 PR 状态表,全 merged 进分支)
|
||||
- [x] 既有 277 + 新增 ~70 测试全 100% 通过 ✅(实际 3250 passed + 31 skipped,新增 ~163)
|
||||
- [x] CI(含 backend-postgres-tests)绿 ✅ 2026-05-12 用户确认
|
||||
- [x] 手工 smoke:注册新用户 → workspace 自动建 → JWT 含 wid → 创建 thread → 跨 workspace 互调 404 ✅ 2026-06-27 `apps/examples/http-chat/multi_tenant.py` PASS(N 租户真并发 + 多轮链式上下文 + 双向隔离 search/404;注:JWT wid claim 未显式解码断言,由隔离端到端间接覆盖)
|
||||
|
||||
Reference in New Issue
Block a user