文档:新增生产升级操作手册并同步基线

This commit is contained in:
yml2213
2026-11-08 21:30:06 +08:00
parent 996054a5c5
commit 1df1b9520b
6 changed files with 689 additions and 16 deletions
+3 -1
View File
@@ -12,7 +12,9 @@
3. 涉及订单、内部 SKU、履约、商品、成本或财务时,必须完整阅读
[docs/统一订单履约与财务模型-权威版.md](docs/统一订单履约与财务模型-权威版.md)。
4. 涉及部署、数据库或备份时,再读取对应的运维文档。
5. `docs/archive/` 只用于追溯,不作为实现依据。
5. 涉及生产升级、数据库迁移、领域模型切换或财务重建时,必须完整阅读
[docs/生产升级操作手册.md](docs/生产升级操作手册.md)。
6. `docs/archive/` 只用于追溯,不作为实现依据。
## 唯一权威
+1
View File
@@ -18,6 +18,7 @@
| 文档 | 用途 |
| --- | --- |
| [生产升级操作手册](生产升级操作手册.md) | 含迁移、履约切换、财务重建的生产升级与回滚步骤 |
| [部署启动与数据库重建](部署启动与数据库重建.md) | 本地与生产部署、数据库重建 |
| [数据库备份与恢复](数据库备份与恢复.md) | 备份、恢复、OSS |
| [数据库SQL约束与运维](数据库SQL约束与运维.md) | SQL 护栏与生产观测 |
+4
View File
@@ -68,6 +68,10 @@ bash deploy/restore-db.sh --verify
`--verify` 会把最新带有效清单的备份恢复到一个隔离的临时 PostgreSQL 容器(不接入业务网络,不影响线上库),并打印迁移列表与各表行数。建议之后每月执行一次演练——没验证过的备份等于没有备份。
生产升级前的恢复验证是硬门禁,并且必须验证本次生成的指定备份,而不是只验证任意旧备份。
具体步骤和当前恢复阻断项见
[生产升级操作手册](生产升级操作手册.md)。恢复验证未通过时禁止执行生产迁移。
### 4. 配置每日定时备份
```bash
+657
View File
@@ -0,0 +1,657 @@
---
type: 生产运维操作手册
description: order_site 生产结构升级、数据切换、验收与回滚的唯一执行步骤。
tags: [生产, 部署, 数据库, 迁移, 备份, 回滚, 财务]
status: current
version: 1.0
updated_at: 2026-11-08
---
# 生产升级操作手册
> 本手册适用于包含数据库迁移、领域模型切换或财务重建的生产升级。
> 业务与架构口径仍以
> [统一订单履约与财务模型-权威版](统一订单履约与财务模型-权威版.md) 为唯一权威。
>
> 涉及普通文档修改、无迁移的小版本更新,可继续使用
> [部署启动与数据库重建](部署启动与数据库重建.md)。
> 只要包含迁移、表结构切换或派生数据重建,必须按本手册执行。
## 一、本次升级基线
以下信息是 2026-11-08 的首次执行基线。后续每次升级必须由发布负责人更新,
旧值只允许保留在发布记录中,不能继续作为执行依据。
| 项目 | 值 |
| ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 发布日期 | 2026-11-08 |
| 发布分支 | `dev_11.8` |
| 目标提交 | `d76e8265f806342c670d570e8ee72f5e8ab08fdc` |
| 生产起始迁移 | `146` |
| 目标迁移 | `150` |
| 新增迁移 | `147_internal_sku_product_routing.sql`、`148_fulfillment_execution_truth.sql`、`149_finance_derived_scope.sql`、`150_voucher_consume_order_received_scope.sql` |
| 升级类型 | 履约、内部 SKU、商品路由、财务派生数据硬切 |
| 预计维护窗口 | 2–3 小时 |
| 核心停写时间 | 20–40 分钟 |
同生产规模本地演练结果:
- 数据量:订单 `456777`、订单项 `456762`、履约 `456762`。
- `146 → 150` 单事务迁移:约 `61 秒`。
- 90 天财务重建:约 `14–17 秒`。
- 第二次财务重建:`ledger.adjusted = 0`,幂等成立。
- 严格财务审计:`critical: []`。
- 原始订单、订单项、收入、退款和资金流水守恒。
## 二、绝对禁止
1. 禁止使用 `deploy/ubuntu-deploy.sh` 执行本次 `147–150` 升级;它会在旧后端
仍运行时执行迁移。
2. 禁止在生产执行 `deploy/ubuntu-deploy.sh --reset-db`。
3. 禁止使用 `--skip-backup`。
4. 禁止在迁移前跳过 `restore-db.sh --verify`。
5. 禁止在旧后端仍运行时执行 `147–150` 硬切迁移。
6. 禁止迁移后用旧镜像启动后端;旧代码不兼容 `order_items.legacy_*`。
7. 禁止为了赶进度绕过硬门禁、数据守恒检查或财务审计。
8. 禁止自动猜测缺失渠道、商品归属或人工配置。
9. 禁止删除或重写原始订单、退款、真实工单、资金流水和审计日志。
10. 禁止在迁移过程中重启 PostgreSQL、强制杀迁移事务或重复启动第二个迁移进程。
11. 禁止在本轮观察期结束前删除 `legacy_*` 字段和兼容表。
## 三、角色与记录
执行前至少确定以下角色:
| 角色 | 职责 |
| ------------ | ---------------------------------------------- |
| 发布负责人 | 冻结提交、确认窗口、决定继续或回滚 |
| 数据库执行人 | 备份、迁移、统计刷新、数据检查 |
| 验收人 | 独立执行审计、核对输出,不复用执行人的口头结论 |
| 业务负责人 | 确认已知待分类项、财务口径和恢复营业 |
整个过程中必须记录:
- 升级前后 commit。
- 升级前后迁移号。
- 数据库与配置备份 OSS key、sha256、迁移号和文件大小。
- 每个阶段的开始时间、结束时间和退出码。
- 三组审计的完整输出。
- 财务重建 dry-run 与 execute 的完整 JSON。
- 上线验收 SQL 的 PASS、FAIL、WARN 清单。
- 继续、暂停或回滚的决定及确认人。
## 四、上线前门禁
以下条件必须全部满足,否则不得进入维护窗口。
### 4.1 代码门禁
```bash
cd /srv/order_site # 替换为服务器实际目录
git fetch --prune
git switch dev_11.8
git pull --ff-only
git status --short
git rev-parse HEAD
```
要求:
- `git status --short` 无输出。
- `git rev-parse HEAD` 等于本次批准的提交。
- 后端 `npm run check` 通过。
- 前端 `npm run check` 通过。
- 本次发布没有未提交文件。
### 4.2 生产只读基线
先执行只读检查,不写数据库:
```bash
docker compose exec -T postgres \
sh -lc 'psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -v ON_ERROR_STOP=1 -f -' <<'SQL'
BEGIN READ ONLY;
SELECT COALESCE(filename, name) AS migration
FROM schema_migrations
ORDER BY COALESCE(filename, name) DESC
LIMIT 5;
SELECT
(SELECT count(*) FROM orders) AS orders,
(SELECT count(*) FROM order_items) AS order_items,
(SELECT count(*) FROM order_refunds WHERE status = 'confirmed') AS refunds,
(SELECT COALESCE(sum(amount_fen), 0) FROM order_refunds WHERE status = 'confirmed') AS refund_fen,
(SELECT count(*) FROM work_orders) AS work_orders,
(SELECT count(*) FROM fulfillment_tasks) AS fulfillment_tasks,
(SELECT count(*) FROM fund_entries) AS fund_entries;
COMMIT;
SQL
```
要求:
- 当前最高迁移必须是 `146`。
- 订单、订单项、退款和资金流水数量记录到发布单。
- `docker compose ps`、`/health/ready` 和外网主入口均正常。
### 4.3 恢复验证硬门禁
这是 P0 门禁。备份文件存在不等于可回滚。
```bash
bash deploy/backup-db.sh
bash deploy/restore-db.sh --list
bash deploy/restore-db.sh --verify --key '<本次备份完整 OSS key>'
```
必须确认:
- `backup-db.sh` 退出码为 `0`。
- OSS manifest、sha256 和文件大小有效。
- `restore-db.sh --verify` 退出码为 `0`。
- 临时恢复库最高迁移为升级前迁移。
- 订单、订单项等关键表数量与生产只读基线一致。
> 2026-11-08 审核结论:当前备份恢复到隔离库时,会因
> `idx_order_items_pending_internal_sku` 依赖函数恢复顺序,以及 `livehub_ro`
> 角色不存在而返回非零。恢复脚本因此会判定备份不可用。
>
> 在上述问题修复并重新验证通过前,本次升级状态为 **禁止上线**。
> 不允许使用 `--allow-unverified`、手工忽略 `pg_restore` 错误或跳过此门禁。
### 4.4 调度任务门禁
升级前在后台关闭全部定时任务:
```text
后台 → 平台配置 → 监控任务 → 任务总开关 → 关闭 → 保存任务
```
要求:
- 总开关显示关闭。
- 所有任务不再排下一次执行。
- 升级期间不得重新开启,直到财务重建、业务配置和上线验收全部通过。
该配置保存在数据库中,会被升级前备份一并保存。
## 五、维护窗口执行顺序
严格按照以下顺序执行。任何一步失败都立即停止,不得跳步。
### 5.1 预构建镜像
在停止业务前完成构建,不替换正在运行的容器:
```bash
docker compose build backend web
docker compose --profile tools build tools
```
构建失败时停止,不进入维护窗口。
### 5.2 进入维护状态
先把公网流量切到维护页,或只允许办公网 IP 访问,并保留管理员内部访问通道。
迁移后的业务配置需要通过后台 UI 完成,不能全程只启动 backend。
如果无法在维护期间隔离公网用户和保留管理员入口,暂停升级。
通知停止接单后执行:
```bash
docker compose stop web backend
docker compose ps
```
要求:
- `web`、`backend` 已停止。
- PostgreSQL 保持运行。
- 此时开始计算核心停写时间。
### 5.3 生成最终升级前备份
虽然 4.3 已验证恢复链路,这里仍必须生成停机后的最终备份:
```bash
# 重新执行 4.2 的只读计数 SQL,记录停机后的最终基线
bash deploy/backup-db.sh
bash deploy/restore-db.sh --list
```
记录:
- 完整 OSS key。
- 对应配置备份 OSS key。
- manifest 中的迁移号,必须为 `146`。
- sha256 和文件大小。
最终停机备份也必须做隔离恢复验证:
```bash
bash deploy/restore-db.sh --verify --key '<最终备份完整 OSS key>'
```
要求:
- 命令退出码为 `0`。
- manifest、sha256 和下载校验通过。
- 临时恢复库最高迁移为 `146`。
- 订单、订单项和资金流水数与停机后的最终基线一致。
最终备份恢复验证未通过时,不得执行迁移。
### 5.4 执行数据库迁移
必须先确认旧后端已停止,再执行:
```bash
docker compose run --rm --no-deps backend node dist/db/migrate.js
```
预期执行:
```text
147_internal_sku_product_routing
148_fulfillment_execution_truth
149_finance_derived_scope
150_voucher_consume_order_received_scope
```
要求:
- 命令退出码为 `0`。
- 不允许中断、重复启动或并行启动。
- 迁移失败时保持后端停止,不自动重启。
迁移后检查:
```bash
docker compose exec -T postgres sh -lc \
'psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -Atc "
SELECT COALESCE(filename, name)
FROM schema_migrations
ORDER BY COALESCE(filename, name) DESC
LIMIT 5
"'
```
最高迁移必须为 `150`。
### 5.5 刷新统计信息
迁移后立即执行,否则履约审计可能超时并产生错误计划:
```bash
docker compose exec -T postgres sh -lc \
'psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -v ON_ERROR_STOP=1 -c "
VACUUM (ANALYZE)
orders,
order_items,
fulfillments,
fulfillment_attempts,
fulfillment_issues,
internal_skus,
sku_channel_routes,
manual_fulfillment_configs,
product_catalog,
cost_snapshots,
sales_daily_facts,
finance_journal_entries
"'
```
命令失败时停止上线;不要用放宽超时替代统计刷新。
### 5.6 启动新后端
先只启动后端,不启动 Web:
```bash
docker compose up -d --no-deps --force-recreate backend
docker compose exec -T backend sh -lc \
'curl -fsS http://127.0.0.1:3000/health/ready'
```
要求:
- 健康检查返回成功。
- 后端日志中定时任务系统显示已停用。
- 不允许用旧镜像执行此步骤。
## 六、迁移后审计
### 6.1 数据回填与订单级核销补投
调度任务保持关闭,执行:
```bash
bash deploy/post-deploy.sh --only=backfill
```
要求:
- 命令退出码为 `0`。
- `revenue:backfill` 完成后 `revenue_basis = 'unknown'` 为 `0`。
- `voucher:backfill-order-received` 完成最近 7 天订单级核销补投,剩余待入队为 `0`。
- 新任务来源为 `order_received`,`target_key` 使用 `order:<订单ID>`。
- `VACUUM ANALYZE` 成功。
`post-deploy.sh` 末尾仍可能打印旧上线手册链接和“从接单模板初始化”提示;
以本手册为准,不要按旧提示重复初始化商品。
### 6.2 商品路由审计
```bash
docker compose --profile tools run --rm --no-deps tools \
npm run audit:product-routing -- --strict
```
以下结构性异常必须为 `0`:
- 无主路由且无人工配置的 `man:` 商品。
- 同一内部 SKU 多主路由。
- `manual / third_party_voucher` 商品缺少内部 SKU。
- 非法商品来源。
`fallback_without_primary`、`missing_manual_route` 和未路由商品可以保留为
“待分类”,但必须逐类记录数量,交业务负责人在本轮维护窗口内确认。
严格审计可能因这些已知待分类项返回非零;只有确认失败项全部属于已签字类别、
且上述结构性异常均为 `0` 时,才允许继续。
### 6.3 履约审计
```bash
docker compose --profile tools run --rm --no-deps tools \
npm run audit:fulfillment -- --strict
```
以下完整性指标必须为 `0`:
- 正式履约缺失。
- 正式履约状态差异。
- 执行尝试缺失。
- 开放异常缺失。
- 履约事件未关联正式记录。
- 近 24 小时重复尝试。
以下业务异常不得增加,并必须已经进入结构化待办:
- `missing_internal_sku`
- `missing_channel`
- `manual_config_missing`
- `carrier_missing`
- `state_inconsistent`
- `user_refund`
- `platform_cancelled`
其中 `state_inconsistent`、售后关闭仍进入履约队列、已分配但无有效载体属于
恢复营业前必须处理或由业务负责人明确签字的阻塞项。
2026-11-08 演练基线:
- 待处理履约项 `476`。
- 状态不一致 `7`。
- 售后关闭仍进入履约队列 `24`。
- 已分配但无有效载体 `27`。
### 6.4 财务重建 dry-run
先定义本次财务回看区间:
```bash
RECONCILE_FROM=2026-08-11
RECONCILE_TO=2026-11-08
```
执行 dry-run:
```bash
docker compose --profile tools run --rm --no-deps tools \
npm run finance:rebuild-derived -- \
--date-from="$RECONCILE_FROM" \
--date-to="$RECONCILE_TO"
```
检查:
- `closedPeriods` 为空;若包含已关账期间,停止并先走财务确认流程。
- `scopeItems > 0`。
- `protectedTotals` 与生产基线一致。
- `plan` 中的 estimated 快照、销售事实和总账调整数量能够解释。
### 6.5 业务配置
为完成后台操作,启动 Web;此时公网仍必须停留在维护入口,不能对普通用户开放:
```bash
docker compose up -d --no-deps --force-recreate web
```
由业务负责人完成,脚本不能代替:
1. 钱包管理 → 补建客服备用金账户并按需拨付。
2. 商品与成本 → 积分钱包 → 发放三平台积分。
3. 商品与成本 → 标准商品 → 按需执行「按工单回填商品」和「归一人工商品」。
4. 商品与成本 → 人工 SKU 配置 → 扫描并逐项配置。
5. 商品与成本 → 标准商品 → 处理未路由、待分类和人工兜底项。
> 迁移 `122` 已负责接单模板商品初始化。本手册不再要求执行旧的
> “从接单模板初始化”步骤。
完成业务配置后重新执行商品路由审计,并记录前后数量变化。
### 6.6 财务重建
业务配置完成后,重新执行 6.4 的 dry-run,确认 `protectedTotals`、已关账期间和
计划数量仍符合预期。业务负责人确认后再执行:
```bash
docker compose --profile tools run --rm --no-deps tools \
npm run finance:rebuild-derived -- \
--date-from="$RECONCILE_FROM" \
--date-to="$RECONCILE_TO" \
--execute \
--confirm=REBUILD_DERIVED
```
要求:
- `protectedTotals` 前后完全一致。
- 订单、订单项、收入、退款、人工支出和资金流水守恒。
- 已过账总账只追加反向/补差凭证,不删除历史凭证。
- 所有成本缺口都进入结构化异常,不做自动猜测。
再执行一次相同命令验证幂等:
```bash
docker compose --profile tools run --rm --no-deps tools \
npm run finance:rebuild-derived -- \
--date-from="$RECONCILE_FROM" \
--date-to="$RECONCILE_TO" \
--execute \
--confirm=REBUILD_DERIVED
```
第二次必须满足:
- `ledger.adjusted = 0`。
- `protectedTotals` 再次保持完全一致。
然后执行:
```bash
docker compose --profile tools run --rm --no-deps tools \
npm run audit:finance -- --strict
```
要求 `critical` 为空。
## 七、上线验收
停止调度任务期间执行:
```bash
bash deploy/post-deploy.sh \
--only=verify \
--launch-at='YYYY-MM-DD HH:mm:ss+08'
```
要求:
- 退出码为 `0`。
- FAIL 必须为 `0`。
- WARN 必须逐项记录并由业务负责人签字。
- `audit:finance --strict` 必须同时通过。
2026-11-08 演练中,在做完财务重建后仍有:
- `07 客服备用金账户已补建`:需在后台完成初始化后才可通过。
- `15 近 7 天非人工成本覆盖`:演练时为 WARN,原因为 `206`,必须确认成本缺口。
## 八、恢复营业
验收通过后:
```bash
docker compose up -d --no-deps --force-recreate web
```
然后:
1. 后台 → 平台配置 → 监控任务 → 开启任务总开关 → 保存。
2. 确认任务运行状态恢复,且下一次执行时间已生成。
3. 检查主站、打手端、领取页和订单服务链接。
必须完成以下冒烟检查:
- 后台登录。
- 订单列表、详情和筛选。
- 接单工单列表、详情和状态操作。
- 履约渠道页和商品与成本页签数量一致。
- 人工 SKU、自动发货、接单平台、第三方卡券和统一结算分类正确。
- 财务总账试算平衡。
- 打手端登录、订单页和大厅。
- 领取链接 `/h5/<订单号>`。
- 订单服务链接 `/o` 和 `/o/<订单号>`。
## 九、观察期
恢复营业后:
- 前 60 分钟持续观察错误率、慢查询、定时任务和订单入单。
- 前 7 天每天检查商品路由、履约和财务严格审计。
- 一个完整财务期间持续对平后,才允许讨论删除兼容表、`legacy_*`
字段和旧脚本。
观察期内不得删除:
- `product_channel_capabilities`
- `manual_sku_registry` 派生行
- `internal_sku_channels`
- `order_items.legacy_*`
- `fulfillments`、`fulfillment_attempts`、`fulfillment_issues`、`fulfillment_state_events`
## 十、失败与回滚
### 10.1 迁移命令失败
如果迁移尚未提交:
1. 保持 backend/web 停止。
2. 保存完整迁移日志。
3. 确认 PostgreSQL 中不存在半提交状态。
4. 修复迁移或取消本次发布。
5. 取消发布时,先切回升级前 commit 并重新构建 backend/web,再启动旧后端。
6. 不得在未确认迁移事务已回滚时启动任何一版后端。
### 10.2 迁移已提交但新后端失败
硬切后的数据库不兼容旧镜像。选择以下一种:
1. **修复前进**:保持停服,修复新后端,禁止用旧镜像连接迁移 `150`。
2. **整库回滚**:使用已通过验证的升级前备份恢复。
整库回滚:
回滚前必须先切回旧代码并重建旧镜像。否则 `restore-db.sh` 会用当前新镜像补迁移,
把刚恢复的 `146` 再次升级到 `150`。
```bash
git switch --detach '<升级前 commit>'
docker compose build backend web
bash deploy/restore-db.sh \
--key '<升级前最终备份 OSS key>' \
--config-key '<对应配置备份 OSS key>' \
--yes
```
恢复后:
1. 确认最高迁移为 `146`。
2. 启动 backend/web。
3. 执行健康检查、登录和近期订单抽查。
4. 恢复调度任务总开关。
> 当前恢复脚本只有在 4.3 硬门禁通过后才可用于回滚。
> 恢复脚本失败时,数据库可能处于部分恢复状态,必须立即停止业务并人工处理。
### 10.3 财务重建失败
财务重建是幂等的数据阶段,不应因为一次失败立即整库回滚:
1. 保持停服和调度关闭。
2. 保存失败 JSON、日志和当前 protected totals。
3. 修复数据或脚本后重跑。
4. 只有原始订单、退款、资金流水发生不守恒或数据库不可用时才考虑整库回滚。
### 10.4 验收失败
验收 FAIL 或关键审计异常时不得恢复营业:
1. 保持 backend 健康但 Web 不开放。
2. 调度保持关闭。
3. 按失败项修复或走整库回滚。
4. 修复后从对应阶段重新执行,不跳步。
## 十一、发布记录模板
```text
发布日期:
发布负责人:
数据库执行人:
验收人:
业务负责人:
升级前 commit:
目标 commit:
升级前迁移:
目标迁移:
升级前备份 key:
升级前备份 sha256:
升级前配置备份 key:
恢复验证结果:
维护开始时间:
迁移开始时间:
迁移结束时间:
统计刷新结束时间:
财务重建结束时间:
验收结束时间:
恢复营业时间:
商品路由审计:
履约审计:
财务 dry-run:
第一次财务重建:
第二次财务重建:
财务严格审计:
上线验收 FAIL:
上线验收 WARN:
已知待分类项及负责人:
最终结论:继续 / 暂停 / 回滚
```
@@ -3,7 +3,7 @@ type: 权威架构与实施计划
description: 订单、内部 SKU、履约路由、履约执行、商品、成本与财务的唯一权威口径及重构计划。
tags: [订单, 内部SKU, 履约, 商品, 成本, 财务, 迁移]
status: authoritative
version: 2.3
version: 2.4
updated_at: 2026-11-08
---
@@ -12,7 +12,7 @@ updated_at: 2026-11-08
> 状态:**唯一权威文档**。
> 最后校准:2026-11-08。
> 生产基线:迁移 `146`。
> 开发基线:迁移 `149`(仅本地,尚未部署生产)。
> 开发基线:迁移 `150`(仅本地,尚未部署生产)。
>
> 从本文件生效起,订单、内部 SKU、履约渠道、履约载体、标准商品、成本和财务相关实现,
> 只能以本文件为业务口径。其他旧分析只作为历史资料,不再具备设计或验收效力。
@@ -332,7 +332,7 @@ finance_journal_* -- 总账凭证,可重建
2026-11-08 生产只读核对结果:
- 生产迁移 `146`,本地开发基线迁移 `149`。
- 生产迁移 `146`,本地开发基线迁移 `150`。
- 启用标准商品 `1127`:`aff:` 30、`tpl:` 903、`tpv:` 46、`man:` 148。
- `man:` 商品中只有 105 个当前主渠道为人工;41 个已走其他主渠道,2 个无主渠道。
- 人工页头部显示 `107`,商品列表显示 `148`,相差的 41 个就是跨渠道旧商品。
@@ -600,6 +600,8 @@ assigned 且 carrier_status=missing 必须进入异常队列
任务/工单只维护尝试历史;订单项旧履约列冻结并统一读取 `v_order_item_current`。
- 迁移 `149`:建立 `v_finance_order_item_scope`,统一销售事实、重建与审计的收入、
退款、商品、渠道和业务日口径,并增加销售凭证按日查询索引。
- 迁移 `150`:核销任务允许订单级来源;`收到订单后`由订单入库事件直接入队,
使用 `order:<订单ID>` 去重,不读取履约渠道、载体或订单项状态。
- 商品列表、总览、渠道映射和商品下拉统一读取商品当前渠道。
- 运行期代码停止写入 `product_channel_capabilities`,该表仅保留到兼容期结束。
- 只读审计:`npm run audit:product-routing -- --strict`。
@@ -607,7 +609,7 @@ assigned 且 carrier_status=missing 必须进入异常队列
- 自动/卡券/接单主渠道商品的人工配置均保留为显式 `fallback`,没有被误升为人工主渠道。
- 1 个无主路由、无人工配置、无启用映射的 `man:` 商品已归档,未删除历史引用。
- 旧 `internal_sku_channels` 已冻结:运行时不再读、不再写,也不再有视图或触发器依赖。
- 空库从迁移 `001` 顺序执行到 `149` 已通过;新库不再保留任何旧履约影子同步触发器。
- 空库从迁移 `001` 顺序执行到 `150` 已通过;新库不再保留任何旧履约影子同步触发器。
- 无主路由的活动商品会进入“未路由”,不自动猜测渠道。
当前本地仍需业务处理的数据:
@@ -667,7 +669,7 @@ assigned 且 carrier_status=missing 必须进入异常队列
5. 全部业务读 SQL 切到 `v_order_item_current`,禁止直接读取订单项旧状态列。
6. 状态事件、任务尝试、工单尝试和配置变化触发器统一围绕正式履约表工作。
7. 真实 PostgreSQL 集成测试覆盖状态写入、幂等、事件留痕、当前尝试和配置关联。
8. 新空库 `001 → 149` 与迁移 `145` 备份升级库均完成硬切验证。
8. 新空库 `001 → 150` 与迁移 `145` 备份升级库均完成硬切验证。
验收:
@@ -745,6 +747,8 @@ npm run audit:finance -- --strict
- 数据库迁移由 `154–168` 重组为 `147–149`:内部 SKU/商品路由、履约执行、
财务派生三段各一个文件;未迁入旧 `dev` 的 `147–153`。
- 迁移 `150` 增加订单级收单核销来源。订单入库后仅按平台策略投递
`order_received` 任务,不再依赖渠道或载体;旧 `unmatched` 开启时自动继承一次。
- 删除会直接写已改名订单项列的 `reclassify-post-cutover.ts` 和
`merge-duplicate-products.ts`。
- 删除重复的 `finance:rebuild-cutover` 入口,部署脚本统一调用
@@ -760,7 +764,7 @@ npm run audit:finance -- --strict
生产升级演练(本地临时库):
- 输入:`backups/postgres/order_site-20261106-192520.dump`,备份迁移 `145`;
恢复后执行 `146 → 149`。
恢复后执行 `146 → 150`。
- 数据规模:订单 `456777`、订单项 `456762`、商品 `1572`、正式履约 `456762`。
- 升级和迁移全部成功;恢复时唯一失败的是备份自身依赖顺序导致的函数索引,
在函数恢复后按原定义补建,随后迁移 `148` 正常删除该索引。
@@ -867,11 +871,12 @@ docs/archive/
本地阶段 0–6 已按硬切方案完成,生产仍停留在迁移 `146`。后续顺序固定为:
1. 生产执行前重新生成全量备份,并核对备份迁移号确为 `146`。
2. 在生产依次执行迁移 `147 → 149`,每阶段运行对应严格审计;
无法确定的数据进入未路由或待分类,不做猜测。
3. 执行一次 `finance:rebuild-derived` 的 dry-run,核对 A 级数据守恒后,
再按窗口执行 `--execute --confirm=REBUILD_DERIVED`。
4. 观察一个完整财务期间,确认页面、履约、事实和总账持续对平。
5. 观察期结束后,再单独发布兼容表、旧脚本别名和 `legacy_*` 字段的删除迁移。
1. 生产升级只按 [生产升级操作手册](生产升级操作手册.md) 执行。
2. 升级前备份必须完成隔离恢复验证;恢复验证未通过时禁止迁移。
3. `147 → 150` 作为同一硬切迁移组执行,迁移后刷新统计并完成商品、履约、
财务三组严格审计;无法确定的数据进入未路由或待分类,不做猜测。
4. 执行 `finance:rebuild-derived` 的 dry-run,核对 A 级数据守恒后,
再按窗口执行 `--execute --confirm=REBUILD_DERIVED`,并验证第二次重建幂等。
5. 观察一个完整财务期间,确认页面、履约、事实和总账持续对平。
6. 观察期结束后,再单独发布兼容表、旧脚本别名和 `legacy_*` 字段的删除迁移。
+6 -2
View File
@@ -219,7 +219,7 @@ docker compose ps
docker compose logs -f backend
```
## 财务/成本上线后的初始化(当前开发基线 149)
## 财务/成本上线后的初始化(当前开发基线 150)
代码与迁移只负责建表;**存量订单回填、备用金账户、积分余额、商品目录、人工 SKU 不会自动创建**。
部署成功后按「回填 → 商品初始化 → 财务同步 → 验收」四步走:
@@ -228,7 +228,7 @@ docker compose logs -f backend
```bash
bash deploy/post-deploy.sh --dry-run # 先看计划与待回填量
bash deploy/post-deploy.sh --only=backfill # ① 收入回填 + ② 履约方式回填
bash deploy/post-deploy.sh --only=backfill # ① 收入回填 + ② 订单级收单核销补投
```
> 不要在商品目录为空时直接跑 `--only=sync`:财务同步会为每个未归一订单项写一条
@@ -288,6 +288,10 @@ cd /home/order_site && git pull
bash deploy/ubuntu-deploy.sh # 想看这次会做什么:加 --dry-run
```
如果本次包含数据库迁移、履约/商品路由切换或财务派生数据重建,不要直接执行上述命令,
必须按照 [生产升级操作手册](生产升级操作手册.md) 的停写、备份验证、迁移、审计、
财务重建和验收顺序执行。
后端启动时自动执行未应用的增量迁移,一般不必单独跑迁移。
确认: