完善微博半自动凭证与本地开发环境

This commit is contained in:
yml
2026-11-13 22:52:51 +08:00
parent 90173e3bd7
commit 654c087c1b
32 changed files with 1701 additions and 223 deletions
+18
View File
@@ -17,6 +17,24 @@ updated_at: 2026-11-08
> [部署启动与数据库重建](部署启动与数据库重建.md)。
> 只要包含迁移、表结构切换或派生数据重建,必须按本手册执行。
> 2026-11-13 增量待发布基线:`dev_11.9_2` 从生产迁移 `151` 增量到 `156`。
> 该次变更包含 `152_order_source_facts_immutable.sql`、`153_semi_auto_fulfillment.sql`、
> `154_semi_auto_connector_mode.sql`、`155_semi_auto_connector_mode_embedded.sql`、
> `156_semi_auto_credentials.sql`。在发布负责人确认目标提交并完成隔离恢复演练前,只作为开发基线,
> 不得按旧的 `147–150` 一条路径直接上线。
### 1.1 迁移 `151 → 156` 增量门禁
- 升级前必须确认生产最高迁移仍为 `151`;分支合并后重新核对迁移号,禁止回退或改写 `151` 及以前文件。
- `156` 新增账号级加密凭证表、`semi_auto_tasks.credential_id` 和
`semi_auto.credential.export` 权限;不迁移或清理订单、退款、资金流水等 A 级事实。
- 发布环境必须预先配置稳定的 `SEMI_AUTO_CREDENTIAL_ENCRYPTION_KEY`(至少 32 字符)。
未配置或仍为示例值时,生产运行时校验会拒绝启动。
- 迁移完成后至少验证 `semi_auto_credentials` 表、任务外键、索引和导出权限存在;
用测试库完成 `001 → 156` 空库迁移,并在隔离库验证 `151 → 156`。
- 该增量仍包含迁移,普通停机发布不能使用 `deploy/ubuntu-deploy.sh` 在旧后端运行时直接换库;
必须沿用本手册的停写、最终备份、隔离恢复验证、迁移、新后端健康检查和验收流程。
## 一、本次升级基线
以下信息是 2026-11-08 的首次执行基线。后续每次升级必须由发布负责人更新,
@@ -3,16 +3,16 @@ type: 权威架构与实施计划
description: 订单、内部 SKU、履约路由、履约执行、商品、成本与财务的唯一权威口径及重构计划。
tags: [订单, 内部SKU, 履约, 商品, 成本, 财务, 迁移]
status: authoritative
version: 2.10
updated_at: 2026-11-09
version: 2.11
updated_at: 2026-11-13
---
# 统一订单、履约与财务模型
> 状态:**唯一权威文档**。
> 最后校准:2026-11-09。
> 最后校准:2026-11-13。
> 生产基线:迁移 `151`。
> 开发基线:迁移 `155`(仅本地,尚未部署生产)。
> 开发基线:迁移 `156`(仅本地,尚未部署生产)。
>
> 从本文件生效起,订单、内部 SKU、履约渠道、履约载体、标准商品、成本和财务相关实现,
> 只能以本文件为业务口径。其他旧分析只作为历史资料,不再具备设计或验收效力。
@@ -286,14 +286,26 @@ manual fulfillment
- 是否启用半自动履约由 `manual_fulfillment_configs.semi_auto_*` 显式配置,不能按商品名或平台前缀猜测。
- 半自动任务必须绑定 `order_item_id`、`fulfillments.id` 和人工履约配置,不得伪造接单平台工单。
- 登录状态、绑定状态、执行状态必须正交保存于 `semi_auto_tasks`;不得写入 `material_json` 作为正式状态。
- 平台 CK 只能由 Connector 的短期凭证域托管;order_site 数据库不保存、不返回、不记录原始 CK。
默认真实 Connector 内置于 order_site 进程,远程 Connector 仅是可选隔离部署方式;两者均为进程内存会话,
重启即失效。多实例或多副本部署必须迁移到 Redis 或加密凭证存储。
- 平台 CK 是账号级凭证,唯一持久化真源为 `semi_auto_credentials`。Cookie 集合按平台 UID 唯一保存,
使用 AES-256-GCM 加密后写入 `credential_ciphertext`,并记录来源、更新时间、健康状态和最近检查错误。
`semi_auto_tasks.credential_id` 只引用账号凭证,任务表不保存 CK 明文。
- Connector 会话仍是进程内短期缓存,但不再是唯一真源。进程重启、会话过期或实例切换后,
执行器必须从账号级密文凭证恢复会话;恢复前校验平台 UID,恢复失败时更新凭证健康状态并要求重新登录。
- 生产必须配置稳定且至少 32 字符的 `SEMI_AUTO_CREDENTIAL_ENCRYPTION_KEY`。该密钥不得与日志、
任务事件、接口响应或导出内容一起保存;未完成历史凭证重加密前不得直接更换密钥。
- CK 不得进入普通任务 DTO、客户页面、任务事件、错误日志或审计明细。人工后台默认只展示平台 UID、
凭证来源、健康状态和更新时间;仅持有 `semi_auto.credential.export` 权限的角色可受控导出单个任务的
账号 Cookie,导出响应必须禁止缓存,审计只记录任务、凭证 ID 和平台,不记录 Cookie 内容。
- 微博登录必须保留完整域名/路径 Cookie Jar,不能在跨域跳转后把所有同名 Cookie 合并成单个字符串。
浏览器注入只下发与目标 URL 匹配的 Cookie;账号级凭证保存完整集合,以便后续会话恢复和跨域重放。
- 微博手机号登录首次发码返回 `mfa_1` 时,客户必须在浏览器完成网易易盾安全验证,再使用同一会话的
`mfa_id` 重发短信;服务端不尝试绕过或伪造人机验证。
- 半自动任务通过 `connector_mode` 显式记录 Connector 来源:
`embedded` 为 order_site 内置真实实现并作为默认值,`external` 为显式配置的远程真实实现,
`mock` 为 order_site 内置开发 Mock 且仅在非生产环境可用。开发 Mock 造单时默认选择 `embedded`,
只有需要完全脱离虎牙接口联调页面时才显式选择 `mock`。
- 虎牙二维码登录有效期 `5` 分钟;登录成功后的 CK 会话有效期 `24` 小时;角色绑定二维码 `5` 分钟;
- 虎牙二维码登录有效期 `5` 分钟;登录成功后的 Connector 内存会话有效期 `24` 小时,
账号级 CK 由加密凭证保存并通过健康检查判定有效性;角色绑定二维码 `5` 分钟;
浏览器一次性注入票据 `2` 分钟且消费后立即失效。重新登录前必须撤销旧 Connector 会话。
- 虎牙账号已经绑定游戏角色时,客户必须确认当前角色是否为本次需要的角色:选择“使用当前角色”时
不再调用虎牙换绑接口;选择“角色不对,重新扫码换绑”时重新生成绑定二维码,并在确认新角色时
@@ -359,7 +371,7 @@ finance_journal_* -- 总账凭证,可重建
| 执行尝试 | 履约尝试服务 | `fulfillment_attempts` | 用最大 ID 猜当前任务 |
| 当前异常 | 履约异常服务 | `fulfillment_issues` | 自由 JSON 字符串代替问题模型 |
| 半自动任务 | 半自动任务服务 | `semi_auto_tasks` / `semi_auto_task_events` | 把登录/绑定/执行状态写进 `material_json` |
| 客户平台 CK | 外部平台 Connector | Connector 短期凭证域 | order_site 或浏览器页面持久化原始 CK |
| 客户平台 CK | 半自动凭证服务 | `semi_auto_credentials` 加密凭证 | 明文落库、写日志、普通接口返回或未审计导出 CK |
| 标准商品 | 商品主数据服务 | `product_catalog` | 用商品来源反推渠道 |
| 平台商品到财务商品 | 商品归一服务 | `channel_product_mappings` | 人工在多个页面重复维护 |
| 成本规则 | 成本中心 | `cost_versions` | 业务表直接改金额 |
@@ -530,7 +542,9 @@ has_active_cost
平台登录 → 角色绑定 → 客服处理 → 完成
```
页面只能展示客户完成操作所需的最小信息,不得展示 CK、内部成本或其他订单。后台不得展示原始 CK,只展示平台 UID、绑定角色、凭证有效性和一次性注入入口。
页面只能展示客户完成操作所需的最小信息,不得展示 CK、内部成本或其他订单。后台默认只展示平台 UID、
绑定角色、凭证来源、健康状态、更新时间和一次性注入入口;持有独立导出权限的角色可按任务受控查看
账号 CK,导出动作必须留审计且不得复用普通详情接口。
## 八、存量数据处理方案
@@ -934,9 +948,10 @@ docs/archive/
## 十三、当前下一步
截至 2026-11-09,生产基线为 `151`,本地开发基线为 `155`。迁移 `152` 保护订单来源快照,
截至 2026-11-13,生产基线为 `151`,本地开发基线为 `156`。迁移 `152` 保护订单来源快照,
迁移 `153` 增加人工渠道半自动任务,迁移 `154` 增加半自动任务的 Connector 来源,
迁移 `155` 将内置真实 Connector 设为默认并扩充来源约束。
迁移 `155` 将内置真实 Connector 设为默认并扩充来源约束,迁移 `156` 增加账号级加密凭证、
任务凭证引用和受控导出权限。
1. 生产升级只按 [生产升级操作手册](生产升级操作手册.md) 执行。
2. 升级前备份必须完成隔离恢复验证;恢复验证未通过时禁止迁移。
@@ -945,7 +960,7 @@ docs/archive/
4. 执行 `finance:rebuild-derived` 的 dry-run,核对 A 级数据守恒后,
再按窗口执行 `--execute --confirm=REBUILD_DERIVED`,并验证第二次重建幂等。
5. 观察一个完整财务期间,确认页面、履约、事实和总账持续对平。
6. 半自动履约第一版先接入虎牙扫码登录、角色绑定、一次性浏览器注入和人工完成确认;
微博只保留平台扩展位,不提前写死平台专用状态。
6. 半自动履约继续完善微博手机号登录、易盾二次验证、完整域名 Cookie 保存、会话恢复和受控导出;
所有平台继续复用账号级凭证模型,不把平台专用 CK 状态写回订单或商品字段。
7. 观察期结束后,再单独发布兼容表、旧脚本别名和 `legacy_*` 字段的删除迁移。
+6 -1
View File
@@ -152,6 +152,7 @@ CLAIM_BASE_URL
POSTGRES_PASSWORD
DATABASE_URL
ADMIN_SESSION_SECRET
SEMI_AUTO_CREDENTIAL_ENCRYPTION_KEY
ADMIN_DEFAULT_USERS_JSON
CORS_ALLOWED_ORIGINS
STORAGE_MODE
@@ -164,6 +165,10 @@ STORAGE_OSS_REGION
其中 `APP_DOMAIN`、`CORS_ALLOWED_ORIGINS` 与 `STORAGE_MODE=oss` / `STORAGE_OSS_*` 为生产必需:`docker-compose.yml:95` 的 `STORAGE_MODE` 生产默认即 `oss`,`apps/backend/src/config/runtime-validation.ts:107-114` 在生产环境强制校验 `STORAGE_OSS_*` 凭据并使用显式 CORS 域名白名单;`.env.server.example` 已给出这些变量的模板值,其中带 `change-me` 的占位会被 `deploy/ubuntu-deploy.sh` 的占位值检查拦住,需替换为真实值。
`SEMI_AUTO_CREDENTIAL_ENCRYPTION_KEY` 用于加密半自动履约的账号级平台 CK,生产必需且至少 32 个字符。
该密钥必须长期稳定保存;直接更换会导致已有 `semi_auto_credentials` 无法解密。需要轮换时,先实现并验证
旧密钥解密、新密钥重加密的数据迁移,不能只修改环境变量。
容器内连接 Compose PostgreSQL 时,主机名用 `postgres`:
```text
@@ -219,7 +224,7 @@ docker compose ps
docker compose logs -f backend
```
## 财务/成本上线后的初始化(当前开发基线 150)
## 财务/成本上线后的初始化(历史基线 150)
代码与迁移只负责建表;**存量订单回填、备用金账户、积分余额、商品目录、人工 SKU 不会自动创建**。
部署成功后按「回填 → 商品初始化 → 财务同步 → 验收」四步走: