跳转至

听云 OCM 执行任务单 V4 · dip1-backend 基线替换重部署(R2)+ A1~A4 复核

字段
任务编号 OCL-DEPLOY-20260827-04(V4 · 承接 WDE-TASK-L-20260827-01 听码交付)
签发方 听写 DT(用户"继续"指令链授权)
执行方 听云 OCM
签发时间 2026-08-27 深夜
用户决策 甲方案已批:dip1 HEAD 全面接管 8.218 后端(v2 全家桶一次到位,单实例 :8000,无需 :8010 分流实例)
上游回执 WDE 单 §六(听码实填):A1/A2/A3/A5 本地全绿

⚠️ 零、交付物与包选择(必读)

包名 SHA256 判定
dip1-backend-head-20260827-2127.tar.gz a60f34a5b0148d5afbd60ffad04c99675d4b47bf2d13a17ed8d7205b7acd09de 唯一可用(含 W2 CORS 改动;319,235 B / 178 文件条目)
dip1-backend-head-20260827-2056.tar.gz a38259…bc74 🔴 作废禁用(纯 HEAD 快照,不含 CORS 补齐;A2 断言会挂)

暂存区位置:ocm/private/deploy/(听写已转存并双端 SHA 复验一致)。上传 ECS 后请先复验 SHA256 再解包。

一、执行步骤(R2 口径 · 对齐 WDE 单 §7.2 + §八注意事项)

R2-1 传输与校验

scp ocm/private/deploy/dip1-backend-head-20260827-2127.tar.gz root@8.218.165.94:/opt/weavely/
ssh root@8.218.165.94 'sha256sum /opt/weavely/dip1-backend-head-20260827-2127.tar.gz'
# 必须等于 a60f34a5b0148d5afbd60ffad04c99675d4b47bf2d13a17ed8d7205b7acd09de

R2-2 远程备份(回滚锚点)

cd /opt/weavely/src/dip1 && cp -a backend backend.bak.$(date +%Y%m%d%H%M%S)
docker tag weavely/dip1-api:prod weavely/dip1-api:rollback-20260827   # 旧镜像留作秒级回滚
cp -a .env.prod .env.prod.bak.$(date +%Y%m%d%H%M%S)                   # 若 env 独立存放则按实际路径

R2-3 清空替换代码包

cd /opt/weavely/src/dip1/backend
tar --exclude='data' -xzf /opt/weavely/dip1-backend-head-20260827-2127.tar.gz
ls app/interfaces/api/qsv_router.py   # 存在性抽检(旧基线无此文件)

R2-4 配置注入(R3 映射 · 全表见 WDE 单 §八)

动作
DIP1_DATABASE_URL 必须拼接postgresql+asyncpg://<user>:<pw>@<host>:5432/<db>+asyncpg 必写)
DIP1_JWT_SECRET 迁移 APP_SECRET_KEY 值;dev-auth 模式须 ≥32 字节
DIP1_CORS_ORIGINS 不配(W2 默认值已含 http://8.218.165.94;显式配置会整体覆盖默认值)
DIP1_KEYCLOAK_URL 留空 → dev 模式(A3 冒烟用 make_dev_token 自产 token)
其余旧大写键 无需清理:pydantic extra="ignore" 静默忽略,不会炸启动

R2-5 数据库升级 + 重建容器

alembic upgrade head          # 0001→0002;若 schema 与生产 PG 冲突 → 见二·回滚预案,不得带病续跑
docker compose build api && docker compose up -d api
docker logs --tail 30 dip1-prod-api    # 启动日志确认无 import/连接错误

二、回滚预案(任一环节失败即执行)

cd /opt/weavely/src/dip1 && rm -rf backend && mv backend.bak.<时间戳> backend
docker tag weavely/dip1-api:rollback-20260827 weavely/dip1-api:prod
docker compose up -d api      # 秒级恢复 v1-only 基线;四端零感知

三、复核断言(A1~A4 · 全过后回填 WDE 单 §六 复核列)

# 断言命令 预期
A1 curl -s http://127.0.0.1:8000/openapi.json \| python3 -c "import json,sys;s=json.load(sys.stdin);print([p for p in s['paths'] if 'mfr' in p])" 输出含 /api/v2/qsv/quote/mfr-open 且 method 含 post
A2 curl -s -o /dev/null -w "%{http_code}" -X OPTIONS -H "Origin: http://8.218.165.94" -H "Access-Control-Request-Method: POST" http://127.0.0.1/api/v2/qsv/quote/x/mfr-open 200(经 Caddy :80 同样应通过)
A3 dev token 自签 + ppl_id=PPL-20260823-0001 头 POST /api/v2/qsv/quote/mfr-open(最小 P0/P1/P5 body,模板见 WDL L-20260827-01 §四) 201 + final_amount(720 HKD 若同参)
A4 /health + v1 抽样 3 条 health ok/db=ok;v1 抽样与变更前状态一致(存量零回归)

补充公网侧断言(听云可顺带):GET https://http://8.218.165.94/openapi.json 中 mfr ≥1 条;OPTIONS 经公网 :80 同样 200。

四、约束与回执

  • 零扰动红线:仅动 backend 目录与 api 容器;Caddy/PM2/四前端/PostgreSQL 数据一律不碰
  • 完成后:① 回填 WDE 单 §六「听云复核」列;② 写 OCL 日志(编号续 L-20260827-05);③ 通知听写启动 D01-4 公网冒烟 + D02 全量 8 项收官
  • 任一环节卡住 >30 分钟:贴至少 20 行错误原文至协作通道,不得静默等待

闭环状态:🟠 V4 已签发 · 待听云执行 R2-1~R2-5 并复核 A1~A4