Files

144 lines
6.0 KiB
Markdown
Raw Permalink Normal View History

# Plan: Env Config Refactor
**Date:** 2026-02-05
**Author:** AI Assistant
**Status:** Draft
## Overview
`.env` / `.env.example``backend/src/core/config/settings.py` 做一次一致性重构,消除同一含义的重复配置来源(例如 `DATABASE_URL` 与分段口令、host/port 与完整 URL)。目标是明确一组规范化环境变量,确保后端仅通过 Settings 读取,并兼顾 `infra/docker/docker-compose.yml` 的现有依赖。
## Requirements
### Functional
- [ ] 提出“规范化环境变量”清单(canonical set),覆盖后端与 Supabase 本地栈的关键配置。
- [ ] 定义 Settings 的读取与推导策略(优先级、默认值、派生字段)。
- [ ] 给出 `.env` / `.env.example` 的迁移步骤与兼容策略。
- [ ] 兼容 `infra/docker/docker-compose.yml` 使用的变量(保证 compose 不被破坏)。
### Non-Functional
- [ ] Performance: Settings 解析不增加明显启动耗时
- [ ] Security: 不在仓库中暴露真实密钥;对后端使用的数据库 URL 与密钥来源保持单一可信源
## Technical Approach
以“后端设置单一来源 + docker-compose 继续使用 Supabase 变量”为原则:
- 后端只接受 `SOCIAL_DATABASE_URL` 与必要的 Supabase 访问变量(`public_url/anon_key/service_role_key/jwt_secret`)。
- Supabase stack 继续使用 `SOCIAL_SUPABASE__*` 变量,保持 compose 模板稳定。
- 通过 Settings 做派生字段(例如 `supabase.url`)与兼容性读入(可选旧字段,设置弃用期)。
### Key Decisions
| Decision | Rationale |
|----------|-----------|
| 保留 `SOCIAL_DATABASE_URL` 作为后端唯一数据库连接来源 | 避免与分段 `POSTGRES_*` 产生冲突,清晰配置入口 |
| Supabase stack 变量继续使用 `SOCIAL_SUPABASE__*` | docker-compose 已广泛引用,改动成本高 |
| Settings 允许短期兼容旧字段 | 保障迁移期间部署安全,减少切换风险 |
## Implementation Steps
### Phase 1: Inventory & Mapping (2 hours)
1. 盘点 `.env` / `.env.example``settings.py` 的变量差异,标注重复与冲突字段。
2. 输出 canonical env vars 列表与映射关系表(旧 -> 新)。
### Phase 2: Settings Refactor (3 hours)
1.`settings.py` 中实现新的读取优先级与派生字段。
2. 为旧字段加兼容读取与弃用注记(仅内存兼容,不继续写入)。
### Phase 3: Env Templates Update (2 hours)
1. 更新 `.env.example` 为 canonical 变量,并标注“后端使用/compose 使用”。
2. 更新 `.env`(本地开发用)以匹配新模板。
### Phase 4: Validation & Docs (2 hours)
1. 本地启动 docker-compose,验证 Supabase stack 与后端连接正常。
2. 写简要迁移说明(README 或 docs/ 中短节)。
## Files to Modify
| File | Changes |
|------|---------|
| `.env.example` | 替换为 canonical 变量,移除重复字段 |
| `.env` | 与模板对齐,移除重复字段 |
| `backend/src/core/config/settings.py` | 调整 Settings 读取与派生策略 |
| `infra/docker/docker-compose.yml` | 仅在必要时新增兼容映射变量 |
| `README.md``docs/*` | 增加迁移说明 |
## Files to Create
| File | Purpose |
|------|---------|
| `docs/plans/PLAN-env-config-refactor-2026-02-05.md` | 规划文档 |
## Dependencies
- [ ] 无新增第三方依赖
## Proposed Canonical Env Vars
### Backend (Settings)
- `SOCIAL_DATABASE_URL` (required) — 后端数据库连接(唯一来源)
- `SOCIAL_SUPABASE__PUBLIC_URL` — Supabase 公网/本地外部访问 URL
- `SOCIAL_SUPABASE__API_EXTERNAL_URL` — Supabase Auth 回调外部 URL
- `SOCIAL_SUPABASE__ANON_KEY` — 前端/匿名访问 key
- `SOCIAL_SUPABASE__SERVICE_ROLE_KEY` — 后端服务角色 key
- `SOCIAL_SUPABASE__JWT_SECRET` — JWT 验证密钥(后端验证用)
### Supabase Stack (docker-compose)
- `SOCIAL_SUPABASE__POSTGRES_HOST`
- `SOCIAL_SUPABASE__POSTGRES_PORT`
- `SOCIAL_SUPABASE__POSTGRES_DB`
- `SOCIAL_SUPABASE__POSTGRES_PASSWORD`
- `SOCIAL_SUPABASE__KONG_HTTP_PORT`
- `SOCIAL_SUPABASE__KONG_HTTPS_PORT`
- `SOCIAL_SUPABASE__SITE_URL`
- `SOCIAL_SUPABASE__JWT_SECRET`
- `SOCIAL_SUPABASE__ANON_KEY`
- `SOCIAL_SUPABASE__SERVICE_ROLE_KEY`
- 其余 `SOCIAL_SUPABASE__*` 保持现状(Logflare、SMTP、Pooler 等)
## Mapping Strategy
1. **Backend DB**
- Only: `SOCIAL_DATABASE_URL`
- Deprecated: `SOCIAL_SUPABASE__POSTGRES_*`(后端不再拼接)
2. **Supabase URL**
- Primary: `SOCIAL_SUPABASE__PUBLIC_URL`
- Fallback: `SOCIAL_SUPABASE__API_EXTERNAL_URL`
- Settings 中 `supabase.url` 由上述字段派生
3. **Docker Compose**
- 继续读 `SOCIAL_SUPABASE__POSTGRES_*`
- 不引入 `SOCIAL_DATABASE_URL` 到 compose,以免混淆职责
## Migration Steps
1.`settings.py` 中增加兼容逻辑:若 `SOCIAL_DATABASE_URL` 不存在,可临时从 `SOCIAL_SUPABASE__POSTGRES_*` 组装(同时记录弃用)。
2. 更新 `.env.example`:只保留 canonical 变量并标注用途。
3. 更新 `.env`:移除重复字段,确保本地后端使用 `SOCIAL_DATABASE_URL`
4. 校验 compose`infra/docker/docker-compose.yml` 不依赖被移除字段。
5. 发布说明:提示下游用户迁移并在下个版本移除兼容逻辑。
## Testing Strategy
- **Unit Tests:** Settings 派生字段与优先级规则
- **Integration Tests:** 后端连接 Supabase DB(使用 `SOCIAL_DATABASE_URL`
- **E2E Tests:** 关键登录/读写流程(确认 JWT 与 Service Role 配置无误)
## Risks & Mitigations
| Risk | Impact | Likelihood | Mitigation |
|------|--------|------------|------------|
| compose 变量被误删导致 Supabase 启动失败 | High | Medium | 迁移前后对照 `docker-compose.yml`,保留全部 `SOCIAL_SUPABASE__*` 依赖 |
| 后端数据库连接断开 | High | Medium | 兼容旧字段,先引入新变量再切换 |
| 开发环境 `.env` 未更新 | Medium | High | 更新模板并在 README 明确迁移步骤 |
## Estimated Effort
| Phase | Effort |
|-------|--------|
| Phase 1 | 2 hours |
| Phase 2 | 3 hours |
| Phase 3 | 2 hours |
| Phase 4 | 2 hours |
| **Total** | **9 hours** |