From 1112a1971bb8924f53080be3045f31a32426ceb9 Mon Sep 17 00:00:00 2001 From: 1445043649 <> Date: Mon, 11 May 2026 09:23:16 +0800 Subject: [PATCH] docs(impl): PR2 implementation note + acceptance checklist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 记录 Stage 0 PR2 的实施落点、关键 LOCK 决策、跟进项与 7 commit 列表。 验收:3087 passed + 23 skipped + 0 failed(vs PR1 基线 3085 + 2 新 default-backend 测试)。 Stage 0 PR2 T2.10. PR2 完成。 Co-Authored-By: Claude Opus 4.7 (1M context) --- .../03-impl/pr2-postgres-default.md | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 docs/multi-tenant-redesign/03-impl/pr2-postgres-default.md diff --git a/docs/multi-tenant-redesign/03-impl/pr2-postgres-default.md b/docs/multi-tenant-redesign/03-impl/pr2-postgres-default.md new file mode 100644 index 00000000..e96478d4 --- /dev/null +++ b/docs/multi-tenant-redesign/03-impl/pr2-postgres-default.md @@ -0,0 +1,75 @@ +# PR2 · 默认 backend 切到 Postgres + +> 实现笔记。对应 [docs/superpowers/plans/2026-05-10-stage-0-multi-tenant-foundation.md](../../superpowers/plans/2026-05-10-stage-0-multi-tenant-foundation.md) PR2(T2.1-T2.10)。 +> +> 状态:**已落地**,7 commits 提交在 branch `feat/stage-0-pr2-postgres-default`。 + +## 范围 + +让 Postgres 成为 dev + 生产的默认 backend,SQLite 沦为可选 fallback——但**不破坏** SQLite 路径(Stage 0 期间 dev 仍可走 SQLite)。 + +具体动作: +- `config.example.yaml` `database` 段:postgres 活跃、SQLite 注释;bump `config_version` 9→10 +- `.env.example`:`DATABASE_URL` 行从注释改为活值(指向本地 docker postgres) +- `docker-compose-dev.yaml` `gateway depends_on postgres healthcheck`(生产 compose 不动——prod 用远程 RDS) +- `scripts/check.py` 加 `check_postgres_preflight()`:`make dev` 链上 PG 不通时 FAIL 阻断启动 +- `README.md` Quick Start 加 Step 3 "Database backend" +- 2 个 regression test 锁定:(a) 显式 sqlite 仍工作 (b) `config.example.yaml` 默认 postgres + +## 验收 + +- [x] 全套 `pytest tests/` 3087 passed + 23 skipped + 0 failed(PR1 基线 3085;diff = 2 新 default-backend 测试) +- [x] `test_explicit_sqlite_backend_still_works` PASS(SQLite regression 防线) +- [x] `test_config_example_default_backend_is_postgres` PASS +- [x] `python scripts/check.py` 在 sqlite 配置下 silent skip postgres preflight(无破坏现有用户) +- [x] `make doctor` 在 postgres 配置 + DATABASE_URL 不可达时给可执行 fix(指向 docker compose 命令) +- [x] `docker compose -f docker/docker-compose-dev.yaml config` 校验通过(postgres + gateway depends_on healthcheck 都合法) +- [ ] live:`make dev` 在 postgres 模式下 preflight + 服务启动——**待 docker daemon 起后由用户实测** +- [ ] live:CI workflow `backend-postgres-tests` 跑通——**PR push 后验证** + +## 关键决策(lock 项) + +| 项 | 选择 | 理由 | +|---|---|---| +| 默认 backend | postgres | Stage 0 不可逆决策(plan §不可逆决策一览);省 Stage 1 重 ALTER 4 张表的返工 | +| SQLite 处理 | 注释保留为 fallback,不删 | offline dev / 单元测试场景仍需要 | +| `config_version` bump | 9 → 10 | 默认行为变化属于 schema 变更,触发 `AppConfig.from_file()` 旧版 warning | +| `DATABASE_URL` 形态 | `postgresql+asyncpg://` 而非 `postgresql://` | 与 SQLAlchemy 异步 dialect 对齐,避免 dialect 推断警告 | +| `depends_on` 仅 dev compose | prod compose 无 postgres service | 生产用远程 RDS,不在 compose 内 | +| PG preflight 加在 check.py | 不在 serve.sh 加 bash 版 | Makefile 已串 check.py → serve.sh,避免双重实现 | +| preflight FAIL vs WARN | FAIL(阻断启动) | 配了 PG 但不通就一定崩,preflight 早死好过 runtime 崩 | +| sqlite→pg 数据迁移工具 | **不实现**(plan T2.8 marked optional) | Stage 0 没有生产数据需要迁;follow-up | + +## 跟进项(不在 PR2 范围) + +- **PR3+**:在新建的 PG 上跑 workspace 表 schema +- **`backend/CLAUDE.md` 更新**:plan T2.9 包括 backend/CLAUDE.md,本 PR 仅做了 README;CLAUDE.md follow-up +- **`scripts/migrate_sqlite_to_postgres.py`**(plan T2.8 optional):如果将来有用户从 SQLite dev 迁 PG 的需求,再写 +- **prod compose postgres service**:当前 docker-compose.yaml(生产)无 postgres service;如果将来不用远程 RDS,可补上 + +## 涉及文件 + +| 类别 | 文件 | +|---|---| +| 配置 | `config.example.yaml`、`.env.example` | +| Docker | `docker/docker-compose-dev.yaml`(gateway depends_on postgres) | +| 脚本 | `scripts/check.py`(postgres preflight) | +| 测试 | `backend/tests/test_default_database_backend.py` | +| 文档 | `README.md` | + +## 提交记录 + +7 commits(每条 1 task): + +``` +404135a1 feat(config): default database backend to postgres T2.1 +7d3d3560 feat(env): activate DATABASE_URL with local-dev default T2.2 +d312bdf9 test(config): pin default postgres backend + sqlite regression T2.3 + T2.4 +3e62a0f6 feat(docker): gateway depends_on postgres healthcheck (dev only) T2.5 +83b680b2 feat(check): postgres preflight in scripts/check.py T2.6 +745a33e0 chore: T2.7 acknowledgement (covered by T1.8) T2.7(empty) +c53295df docs(readme): add Database backend section in Quick Start T2.9 +``` + +T2.10(impl doc)是这份文档本身。 +T2.8(sqlite→pg 迁移工具)跳过——plan marked optional + Stage 0 无生产数据。