feat(db): 支持接团队共享库 fnsvr-01(PG 17.6),测试库与开发库分离
CI / backend (push) Canceled after 0s

fnsvr-01 的 PostgreSQL 在 8432 端口(不是 5432),实测 PostgreSQL 17.6 / Alpine。
已在该实例建好独立库与角色:
- dadaotask(开发)/ dadaotask_test(测试),owner 都是 dadao_owner
- dadao_owner 迁移用;dadao_app 应用用(NOSUPERUSER NOBYPASSRLS)
- 两个库都已 ALTER SCHEMA public OWNER TO dadao_owner + REVOKE CREATE FROM PUBLIC + GRANT 给 dadao_app

代码改动:
- config 增加 test_database_url / test_migration_database_url,并给出
  resolved_database_url() / resolved_migration_database_url():ENV=test 且有测试库时优先用测试库,
  否则退回开发库(CI 里直接给 DATABASE_URL 即可,行为不变)。
- db.py / alembic/env.py / tests/conftest.py 统一走这两个解析方法。
  原先 conftest 清表用的是 settings.migration_database_url,而应用连的是测试库,
  一旦测试库与开发库不同,TRUNCATE 就清到另一个库上——表现为"测试库脏数据越攒越多、
  列表类断言随机失败"。这是本次真踩到的坑,不是假想。
- tests/conftest.py 保留 E402 豁免(环境变量必须在 import app 模块前写好)。

验证:
- 远程 dadaotask_test 上 pytest 33 passed,跑完表内 0 行(确认清表打在同一个库)
- 远程 dadaotask 上 alembic upgrade head 成功,/health 与 /version 正常,db_role 为 dadao_app 且三项全 false
- 本机便携 PG 16.4 上同样 33 passed(两个 PG 大版本都过)
- ruff check / format 干净

已知限制:该实例没有 pgvector(只有 pg_trgm / pgcrypto),M3 向量检索前必须先定扩展来源,
已写进 2.Design/DEVELOPMENT.md。
This commit is contained in:
Steven
2026-10-28 03:37:41 +08:00
parent b40ea77eec
commit d390b7b58a
7 changed files with 66 additions and 3 deletions
+15
View File
@@ -2,17 +2,32 @@
ENV=dev
APP_NAME=达道Task
# ── 数据库 ───────────────────────────────────────────────────────────
# 应用角色(受 RLS 约束)—— 应用进程只能用它
DATABASE_URL=postgresql+asyncpg://dadao_app:dadao_dev_pw@127.0.0.1:5433/dadaotask
# 迁移角色(owner,绕过 RLS)—— 只有 alembic 用
MIGRATION_DATABASE_URL=postgresql+asyncpg://dadao_owner:dadao_dev_pw@127.0.0.1:5433/dadaotask
# 团队共享库(fnsvr-01,PostgreSQL 17.6)。断网时用上面的本机便携 PG。
# DATABASE_URL=postgresql+asyncpg://dadao_app:dadao_dev_pw@192.168.8.160:8432/dadaotask
# MIGRATION_DATABASE_URL=postgresql+asyncpg://dadao_owner:dadao_dev_pw@192.168.8.160:8432/dadaotask
# 测试库必须独立:测试会 TRUNCATE 所有表,打到开发库上数据就没了
# TEST_DATABASE_URL=postgresql+asyncpg://dadao_app:dadao_dev_pw@192.168.8.160:8432/dadaotask_test
# TEST_MIGRATION_DATABASE_URL=postgresql+asyncpg://dadao_owner:dadao_dev_pw@192.168.8.160:8432/dadaotask_test
REDIS_URL=redis://127.0.0.1:6380/0
# ── 认证 ─────────────────────────────────────────────────────────────
# 生产环境启动时会校验:JWT_SECRET 不得是默认值且长度 ≥ 32
JWT_SECRET=dev-only-change-me
ACCESS_TOKEN_MINUTES=30
REFRESH_TOKEN_DAYS=14
# 生产环境禁止 SMS_PROVIDER=dev(否则任意验证码可登录),启动即失败
SMS_PROVIDER=dev
SMS_DEV_CODE=123456
# 同一手机号两次发码的最小间隔(秒),测试里置 0 可关闭
SMS_THROTTLE_SECONDS=60
CORS_ORIGINS=http://localhost:5180,http://127.0.0.1:5180