Files
docs/统一认证与服务通信契约.md
T
2026-10-08 17:08:00 +08:00

44 KiB
Raw Blame History

统一认证与服务通信契约

2026-10-08灰度拼车角色页面补验:专用两销售按本人意向隔离,报价库入口按权限显示;最小调度可确认承运,客户A可见自身商业订单、客户B列表为空。海外PDA浏览器初次登录暴露Gateway CORS漏配两个PDA Origin,已同步灰度持久环境与Jenkins环境文件并仅重建原镜像Gateway;四合法前端Origin通过、其他Origin仍403,海外PDA真实登录、收货与整车发车均通过。此前无Origin HTTP冒烟不代表此浏览器边界已验证。本轮证据、保留账号及硬件验收边界见测试环境主契约同日“灰度拼车角色页面与 PDA H5 补验”节及 reports/gray-ui-20261008/。

2026-10-08新增拼车灰度专项通过:独立GRAY入口735项HTTP断言通过,包含两销售同姓名不同身份隔离、无权确认/他人修改拒绝、客户不能读内部池及其他客户商业单;两类本土订单从实际收货至完成及唯一费用已核对,临时角色/账号停用与会话注销记录保留。取证绑定灰度production容器与数据库,不回落TEST;精确批次、creation_mode字段修复及终态回查见测试环境主契约同日拼车专项节。

2026-10-08内部拼车首版已发布临时灰度:IAM新增五项池权限及平台管理员授权,灰度新登录经统一Gateway和Admin公网代理均能读取池、本人/全部意向及仅id/code/name客户目录,退出成功。Lastleg/Admin/Client灰度版本、SQL精确范围及资源SHA验证见测试环境主契约同日发布节;其余认证服务、Gateway与PDA未重新发布。该冒烟不替代TEST的跨销售/客户隔离和完整业务链证据。

2026-10-07内部拼车需求池TEST身份验收:reports/fleet-cross-pool-20261007-r5/report.json 732项通过,独立r5审计核对原始响应与库存证据,其中两名同显示名、不同登录ID销售按本人意向隔离,最小调度manage权限可处理承运;销售不能确认占位,Client不能读取平台池,池来源商业单旧手工操作旁路被拒。凭据与会话均经统一Auth/ Gateway,执行后退出脚本会话;该HTTP证据不替代两端角色页面验收。Admin真实浏览器打开发布详情时自然遇到401,随后一次refresh200、权限快照200、原详情重放200,未形成多次刷新循环;网络与响应证据分别为 reports/capacity-pool-20261007/admin-pool-detail-network.json、admin-pool-detail-status.json。该场景首次详情有一次认证拒绝和一次成功请求,不能计作零认证重试的单次请求。本轮最小销售、调度及客户页面与请求预算已完成分层核对;48条最终合同映射必要未关闭项为0,部署版本和各证据层级以测试环境主契约及 supplemental-ui-audit.json 为准。报价正向补证为本地组件/API测试,不扩大为真实HTTP声明。

2026-10-07灰度退税 FBA 定向闭环补证:主单 FL2107698725471256577 及其余量单通过统一灰度 Gateway/Auth 完成国内装柜、报关、人工船节点、海外 PDA 收货、发车签收和完成回传,1325项断言通过。收货库存与原键重放使用灰度数据库只读快照核对;两来源完成 Outbox 各唯一一条 PUBLISHED,pending/failed均0,签收资料重复保存未新增完成事件。独立新会话回查主/余量订单均 COMPLETED、入仓均 DELIVERED;此证据仅证明本轮正常业务链和所执行的幂等边界,不代替灰度故障注入或 TEST 默认全量。准确版本、过程两次失败、脚本选仓修复、月度测试汇率及未覆盖范围见测试环境单机部署与配置契约临时灰度节;原始证据 reports/gray-release-20261007/gray-flow-tax-r3.json、gray-flow-tax-final-verification-r3.json。

2026-10-07临时灰度统一认证已实际部署并验证:四端共用独立灰度Auth、签名密钥、Redis会话前缀和Nacos命名空间;两个API域名指向同一Gateway,不再运行独立海外Gateway或事件桥。四角色登录、权限、核心读取及Access/Refresh撤销48项通过,四个各自公网入口追加16项代理/登录/退出检查通过,JWT均为本次灰度签名身份;没有将内部服务接口暴露到公网。灰度旧Redis用户名错误已修正,临时管理员密码对齐用户安全配置,新建验收客户和国内PDA经正式接口创建。详细运行版本、账号交付位置、过程失败及验收边界以测试环境单机部署与配置契约的临时灰度发布节为准。

2026-10-05本轮收口:用户明确跳过测试邮件/告警通知、外部船司自动查询以及V02凭证图片像素核对,均记录为“用户跳过”,不计为测试通过,也不关闭产品功能。结合下列最新补验证据,本轮约定范围已完成;最终范围、运行版本及保留边界统一见测试环境单机部署与配置契约的最新验收状态。下方各日期记录保留当时证据范围,不将旧待补验描述作为新的阻塞。

2026-10-05 0A首次同/异hash并发补验:两组隔离合法换标业务先持本客户账户行锁,真实MySQL锁等待证明原自然消费者持有Inbox且两个手工请求在首次结果未成立时并发等待。门锁分别1.046秒/3.868秒;same原事件a92f9c14-548b-4119-b94e-7fc6c4e8d30c两手工DUPLICATE,different原事件8baa9074-d60a-4c33-90a9-aaab356a9697的不同载荷只改remark、实际运行库Java校验合法摘要,返回FIN-EVT-002身份冲突(不是坏摘要)。原自动消费者加两个手工请求分别留下完整时序与SQL锁链;每组唯一0.01冻结及唯一结果、源Outbox/结果Outbox PUBLISHED、Lastleg结果Inbox PROCESSED。只读终态复核、会话退出、账户锁连接/锁0、运行指纹/健康未变及远端临时文件清理见后端reports/wallet-first-execution-concurrency-root-20261005-r1/root-independent-review.json与root-final-runtime-cleanup.json;11份原文件已归档。关闭此首次并发要求,不宣称其他消费者或全局压力测试通过。

2026-10-05 结果提交失败原子性补验:合法RL-WH-20261005-264066原指令00c6799d-743c-4137-a499-c1a3a852e835在资金及成功结果Outbox均写入同一事务后,于最后UPDATE Inbox命中限定SQLSTATE45000/1644;资金余额/版本、hold/ledger/idempotency及本命令结果Outbox全部回滚,仅事件身份PROCESSING持久化。删除唯一触发器后同原事件/hash/envelope自然恢复,唯一0.01冻结及结果2e63d316-fbf3-4a5b-a74d-0e008c6d07bb的PUBLISHED/Lastleg PROCESSED均成立。触发器回查0、会话退出、服务容器/配置/网络指纹与健康未变;其他账户摘要未变,库存按合法重新预留与故障后恢复两个阶段核对。后端reports/wallet-result-commit-20261005-r1/root-independent-review.json复核18项原始条件及证据SHA,保留先前合法余额不足FAILED事件。本次关闭对应原子性与原事件恢复缺口;首次同/异hash并发由本文件开头另列的独立场景补证,不冒充已找回历史原0A报告。

2026-10-05 Client退出补验关闭:修复随Client384发布,当前385只追加报关统计文案。正常UI退出恰好一次带Bearer的logout200/200,返回登录页;原Access尚未过期即被受保护接口401/A0401拒绝,原Refresh为HTTP200/A0401。自然过期分支使用独立正式登录会话,原Access于11:02:51 UTC到期后实际确认退出,完整网络严格为logout401/A0401→refresh200/200→logout200/200,只有一次刷新;原与替换Access/Refresh全部被拒,替换Access在11:06:36 UTC验证时尚未到11:27:34 UTC自然到期。身份长整数以私有原JWT精确核对,原及替换Bearer与真实UI请求匹配;未改时钟、TTL或伪造响应。后端reports/f22-201-browser-20261005-root-r4/final-result.json、normal-logout-independent.json、expiry-independent.json及网络/DOM/截图为证据,客户端自建标签已关闭、临时视口恢复。仅关闭该客户端正常与自然过期退出分支,不外推未运行的并发或未知传输分支;部署及其他未关闭项见测试环境主契约。

2026-10-05 自然租约与旧持有者CAS补验:新合成换标RL-WH-20261005-915970的WalletCommandCompleted结果a109b5d8-2ff6-4d00-bfba-bf17594b6012由独立非Spring JVM使用当前Finance125生产Relay/Journal领取一次;真实内部ACK已收到后,本进程屏障等待原60秒租约自然过期。正式共享Finance在62020ms标LEASE_EXPIRED、按原退避另由新owner获得DUPLICATE/PUBLISHED;先保存独立SQL快照,再放行旧真实ACK,原deliver返回前后Outbox、两审计及本包Finance/Lastleg业务数据完全不变,唯一0.01冻结。没有改锁时间/重试时间/TTL、暂停共享服务或假ACK;生产类库/容器/配置/Nacos未变,临时JVM/worker退出且自有文件清理。后端reports/outbox-lease-live-20261005-r1/root-business-verification.json、root-ledger-verification.json、root-final-verification.json及其运行证据为依据。仅关闭指定生产Relay/Journal的晚到成功CAS;一次性客户端为JDK真实HTTP,不宣称Feign故障、全部消费者或压力测试通过。

2026-10-05 船节点限定消费补验:独立新柜D1442/TSTU1527735正常装柜事件APPLIED后,3条受内部服务身份保护的直接请求依次得到APPLIED、STALE、EVT_PROTOCOL摘要冲突。新事件ID的低版本/低节点不回退有效事实;原eventId配不同但规范合法的payloadHash拒绝且原Inbox/gate不变,捕获的客户订单/库存及原装柜Outbox/Inbox/投递审计不变。后端reports/shipping-event-canonical-20261005-r1/root-final-verification.json与root-original-source-unchanged.json为真实HTTP/MySQL证据,生产canonical原类计算字节/hash;不是篡改旧Outbox,也不宣称外部船司、其他消费者或自然租约故障通过。

2026-10-05 国内PDA退出修复已发布:e699e9d9bacb捕获原会话后立即清理敏感草稿,等待服务端撤销再跳转;明确HTTP401时最多刷新一次并撤销同主体的新凭据,不将该凭据写回本地。并发自动刷新共享原请求且旧响应不能恢复已退出或覆盖后续登录;未知网络失败不盲目重试,明确提示服务端退出未确认。总控176项本地测试、5项Gateway合同及HBuilderX5.26实际构建通过,TEST静态包逐66文件核对通过;本机390×848正常页面退出已捕获唯一logout200、无refresh,原Access在尚未过期时受保护接口401/A0401,原Refresh200/A0401且不签新凭据;reports/domestic-pda-logout-ui-20261005-r1/normal-final-evidence.json及root-normal-independent-verification.json为证据。自然过期退出已补验:原Access14:10:30自然到期,14:11:54在原tab确认,真实logout401→refresh200→logout200;原及替换两组Access/Refresh均A0401且不签新凭据,替换Access在14:13:30拒绝时尚未到14:35:53的自然到期时刻。root私有核对两组身份/原exp及替换iat、完整网络,查看原390×848截图并记录导出像素差异;原标签关闭、视口恢复。证据为同目录expiry-final-evidence.json与root-expiry-independent-verification.json,仅关闭国内本分支。部署证据见测试环境主契约及后端reports/domestic-pda-logout-release-20261005-r2/root-runtime-verification.json。

2026-10-05 Gateway Redis连接不可用补验:仅同镜像Gateway临时覆盖Redis客户端host/port,指向容器自身无监听端口19391;共享Redis、Auth/IAM保持运行。实际日志确认连接拒绝;两组原有效Admin/PDA Access在直达及公网入口均401/A0401,同时Auth权威接口对同会话仍200/true。聚合health503/DOWN未当作认证拒绝证据。恢复原镜像完整配置/Nacos后,同Access摘要的直达和公网请求均200、health200/UP,Auth/IAM原容器/配置未变,运行FINISHED且会话退出。后端 reports/redis-gateway-failclosed-20261005-r1/root-final-verification.json(26项)保存HTTP、运行状态及私有原故障日志摘要。第一次准备因namespace链接权限失败的原记录保留,确认无state且原服务未改后仅归档自有初始化;没有停共享Redis、清键或变更超时预算。本项只证明Gateway自身Redis连接故障的失败关闭和原凭据恢复,不覆盖全部Redis消费者及剩余消息可靠性场景。

2026-10-05 IAM→Auth撤销响应超时补验:仅新合成PDA账号auth2106926470848942081/member2106926470848942083的一次正式仓绑定PUT,Auth /internal/auth/accounts/sessions/revoke 已真实成功后,代理精确延迟该响应6秒;IAM在5277ms返回HTTP200/S0503。真实SQL核对完整IAM成员/用户/角色/主体权限版本均回滚,仍为洛杉矶原仓和权限版本1;Auth令牌版本1→2已提交,旧Access与Refresh均A0401且没有新凭据,对照账号200。恢复原IAM运行配置后新登录仍正常访问原仓,证明IAM回滚没有复活已撤销会话。原镜像/完整配置/Nacos摘要一致,Auth与Gateway原容器未变并健康;代理/端口/锁清理、有效会话退出,唯一新账号经正式接口停用并由SQL确认。证据为后端 reports/auth-revocation-timeout-20261005-r1/root-final-verification.json(26项核对)及所引HTTP、代理时间记录和三份真实SQL快照。只关闭此“远端成功、调用方响应超时”的撤销分支,不覆盖Redis故障及所有IAM/Auth变更;未采集原IAM异常栈,不推定具体异常类。

2026-10-05 Gateway权威会话校验超时补验:精确TEST PDA账号及jti的单次 /internal/auth/accounts/sessions/validate 调用延迟6秒,外部受保护请求在4142ms返回401/A0401;另一平台账号的用户列表请求168ms返回200。完整5条代理事实证明只延迟指定一次校验、对照直通及Auth稍后正常200。恢复原网关后,同两组尚未过期原Access再次通过,代理记录无增长;原Gateway镜像及完整配置、Auth原容器及配置、Nacos摘要均一致并健康。代理进程和两监听端口清理、锁消失、两会话退出均已核对。后端 reports/auth-validate-timeout-20261005-r1/root-final-verification.json(23项原证据核对)及 root-final-runtime-proof.json 为本次依据。只关闭Gateway→Auth权威校验超时,不覆盖Auth撤销调用超时、Redis不可用或所有业务服务的校验分支。首次旧PDA对照登录被A0403拒绝的记录保留,原目标会话正常退出后改用现有有效平台账号,未复活旧账号、创建替代账号或更改权限。

2026-10-05 资金执行中途故障补验:合法新换标RL-WH-20261005-560514的0.01CNY冻结指令200ebc4a-f078-4fc8-af7d-2e334c123b8c,在真实MySQL账户更新/hold插入后、流水插入前命中特定SQL异常;余额/版本、hold、资金流水和业务幂等写入均回滚,仅保留PROCESSING事件身份,无最终结果/结果Outbox。专属短时触发器移除后,同eventId/hash自然重试仅冻结一次,结果Outbox发布、Lastleg结果Inbox处理和FROZEN状态均完成,原库存/流水不变;触发器不存在、独立会话退出。证据为后端reports/wallet-mid-transaction-20261005-r1/root-fault-run.json、independent-final-review.json及所引原始SQL/日志。初次余额不足FAILED前置事件另存,不把重新发布业务指令当作原故障事件恢复。本次关闭这一资金中途回滚运行缺口,其余认证/消息故障和通知链路仍分别保留。

2026-10-05 自然过期退出补验:海外PDA r2原Access于北京时间07:30:33到期、07:30:58从原个人中心点击退出;Admin原Access于07:36:13到期、07:37:07从原详情页点击退出。两端各一次真实退出确认,完整网络均为logout401→refresh200→logout200。原及替换Access均401/A0401,两组Refresh均HTTP200/业务A0401且不签新凭据;总控分别私有核对替换Access被拒时尚未自然到期。原/替换凭据同一性、登录页和标签释放均有证据,见后端reports/pda-expired-logout-ui-20261005-r1/与admin-expired-logout-ui-20261005-r1/下的final-evidence.json、root-independent-verification.json。关闭R07两个指定自然过期退出分支,其他认证故障未据此关闭。下方2026-10-04记录中的“待补验”保留为当时状态,以本段较新证据为准。

2026-10-04 本轮权限与退出补验:既有转运执行权限 lastleg:warehouse-transfer:manage 已在 IAM 模块及统一基线注册,TEST 仅给默认平台管理员增加该授权,并推进受影响主体权限版本。新登录正式权限接口已确认执行/审核/库存列表权限,退出成功;证据 baiyue-firstleg/reports/transfer-permission-login-verify-20261004-r1.json。海外 PDA b247b0c 正常主动退出已用真实页面验证,一次 Auth logout 成功后原 Access 与 Refresh 均拒绝且不签发新凭据;证据 reports/pda-local-h5-ui-20261004-r1/fixed-logout-credential-proof-r1.json。自然过期令牌退出分支仍待真实 UI 补验,不以单元测试代替。装柜 B 柜唯一实际来源完成事件、APPLIED 回执及 Lastleg Inbox 摘要对应已验证,见 reports/partial-B-completion-event-proof-20261004-r1.json;只关闭该样本范围,不扩展为全部船节点/库存/车辆验收通过。

更新日期:2026-09-29。本文是已确认目标的唯一主契约;当前仅有测试环境,所有服务同机部署。部署与切换见测试环境单机部署与配置契约。

状态:统一 Token/JWKS/Redis 会话、八类可靠直接投递和单 TEST 的 13 个服务已部署。真实 HTTP 主验收 7149 项断言通过,目标装柜事件 ACK 丢失、有限重试耗尽、人工原事件恢复及幂等结果已实测;代理已停止并恢复直连。旧海外 Gateway 与事件桥已停止且退出构建/部署,遗留源码尚未删除。完整页面作业、其余真实故障矩阵及告警通知链路不能据此视为通过,整体迁移验收尚未关闭。

2026-10-03 费用可靠投递补证:F40三顺序共10条费用事件以及车辆专项外接30CNY来源费用,均已按客户/来源/版本/事件ID核对唯一Outbox与已完成APPLIED投递审计。车辆专项组合证据为后端reports/fleet-current-20261003-r2-terminal/final-evidence.json,总控已核对源报告摘要;该结论仅证明这些样本正常投递确认,不覆盖费用ACK丢失、撤销重试或完整故障矩阵。具体部署及未关闭项仍维护在测试环境主契约。

2026-10-03 Order依赖故障边界补验通过:限定本轮客户与原请求ID,客户端/平台分别验证IAM资格和Finance钱包不可用(4次),提交正确失败且订单/履约事实不变;恢复同镜像/同配置/同Nacos源后,原请求成功提交且重放不重复,代理已停止、会话已退出。运行报告为后端reports/order-dependency-fault-runtime-20261003-r1.json。请求关联在实际熔断配置下命中,无关闭熔断或扩大故障客户范围;该证据不覆盖事件ACK丢失等另一类可靠投递测试。

下文路径、响应与时序为改造目标。实际业务服务、客户隔离、仓库类型、作业角色与状态机保持原职责;不能将“同机”解释为合并数据库表或绕过权限。

A. 唯一路由与消费端映射

全部客户端共用 Gateway。下表写完整服务端路径;前端 HTTP Base 若已含 /api,业务调用不重复拼接该段。所有资源接口仍校验平台身份、客户范围及业务权限。

海外资源前缀记作 R=/api/platform/v1/overseas-warehouse-resources,权限前缀记作 P=platform:overseas-warehouse:。以下 R/P 仅用于文档缩写,不是配置变量。

方法与目标路径 目标服务 权限 主要调用方/改动
GET /api/platform/v1/warehouse-admin 及现有主档 CRUD Warehouse 维持现有主档权限,GET 为 platform:warehouse:list 主档页面与 IAM 的共享收货仓查询保留现有调用;写操作不改权限
GET /api/platform/v1/warehouse-admin/overseas-receiving-options Warehouse P+warehouse:list 新增限定用途查询;替代海外资源服务原根目录查询,返回平台公共、OVERSEAS、ACTIVE、RECEIVING 仓库,不因迁移给资源角色授予主档维护权限
GET R+/pallets、R+/pallets/summary Warehouse Overseas P+pallet:list Admin overseas-warehouse/api/pallets.ts 跨仓查询
GET R+/{warehouseId}/locations、R+/{warehouseId}/locations/{id} Warehouse Overseas P+location:list Admin overseas-warehouse/api/locations.ts
POST R+/{warehouseId}/locations Warehouse Overseas P+location:create 同上
PUT R+/{warehouseId}/locations/{id} Warehouse Overseas P+location:edit 同上
DELETE R+/{warehouseId}/locations/{id} Warehouse Overseas P+location:delete 同上
GET R+/{warehouseId}/pallets、/pallets/summary、/pallets/{id}、/pallets/{id}/label(后面三项同属 R+/{warehouseId}) Warehouse Overseas P+pallet:list Admin overseas-warehouse/api/pallets.ts,标签二进制响应保持原格式
POST R+/{warehouseId}/pallets Warehouse Overseas P+pallet:create 同上
PUT R+/{warehouseId}/pallets/{id} Warehouse Overseas P+pallet:edit 同上
DELETE R+/{warehouseId}/pallets/{id} Warehouse Overseas P+pallet:delete 同上
现有方法 /api/platform/v1/last-leg/**、/api/merchant/v1/last-leg/**、/api/pda/v1/last-leg/** Lastleg 保留对应 Controller 权限与作业数据范围 Admin、Client、海外 PDA 改用统一 HTTP/Token,业务路径保持
现有文件、打印、审计、集成公开接口 原对应服务 保留现有权限 从原双网关去重后接入唯一入口
任意 /internal/** 仅服务间内部网络 内部服务身份 Gateway 无公开路由;测试内部接口不能通过公网入口调用

新增收货仓选项查询沿用原海外目录的分页参数 page/size(size≤200)和 WarehouseOption 字段语义,由 Warehouse 直接查询权威主档,不能只通过客户端过滤实现范围限制。该用途查询需在 Warehouse Controller/OpenAPI/IAM 权限合同中明确登记。现有 IAM 查询与 Admin pallets 中 listSharedReceivingOverseasWarehouseOptions 已使用主档接口,保留其现有权限边界;仅原海外目录的直接调用者迁移到新用途接口,不批量改写无关主档消费者。

修改 PlatformWarehouseResourceController 和 PlatformWarehouseDirectoryController 的资源路径;移除海外服务中的重复目录代理和无独立必要性的公开健康路由。内部资源锁、托盘作业路径保持服务内使用。Gateway 对 /warehouse-admin/** 只指向 Warehouse,对 R 只指向 Warehouse Overseas,不按路由先后顺序或请求 warehouseId 猜测目标服务。

路由验收:逐条 method/path 唯一匹配;静态 /overseas-receiving-options 不误命中 /{id};同名旧前缀下的国内接口仍有效;海外调用方全部迁移,不为其保留旧别名;客户端角色只能读取被授权目录,不能借新增用途查询修改主档。

B. 逐事件直接投递与结果确认

以下内部路径复用当前消费者入口,统一为 POST,使用内部服务令牌、服务发现或容器服务名,不能经公开 Gateway。按 eventType 明确选择目标,不再根据 CN/OVERSEAS 选择目标;未知事件类型直接记录永久错误,不默认投某个业务服务。

eventType 当前生产与投递入口 直接目标
FirstLegLoadingPlanCompleted Firstleg LoadingCompletedOutboxService → LoadingCompletedOutboxRelay Lastleg /internal/lastleg/events
FirstLegContainerShippingNodeRecorded Firstleg CarrierScheduleNodeOutboxService → 同一 LoadingCompletedOutboxRelay Lastleg /internal/lastleg/events
OverseasContainerUnloaded Lastleg InboundUnloadCompletedOutboxService → InboundUnloadCompletedOutboxRelay Firstleg /internal/firstleg/v1/container-events
OverseasInboundOrderDetainedChanged Lastleg InboundOrderDetainedOutboxService → 同一卸柜 Relay Firstleg /internal/firstleg/v1/container-events
OverseasDeliveryCompleted Lastleg DeliveryCompletedOutboxService → 同一卸柜 Relay Firstleg /internal/firstleg/v1/container-events
BusinessFeeSourceChanged Lastleg OverseasFeeOutboxService → OverseasFeeOutboxRelay Finance /internal/finance/v1/business-fee-source-events
CompanyVehicleCostSubmitted Lastleg车辆运维费用来源 → InboundUnloadCompletedOutboxRelay;源码接入中,尚未部署验收 Finance /internal/finance/v1/vehicle-costs/events
WalletCommandRequested Lastleg WalletCommandOutboxService → InboundUnloadCompletedOutboxRelay Finance /internal/finance/v1/wallet-command-events
WalletCommandCompleted Finance 资金指令处理的结果 Outbox → WalletResultOutboxRelay Lastleg /internal/lastleg/events
IamUserStatusChanged、IamTenantStatusChanged、IamPermissionVersionChanged IAM 安全事件专用生产/Relay 不迁移业务投递;完成 C 的撤销替代验证后移除专用投影链

车辆混合履约边界(2026-10-03):OverseasDeliveryCompleted仍只表示整来源实际签收,消费者据此把来源入仓单置为DELIVERED,不表示车次结束或异常工单关闭。工作区新增接线在首次实际签收的显式READ_COMMITTED事务中,沿历史出库/拣货分组取得全部受影响来源,按订单数值ID排序加锁,再核对实际签收、退回流水与重派凭据;不能使用可被改写的当前派送号或按比例猜来源数量。签前退回的货物重派后首次签收才新增贡献;签后退回再次签收不重复累计,可追溯多跳沿同一规则。逐来源独立发布,幂等键为事件类型+客户+来源入仓单;未齐来源保留未完成和中文审计,不影响同车另一已全签来源。事件格式与消费者语义未变,只有确实整来源全签才产生既有事件;国内异常结案不在本轮自行新增。签收完成与整单完成分别验收:来源入仓已签收不跳过仍未履约的有效余量子单。匹配版本部署、逐来源实签/退回重派、事件与接收端核对、失败记录及未关闭验收项统一见测试环境主契约。

已核对:Lastleg 卸柜 Relay 的 Repository 还选择了资金指令,不能把它整体改成 Firstleg URL;费用 Relay 只选择费用来源事件。实现时使用明确的事件白名单分派,并测试资金请求不误投 Firstleg。Firstleg 现有直达 Finance 的其他费用链、Order 的既有投递和 RocketMQ 导出/通知不并入本次新路由表,保持现有行为并做受影响回归。

统一目标返回结构为 ApiResponse<DeliveryAck>,其中 DeliveryAck={eventId,payloadHash,outcome}。outcome 只允许 APPLIED(已完成消费)、DUPLICATE(已成功处理的同一事件)、STALE(该类事件明确允许忽略的旧版本)。四个内部消费路径同步修改为这个返回结构,Relay 与全部直接调用者同步更新;当前 Integer/Object/feeSourceId 等响应不作为最终成功判定依据,不引入双响应兼容。

成功必须同时满足:HTTP 2xx、body code 为字符串 200、ACK 中 eventId/payloadHash 与发送一致、outcome 为该类事件允许的值。消费端只在可靠提交后返回成功;不能刚入内存或仅保留待处理记录就返回 APPLIED。重复确认必须来自持久化幂等记录;同 eventId 不同 hash 为冲突,不允许覆盖。

消费处理的原子性按业务实现验证:普通消费者将业务变更与成功幂等记录同事务提交;第0A批已将资金执行、成功Inbox和结果Outbox收敛到同一事务,保存结果失败时资金一同回滚;事件身份独立持久化防止重试换内容。保留既有钱包业务幂等键和状态机。历史记录曾报告MySQL结果提交失败回滚、原事件恢复及首次同/异hash并发已测,但本轮定向追溯未定位这些场景的原始证据,历史结论本身不能计作可复核关闭;见reports/wallet-0a-original-evidence-trace-20261005-r1.json。结果提交失败与原事件恢复现已由本轮新合法样本补证,见本文件开头wallet-result-commit证据;首次同/异hash并发也已由本文件开头的独立真实锁等待场景补证关闭。2026-10-05又完成账户更新/hold插入后、流水插入前的真实中途故障、完整回滚及原事件唯一冻结恢复,原始证明见本文件开头的限定钱包场景;不以此替代其他故障分支。

特别约定:资金指令的投递成功不等于冻结/扣款成功。Finance 必须可靠保存 SUCCEEDED 或 FAILED 业务结果及结果 Outbox 后确认该指令已消费,Lastleg 以 WalletCommandCompleted 更新业务状态。余额不足等已形成 FAILED 结果的指令不进行无意义的传输重试;成功扣款后结果发送失败,只重试原结果事件,不能再次生成扣款指令。

情况 生产端动作 消费端要求
APPLIED / DUPLICATE 标记完成 已提交、幂等记录可核验
STALE 仅显式允许旧版本忽略的事件标记完成 证明较新版本已覆盖且不丢独立业务事实;资金和独立费用动作不能泛用 STALE
连接失败、超时、HTTP 5xx/429、临时数据库失败 原事件重试 超时后可能已提交,下次必须幂等
船节点等先于依赖单据到达 返回明确的可重试“依赖未就绪”业务错误,退避重试 不以不存在直接当成功,不靠查询顺序假设到达顺序
非法信封/版本、hash 冲突、未知类型、明确不可执行协议错误 DEAD 并保留原因 不修改业务,不兜底成功
401/403 或内部令牌错误 DEAD,标注配置/认证失败,修复后人工原样重试 失败关闭,不绕过鉴权
响应缺失、ACK 不匹配、未识别业务错误 不确认成功,有限重试后 DEAD 保留诊断信息,不能仅按 HTTP 200 通过

统一逻辑状态为待投递、投递中、重试等待、完成、DEAD;可映射到现有表字段,不要求批量改名。初始测试参数:连接超时 3 秒、单次请求超时 15 秒、租约 60 秒、累计自动尝试 12 次、退避从 5 秒翻倍上限 30 分钟,加入小幅抖动;参数需可配置。租约失效后的恢复和最终状态更新必须校验持有者,避免旧任务覆盖新任务。消费超时不能被解释为事务一定回滚。

源码配置已统一为 baiyue.event-delivery.connect-timeout-ms=3000、read-timeout-ms=15000、max-attempts=12、base-delay-seconds=5、max-delay-seconds=1800、jitter=0.1、lease-seconds=60,供四个业务 Relay 使用。事件 Feign 客户端显式应用 EventDeliveryFeignConfiguration,禁止客户端内部自动重试及重定向,最终构建参数不被旧的全局 Feign 超时覆盖;连接与读取超时之和必须小于租约时长。retry_count 表示已失败或租约超时的投递次数;普通领取不递增,领取超时任务或恢复超时租约时计入一次,自动预算耗尽后保持 DEAD。实际投递失败从失败时刻计算下一次重试时间;每次领取使用独立租约 ID 和当前时间,最终写入必须匹配该 ID。DEAD 保留原始事件,不能通过定时扫描自行恢复。人工重试、逐次审计和指标已落地并通过本地事务回归,真实 MySQL 的目标装柜事件故障恢复已验证,旧桥已停止;其他故障矩阵场景仍须按实际证据分别确认。

每次尝试在本服务 event_delivery_attempt 表记录事件、目标、时间、耗时、结果、有限错误码和下一次重试;领取与STARTED审计同事务提交后才发HTTP,持有者CAS完成与审计完成同事务,失败一同回滚。过期租约审计为LEASE_EXPIRED并退避,本轮不立即重发。按服务/类型提供 pending/DEAD 数量及最老待处理时长;指标 baiyue.event.delivery.pending/dead/oldest.pending.seconds/sample.timestamp/sample.success 默认30秒采样,Prometheus只读缓存。采样失败保留旧值并标记失败,未知初值为NaN,不误报零积压。告警接入现有能力,不为本次新增独立监控平台。人工重试采用各生产服务的受保护内部操作与配套运维脚本,不新增公开后台页面:只允许 DEAD 原事件重试,记录操作人/原因,保留 eventId/hash/payload/业务幂等键,禁止修改载荷或伪造新 ID 后重发。

人工重试源码接口已冻结:GET /internal/{firstleg|lastleg|finance}/event-operations/{entryId} 查询状态,POST 同路径加 /retry 提交 {requestId,operator,reason,expectedPayloadHash}。使用独立 X-Event-Operations-Token,服务配置 baiyue.event-delivery.operations-token 对应 EVENT_OPERATIONS_TOKEN;缺失或不足32字节时仅关闭该运维能力,不影响业务启动。请求编号为稳定UUID,锁定本服务原Outbox行,DEAD→PENDING和 event_delivery_retry_audit 同事务提交;相同请求参数幂等,不同参数冲突,审计失败回滚状态。脚本 baiyue-firstleg/scripts/event-outbox-operations.mjs 只接受显式服务源地址与 CHONGCHONG_ENV=test,凭据仅从环境读取,不跟随重定向、不自动重试。不得通过公网Gateway或直接改表验收。

信封保留业务事件类型/版本、客户归属、聚合版本、因果/追踪标识及 payloadHash;删除 sourceRegion/targetRegion 及纯区域部署字段时同步 DTO、Validator、构造调用、SQL 基线和测试。语义事件版本及业务载荷不因去桥而随意改动。本轮不重写旧测试事件,不做旧信封兼容。

C. 统一认证和会话撤销矩阵

2026-10-04 本机海外PDA真实登录与仓绑定通过,但个人中心主动退出未发起 /auth/logout,仅清本地会话;该项不满足服务端撤销要求。原始网络证据和独立账号停用清理保留。最小修复b247b0c已提交且TEST H5发布,正常撤销、明确401单次刷新、在飞刷新与新登录隔离的42项定向及192项全量Node通过;新版真实UI及旧Access/Refresh拒绝仍待验证,不能以返回登录页证明凭据失效。详细版本与证据见测试环境主契约。

2026-10-04 Admin 实际页面退出返回401、清本地后原Refresh仍可刷新,说明过期Access的退出路径未完成服务端撤销。Admin d3a2671 经 #509匹配发布:本地状态先清除,只有明确HTTP401或已移除过期Access时,才用捕获的原Refresh刷新一次并撤销新签发的同一会话凭据;该结果不写回登录存储、不加载权限,也不覆盖后续新登录;网络/503未知结果不自动重试。6项红灯后32项定向、299文件2392项全量及类型/build通过。已确认部署及实际auth分块;#509 普通页面退出已实际取得一次 POST200、登录页恢复及会话清理证据,自然过期401分支仍未取得新版真实运行证据。原失败和人工刷新撤销结果保留,具体证据见测试环境主契约。

2026-10-02 Admin r4 已取得密码重置多会话撤销、角色权限清空、账号停用、PDA 仓绑定变更与取消 PDA 身份后访问拒绝的真实 HTTP 证据,旧 Access 与旧 Refresh 均分别核对。目标装柜事件的 ACK 丢失、DEAD、原事件 retry、单次消费及配置恢复也在同轮重新验证;运行报告、版本和其余未覆盖边界统一见测试环境单机部署与配置契约的 Admin 全量 HTTP 复核,不据此关闭下表全部矩阵。

Auth 是唯一签发者;Gateway 负责入口令牌与访问域校验,业务服务通过 common-security 校验同一会话及业务权限。统一使用 Auth 现有国内会话协议,不只调整海外 Audience。Auth、Gateway、Lastleg、Warehouse Overseas 必须使用一致 Redis DB、会话键前缀、序列化结构与有效期规则;业务缓存用独立前缀,不能混同会话键。

JWT 不携带角色或权限集合,只保留必要身份、客户/应用/仓绑定与版本声明;授权快照取服务端会话,平台/客户/PDA 访问域仍独立校验。客户端不能从 JWT 或外部伪造头获得绕过服务器权限检查的能力。

并发撤销以持久版本和权威快照指纹为准,不能只依赖删除Redis:Auth账号变更与签发读取使用行锁,Access会话另存状态指纹,Refresh签发前复核旧指纹;Gateway及common-security在Redis会话检查后调用Auth /internal/auth/accounts/sessions/validate。Auth重新核对账号版本及IAM当前授权快照,缺失状态或下游不可用拒绝访问。IAM用单条SELECT读取身份、客户、角色权限、两类仓绑定及subject/tenant版本,避免跨查询混合快照。Gateway采用非阻塞HTTP,校验调用不转发Bearer Token,内部服务令牌保护该端点且不递归调用会话验证。此依赖增加每次请求的权威校验成本,测试环境仍须测可用性与延迟。

触发行为 撤销范围与负责链 必须验证
当前会话退出 Auth 撤销当前会话的 Access/Refresh 能力 原 Access 被拒绝,原 Refresh 不能恢复
密码重置、账号停用 Auth 或 IAM 调 Auth,撤销该账号全部相关会话 多端旧 Token 均失效,停用后不可重新登录
客户停用 IAM 确定该客户成员范围,Auth 撤销该客户作用域会话 该客户业务不可访问/刷新;其他客户与平台账号不被误撤销
成员移除、成员角色改变 IAM → Auth 撤销对应成员/客户作用域会话 旧权限不可继续使用,重新登录/刷新不能恢复被移除身份
角色权限、角色分配变化 IAM RBAC 确定所有受影响账号与作用域 → Auth 撤销 已登录用户不能继续使用旧权限快照,遗漏批量关联用户算失败
平台人员角色改变 IAM 平台人员维护 → Auth 撤销相应账号会话 新旧角色与平台访问域正确
PDA 仓绑定修改/清空 IAM → Auth 撤销绑定账号全部相关会话 原仓 Token 拒绝;新登录只获得新仓;无绑定拒绝受限作业
Refresh Token 轮转与重放 Auth 维持现有会话轮转规则,各端共用刷新编排 失效 Refresh 不重复换取;并发刷新行为与当前契约一致

撤销职责优先复用现有 MemberService、RbacService、PlatformInternalUserService/PlatformUserManagementService 与 Auth revokeSessions 链。逐入口确认,不能只凭其中一处已有调用就删除全体安全投影。

安全变更不得在撤销失败后仍返回完整成功。实施必须核对调用与提交顺序,证明“新安全状态已生效、旧会话却残留”的异常路径不会继续授权;同进程 try/catch 或口头要求重试不构成保证。若当前实现无法保证,应在该批次补齐可靠撤销及失败关闭机制,并先验证再删投影,不能降级为等待 Token 自然过期。这里冻结的是安全结果,具体撤销代码调整依据逐入口核查限定范围。

必须覆盖 Redis 不可用、Auth 撤销调用超时、账号/客户停用后的刷新、跨客户 Token 混用、伪造身份头。业务服务不能仅信任浏览器提供的权限头;统一服务端认证后清除对原海外可信头及 Lastleg 安全投影的专用依赖。权限继续由服务器决定,客户端快照只用于显示。

卸柜反向投递补证:OverseasContainerUnloaded 已通过本轮指定原事件的 ACK 丢失、重试耗尽、人工恢复及重复消费确认,Lastleg 原镜像/有效配置、健康与代理关闭已核对,库存及 Firstleg 柜回写事实不变。原始失败、工具修正、独立故障通过与整轮仍失败的范围统一见卸柜反向事件故障验收;不能据此关闭签收完成事件或其余故障矩阵。

2026-10-03 费用作废另有独立真实证据:BusinessFeeSourceChanged/VOIDED在未出账应收来源验证首次APPLIED后ACK丢失、12次失败DEAD及原事件人工retry后DUPLICATE/PUBLISHED;Finance只作废一次,Lastleg只在匹配ACK后确认。人工retry与逐次投递统一使用UTC,避免默认时区造成恢复排期延迟。共用修复d93185e7已发布Firstleg/Finance/Lastleg,真实范围、恢复指纹及首轮失败保留见部署契约。

2026-10-03 签收回写另有独立真实证据:OverseasDeliveryCompleted 在退税FBA根先签完整链中验证首次APPLIED后ACK丢失、12次失败到DEAD、同原eventId/hash/信封人工retry及DUPLICATE/PUBLISHED;Firstleg入仓、Order根/子状态及历史、完成事件和完整库存未重复变化。首片根单等待余量,第二片正常签收后根/子才均COMPLETED。Lastleg原镜像、完整配置/网络指纹、健康及代理关闭均已核对,运行报告与初次脚本失败保留规则见部署契约当前验收证据。这项证据不覆盖费用作废、全部摘要冲突或事务中途故障回滚。

业务归属与权限边界

平台和客户两级模型、服务端客户隔离、实际收货仓与 FBA 目的仓的区分继续有效。仓管绑定修改须撤销会话;无关平台角色不能通过客户端参数假冒仓绑定。统一认证后,不再用双区域安全投影作为权限来源。

资金指令当前实现补充:Finance 先单独提交 eventId/hash 身份记录,再在事务内锁定 Inbox 并复核 hash。资金变更、Inbox 最终结果及结果 Outbox 同事务提交;明确业务拒绝在原事务回滚后重新加锁记录,已有最终结果不得覆盖。可重试异常不产生最终 FAILED。内部消费响应已统一为 ApiResponse,可靠提交后才确认成功。

最终业务拒绝白名单为 FIN-WALLET-INSUFFICIENT、FIN-WALLET-HOLD-409、FIN-IDEMPOTENCY-CONFLICT、FIN-REQ-400;处理中、乐观锁冲突、依赖冻结未到达及未分类异常继续向投递方抛出。基于 H2 的 JDBC 并发与回滚测试已经通过,不替代真实 MySQL 和测试环境全链路验证。

国内仓库目录同步读取

  • 国内 warehouse-service 是 Warehouse ID、类型、状态、地址和能力的唯一权威。海外数据库不得复制仓库、地址或服务能力主表。

  • warehouse-overseas-service 只保存库位、托盘、资源锁及其国内 warehouseId 引用;资源写入和 Lastleg PDA 仓绑定校验通过受内部服务令牌保护的国内只读目录完成。

  • 只允许平台共享、OVERSEAS、ACTIVE 且启用 RECEIVING 的仓作为海外实际收货仓。低频正结果可缓存 30 分钟,空目录、不存在和停用结果不得长缓存。

  • FBA 目的仓同样只以国内 warehouse-service 的平台公共主数据为权威,但语义与海外实际收货仓严格分离:Admin 候选使用 warehouseType=FBA&status=ACTIVE 的平台仓库分页;Lastleg 写入通过受内部服务令牌保护的 /internal/warehouses/0/{warehouseId}/active 读取当前事实,并继续校验 warehouseType=FBA 及 ID/编码/名称一致。OVERSEAS、OVERSEAS_PARTNER 或 DOMESTIC 均不得作为 FBA 目的仓。

  • 按 FBA 仓拆分的海外派送单在签收完成时,由 Lastleg 在同一事务按关联来源入仓单分别写 OverseasDeliveryCompleted V1 Outbox;Lastleg Relay 直接投递 Firstleg 的 /internal/firstleg/v1/container-events。Firstleg 校验事件信封、客户、来源入仓单/订单、入仓码和 FBA 仓后,只将该来源入仓单从 LOADED 推进到 DELIVERED;同一 Order 的全部有效入仓单均为 DELIVERED 后,才以内部服务身份幂等推进该 Order 到 COMPLETED。同车其他 FBA 派送单必须各自签收,不得随整车一起完成。

  • 签收本地时间使用服务执行时区转换为事件的 UTC completedAt,信封 occurredAt 与其为同一时刻;Firstleg 完成时间及状态历史按该事件 UTC 时刻保存。不得将本地 LocalDateTime 直接解释为 UTC。来源完成审计同时核对实际签收数量、事件标识与载荷摘要、目标投递 ACK、接收端 Inbox 和完成历史;Outbox 数量检查不能替代完整接收端核对。