# 开发工作流优化复盘

**日期**: 2026-04-06
**范围**: 文档体系重构、setup-project skill、.env.example、dev.sh 修复、新人环境搭建

## 发现的问题与修复

### 1. 环境变量名不匹配（静默失效）
- `.env` 里写 `JWT_EXPIRES_IN`，代码读 `JWT_EXPIRATION` → 配置被忽略，用硬编码默认值
- `.env` 里写 `AUDIT_HMAC_SECRET`，代码读 `AUDIT_SECRET_KEY` → 同上
- **教训**: 新增环境变量时，必须验证 `.env` 中的变量名和代码中 `process.env.XXX` / `configService.get('XXX')` 完全一致

### 2. dev.sh 端口硬编码
- `scripts/dev/dev.sh` 第 48 行硬编码 `DEV_POSTGRES_PORT=3002`，所有 db 命令用这个值构建 DATABASE_URL
- `.env` 里的 `POSTGRES_PORT` 被完全忽略
- **修复**: 改为 `DEV_POSTGRES_PORT=${POSTGRES_PORT:-5432}`，并在 `load_env()` 后重新覆盖
- **教训**: shell 脚本中不要硬编码端口，应从 `.env` 读取

### 3. .env 中空格和行尾注释导致 source 报错
- `APP_NAME=FFOA Platform` → `source` 时 `Platform` 被当成命令
- `DASHSCOPE_API_KEY=xxx # 注释` → 注释被当成值的一部分
- **教训**: `.env` 文件如果会被 `source` 加载，含空格的值必须加引号，不要用行尾注释

### 4. Redis 空密码导致容器崩溃
- docker-compose 写了 `--requirepass ${REDIS_PASSWORD}`，密码为空时 Redis 报 `wrong number of arguments`
- **教训**: `.env.example` 中不能留空的配置项不要留空，给默认值

### 5. Docker volume 残留旧密码
- 重新生成 `.env`（新随机密码）后，旧 volume 里的 PostgreSQL 还是用旧密码初始化的
- `dev.sh down` 不删 volume，导致新密码连不上旧数据库
- **教训**: 如果改了数据库密码，需要 `docker volume rm` 重建

### 6. 跨用户 tmp 文件权限
- ubuntu 用户创建的 `/tmp/backend.log`，lijian 用户无法写入
- **教训**: 后台启动日志应写到用户自己的目录，不要依赖 /tmp

## 沉淀到项目的改进

| 改进 | 文件 |
|------|------|
| 新增 `.env.example` 模板 | `.env.example`（6 组分类，占位符自动生成） |
| 新增 `setup-project` skill | `.agents/skills/setup-project/SKILL.md`（7 步 + 验收门禁） |
| 修复 dev.sh 端口硬编码 | `scripts/dev/dev.sh` |
| README 精简为 AI-first 入口 | `README.md`（快速开始三步 + Skills 速查 + 方法论） |
| 删除冗余的 01-quick-start.md | 内容已合并到 README |
| 文档体系更新 | system-architecture.md、development-workflow.md、02-dev-environment.md 等 |
| Gitea 分支保护加固 | develop/staging/production 三个分支的合并白名单和审批策略 |

## 方法论收获

- **skill 必须通过实际测试迭代** — 写完不代表能用，每次真实跑一遍都会发现边界情况
- **文档的读者是 AI，不是人** — 快速开始不需要列命令，AI 会根据 skill 自动执行
- **环境变量审计应该自动化** — 手动对比 .env 和代码太容易遗漏，后续可以做成 CI 检查
