docs(specs): add AGENTS.md and engineering guidelines

项目尚无统一工程规范,AI 助手与研发各自发挥导致返工风险。建立
总纲 + 细则两层结构:AGENTS.md 只写硬约束与索引(14 条红线、技术栈
基线、仓库结构、命令契约),细则拆为 10 份文档覆盖 Git、代码风格、
格式化、API 与路由、数据库、测试与 CI、Review、日志、密钥、资产命名。

影响面:仅文档。约束力从本轮起对新建代码生效;与现状冲突处以文档为准。
回滚方式:git revert 本提交。
This commit is contained in:
Stev_Wang committed 2026-11-02 15:09:51 +08:00
1 parent d062d79465
commit 00ae12435e
12 files changed
+1562

No files matched your search

@@ -0,0 +1,131 @@
# 09 · 环境变量与密钥规范
| 项 | 内容 |
| --- | --- |
| 文档版本 | V1.0(2026-11-02) |
| 依据 | 技术架构 附录 C(关键环境变量)、§2.8(安全)、§4.1 / §4.4 |
| 适用范围 | 所有环境(dev / staging / prod)、CI、本地开发 |
| 强制级别 | 强制 |
---
## 1 基本规则
- `ENV-01` 只有 `.env.example` 入库;`.env`、`.env.local`、`.env.*.local` 一律不入库(`.gitignore` 已覆盖)。
- `ENV-02` 变量名 `UPPER_SNAKE_CASE`,按前缀分组;新增变量必须同时更新 `.env.example`、本文附录、部署配置三处。
- `ENV-03` 应用启动时用 Zod 校验环境变量,**缺失或非法直接 fail fast**,禁止带默认值「悄悄跑起来」。
- `ENV-04` 代码中只能通过集中配置模块读取(`config/env.ts`),**禁止**到处 `process.env.XXX`。
- `ENV-05` 禁止在仓库、PR、聊天工具、日志中传递真实密钥;示例值用 `xxx` / `changeme`。
- `ENV-06` 三个环境密钥**完全独立**:dev / staging / prod 不得复用同一套数据库、Redis、S3、JWT、AI 密钥。
---
## 2 变量清单(前缀分组)
### 运行与数据库
| 变量 | 说明 | 示例 |
| --- | --- | --- |
| `NODE_ENV` | 运行环境 | `development` / `production` |
| `DATABASE_URL` | PG 连接串 | `postgresql://user:pass@host:5432/lingxi` |
| `REDIS_URL` | Redis 连接串 | `redis://host:6379/0` |
| `QUEUE` | worker 订阅队列名 | `image:render` |
### 对象存储(S3 协议)
| 变量 | 说明 |
| --- | --- |
| `S3_ENDPOINT` | MinIO / 云 OSS 端点 |
| `S3_ACCESS_KEY` / `S3_SECRET_KEY` | 访问密钥(按环境独立) |
| `S3_BUCKET_ASSETS` / `S3_BUCKET_RENDERS` / `S3_BUCKET_TEMP` | 资产 / 产物 / 临时桶 |
| `S3_BUCKET_ARCHIVE` / `S3_BUCKET_UPLOADS` / `S3_BUCKET_EXPORTS` | 归档 / 上传 / 导出桶 |
### 认证与安全
| 变量 | 说明 |
| --- | --- |
| `JWT_SECRET` / `JWT_REFRESH_SECRET` | 长度 ≥ 32,按环境独立 |
| `ENCRYPTION_KEY` | AES-256-GCM 主密钥(加密 AI 供应商密钥等) |
| `PUBLIC_LINK_HMAC_SECRET` | 免登录审核 / 分享链接签名密钥 |
### AI 接入
| 变量 | 说明 |
| --- | --- |
| `AI_PROVIDER_<NAME>_API_KEY` | 按供应商分(如 `AI_PROVIDER_JIMENG_API_KEY`) |
| `AI_PROVIDER_<NAME>_BASE_URL` | 自定义端点(可选) |
| `AI_ROUTE_REFRESH_MS` | 路由表缓存刷新间隔 |
> 供应商 API Key 以加密形式存库(`ai_configs`)时,环境变量只用于**首次注入 / 灾备**;运行时读取库内配置,避免多处真相。
### 媒体处理
| 变量 | 说明 |
| --- | --- |
| `FFMPEG_PATH` / `FFPROBE_PATH` | 二进制路径(镜像内固定) |
| `MAX_UPLOAD_MB` | 单文件上限 |
| `WORKER_CONCURRENCY` | 单 worker 并发 |
### 成本与开关
| 变量 | 说明 |
| --- | --- |
| `COST_SOFT_LIMIT` / `COST_HARD_LIMIT` | 预算软 / 硬限(默认 0.8 / 1.0) |
| `FEATURE_VIDEO` | 视频线开关 |
| `OTEL_EXPORTER_OTLP_ENDPOINT` | 链路追踪导出端点 |
---
## 3 密钥管理
| 项 | 规则 |
| --- | --- |
| 存储 | 生产用云 KMS / Vault / Secrets Manager;**禁止**明文写进 compose 或镜像 |
| 注入 | CI/CD 注入环境变量;本地用 `.env.local`(不入库) |
| 加密 | AI 供应商密钥等入库字段用 AES-256-GCM,密钥不落同一库 |
| 权限 | 应用 DB 账号非 superuser;MinIO 按桶最小权限;CI 只读必要范围 |
| 轮换 | JWT / HMAC / 加密密钥至少每 6 个月或人员变动时轮换;轮换需兼容期(新旧并存) |
| 审计 | 密钥变更记审计(谁、何时、哪个 key 的版本号,**不记值**) |
- `ENV-07` 前端只能暴露 `VITE_PUBLIC_*` 前缀变量;构建产物必须扫描确认无服务端密钥。
- `ENV-08` 禁止把密钥拼进 URL / query / 日志 / 异常信息。
- `ENV-09` 本地开发连的 MinIO / PG 凭据只能是 dev 值,且与生产不一致。
---
## 4 泄露处置(30 分钟内)
1. **立即轮换**对应密钥(先轮换再排查,不等待确认)。
2. 撤销相关 token / session,作废签名链接。
3. 检查访问日志与 `ai_usage`,评估是否被滥用(尤其 AI 费用)。
4. 用 `git filter-repo` 清理历史并强制全员重新 clone(见 [01](01-Git规范.md) `GIT-20`)。
5. 24 小时内出复盘:泄露路径、影响面、改进项(通常补 CI 扫描 / pre-commit)。
- `ENV-10` 泄露事件必须记录在案,**禁止**「悄悄换掉当没发生」。
---
## 5 本地开发
```bash
cp .env.example .env.local # 填 dev 值(不得填生产值)
pnpm compose:up # PG 18 / Redis 7.4 / MinIO
pnpm db:migrate && pnpm db:seed
pnpm dev
```
- `ENV-11` 禁止 `docker compose down -v` 清库;重置数据用 `pnpm db:reset`。
- `ENV-12` 本地不得连生产数据库 / 生产对象存储 / 生产 AI 供应商(费用与数据风险)。
- `ENV-13` 开发机 Node 版本由 `.nvmrc` 固定,`package.json` 声明 `engines`,`preinstall` 用 `only-allow pnpm` 拦截其他包管理器。
---
## 6 检查清单
- [ ] 新增变量已写 `.env.example` 与本文
- [ ] 启动校验覆盖新变量,缺失即失败
- [ ] 未在代码中散读 `process.env`
- [ ] 三环境密钥独立,未复用
- [ ] 无密钥进日志 / URL / 前端 bundle
- [ ] 生产密钥来自 KMS / Secrets Manager
- [ ] 轮换与泄露处置流程已知晓