# Implementation Plan: 生产级部署能力 P0 补齐(两周) **Branch**: `[prod-p0-hardening]` | **Date**: 2026-02-09 | **Spec**: 当前会话需求(生产部署能力评估后的整改计划) **Input**: 基于当前评估结果(12/24,50%)制定 P0 硬化计划,目标达到可审签上线门槛。 ## Summary 本阶段聚焦“可发布但未完全生产就绪”的关键缺口,按 P0 优先级补齐以下 5 项: 1. Secrets 治理:移除/替换仓库中生产明文敏感配置,完成密钥轮换与注入规范。 2. 生产数据库 TLS 强制:release 模式下禁止 `sslmode=disable`。 3. CI/CD 强门禁:强制 backend `go test ./...`、frontend lint(check-only)+build、最小 smoke 验证。 4. 备份恢复与回滚闭环:形成 runbook 并完成预发演练,沉淀可追溯证据。 5. `/readyz` 深度就绪检查:由“存活探针”升级为“依赖感知探针”。 阶段产出是可审签的 Go/No-Go 结论与证据链;未通过门禁则不得标记生产就绪。 ## Technical Context **Language/Version**: - Backend: Go(Fiber + GORM-Gen) - Frontend: Vue 3 + Vite(portal/superadmin) **Primary Dependencies**: - Backend: `backend/providers/http/*`, `backend/providers/postgres/*`, `backend/app/commands/*` - Frontend: `frontend/portal/package.json`, `frontend/superadmin/package.json` - CI: `backend/.gitea/workflows/build.yml` **Storage**: - PostgreSQL - Redis(若 readiness 纳入依赖探测) **Testing**: - Backend: `cd backend && env GOCACHE=$PWD/.gocache GOTMPDIR=$PWD/.gotmp go test ./...` - Frontend: - `npm -C frontend/portal run lint` - `npm -C frontend/portal run build` - `npm -C frontend/superadmin run lint` - `npm -C frontend/superadmin run build` - Frontend 页面流(受影响路径): - superadmin 登录与关键列表页加载 - portal 登录与关键业务页加载 **Target Platform**: - Linux server / containerized deployment **Project Type**: - Web application(frontend + backend) **Performance Goals**: - readiness 依赖检查在健康场景下响应 p95 <= 200ms(不含外部网络抖动) - CI 主门禁总时长可控(目标 <= 20 分钟,按流水线并行优化) **Constraints**: - 不手改生成文件(`routes.gen.go`, `docs.go`, `swagger.*`) - 控制器保持薄层(bind -> services -> return) - 不使用 `as any` / `@ts-ignore` / `@ts-expect-error` - Bugfix 最小化,不做无关重构 **Scale/Scope**: - 覆盖 backend 发布安全基线、CI 门禁、前端构建策略、发布/回滚操作基线 ## Constitution Check *GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* - ✅ 满足仓库“先计划后实施”要求:本计划作为当前活动计划。 - ✅ 覆盖测试与前端页面流验收要求(frontend-involved 必须含页面流 + backend `go test ./...`)。 - ✅ 变更范围集中于 P0 风险,不引入无关架构调整。 - ✅ 包含任务拆解、依赖、验收标准、风险与证据路径。 ## Project Structure ### Documentation (this phase) ```text docs/ ├── plan.md # 当前活动计划(本文件) ├── release-evidence/.md # 执行证据(测试/演练/门禁结果) └── plans/.md # 阶段通过后归档 ``` ### Source Code (repository root) ```text backend/ ├── .gitea/workflows/build.yml ├── providers/ │ ├── http/engine.go │ └── postgres/config.go ├── app/commands/ │ └── http/http.go └── config*.toml frontend/ ├── portal/package.json └── superadmin/package.json ``` **Structure Decision**: 在现有目录中做增量硬化;不新增子工程,不改动无关模块。 ## Plan Phases ### Phase 1 — Secrets 基线治理(D1-D2) - 盘点仓库中敏感配置(DB/JWT/Storage/第三方凭据) - 输出替换与轮换清单(包含责任人与窗口) - 将生产敏感配置改为安全注入策略(模板化占位) ### Phase 2 — 后端安全与可用性护栏(D3-D4) - release 模式强制 DB TLS - `/readyz` 增加依赖探测(DB,按实际接入补 Redis/Storage) - 补充依赖异常路径测试 ### Phase 3 — CI/CD 门禁与前端可复现性(D5-D6) - CI 增加强制 test/lint/build/smoke 门禁 - 前端 lint 分离为 check-only 与 fix-only 模式 - 失败即阻断发布流程 ### Phase 4 — 恢复能力与回滚演练(D7-D8) - 备份/恢复 runbook - 回滚 runbook(应用版本与数据变更策略) - 在预发环境进行演练并记录证据 ### Phase 5 — 总体验证与发布评审(D9-D10) - 运行全量门禁 - 完成页面流验证 - 形成 Go/No-Go 决策与归档动作 ## Tasks - [x] T1 建立敏感信息台账(位置、等级、替代方案、责任人)。 - [x] T2 制定并执行密钥轮换计划(含失效旧密钥)。 - [x] T3 清理仓库中的生产明文敏感配置,改为模板/注入方式。 - [x] T4 在 backend 增加 release 模式 DB TLS 强制校验。 - [x] T5 升级 `/readyz` 为依赖感知检查(至少 DB)。 - [x] T6 增加 readiness 相关测试(依赖正常/异常两类)。 - [x] T7 改造 CI:加入 backend `go test ./...` 强门禁。 - [x] T8 改造 CI:加入 portal/superadmin lint(check-only)+build 门禁。 - [x] T9 增加最小 smoke(API + 页面流)门禁。 - [x] T10 前端脚本拆分:`lint`(check-only) 与 `lint:fix`(本地修复)。 - [x] T11 编写 backup/restore runbook。 - [x] T12 编写 rollback runbook(含触发条件与回退步骤)。 - [x] T13 在预发完成一次备份恢复演练并留存证据。 - [x] T14 在预发完成一次回滚演练并留存证据。 - [x] T15 执行 backend 全量测试并记录结果。 - [x] T16 执行双前端 lint/build 并记录结果。 - [x] T17 执行受影响前端页面流验证并记录结果。 - [x] T18 汇总发布门禁清单并形成 Go/No-Go 结论。 - [x] T19 Go 时归档 `docs/plan.md` -> `docs/plans/.md`,并清空活动 `docs/plan.md`。 ## Dependencies - T1 -> T2 -> T3(先盘点,再轮换,再清理) - T4 + T5 -> T6(代码完成后补测试) - T7 + T8 + T9 依赖 T4/T5/T10(门禁规则与代码策略一致) - T11 + T12 -> T13/T14(先文档后演练) - T6 + T7 + T8 + T9 + T13 + T14 -> T15/T16/T17 -> T18 - T18(Go) -> T19 ## Acceptance Criteria 1. 仓库中不再存在生产明文敏感配置;密钥轮换已完成且有记录。 2. release 模式下若 DB 配置非 TLS,服务必须拒绝启动并给出明确错误。 3. `/readyz` 能真实反映依赖健康状态(异常返回非 2xx)。 4. CI 对 backend test、frontend lint/build、smoke 具备不可绕过门禁。 5. backup/restore 与 rollback 均完成至少一次预发演练并有证据。 6. 前端受影响页面流验证通过;backend `go test ./...` 通过。 7. 发布结论明确(Go/Conditional Go/No-Go),并可追溯到证据文件。 ## Risks - **风险1:密钥轮换影响现网可用性** - 缓解:采用双窗口/灰度切换,先验证再失效旧密钥。 - **风险2:readiness 判定过严导致误摘流量** - 缓解:设置超时、重试和降级策略,先在预发压测验证。 - **风险3:CI 门禁增加导致发布节奏变慢** - 缓解:门禁并行化、缓存依赖、区分必选与补充检查。 - **风险4:演练环境与生产不一致导致“伪通过”** - 缓解:预发配置尽量贴近生产,并记录偏差项。 ## Complexity Tracking | Violation | Why Needed | Simpler Alternative Rejected Because | |-----------|------------|-------------------------------------| | N/A | N/A | N/A |