This commit is contained in:
@@ -80,9 +80,9 @@
|
||||
| 代理订单主钱包退款回充 | `refund.approve` 与退款单、订单、原扣款钱包、原扣款流水和唯一退款流水同事务;重复退款流水不重复写成功事件 | 原成功扣款流水定位付款钱包并限定金额;退款审批、`tb_agent_wallet` 与唯一成功退款流水同事务形成权威事实 | N/A(本资金接缝不调用渠道或审批外部系统;原路渠道退款尚未实现) | 同事务写入 `wallet.agent_main.refunded`,消费者复核退款流水、原扣款事实、金额上限和资产快照 |
|
||||
| 代理商资金概况信用投影 | N/A(普通受权读取;不返回其他数据范围的资金事实,不执行资金或配置变更) | 只读投影 `tb_shop`、主/佣金钱包、提现汇总和主账号;派生金额不另建事实表 | N/A(无外部系统调用) | N/A(纯 Query 不产生可靠副作用) |
|
||||
| 受控系统配置更新 | N/A(用户已明确取消全局 Audit Event;仅超级管理员可更新代码注册 Key,未知 Key、非法类型和值域均拒绝) | `tb_system_config` 是配置值、类型、模块及更新人的 PostgreSQL 权威事实,更新后失效 Redis 缓存 | N/A(配置更新不调用外部系统;不得写 Integration Log 冒充配置审计) | N/A(配置更新不产生可靠异步副作用) |
|
||||
| 电信实名结果回调 | N/A(Audit Event 已移出本 Change;运营商来源真实性验证也不在本票边界) | `tb_iot_card` 是实名状态、首次实名时间和逆转窗口的权威事实 | 每次入站先写 `tb_integration_log`,仅保存正文摘要;覆盖 `invalid_payload/ignored/not_found/conflict/success/failed` 终态 | 实名事实首次变化时由公共 `ApplyCardObservation` 同事务写入实名状态变化 Outbox;重复成功不重复写事件 |
|
||||
| 移动实名成功回调 | N/A(Audit Event 已移出本 Change;不接入旧平台登录、MSISDN 补查或来源真实性验证) | `tb_iot_card` 是实名状态、首次实名时间和逆转窗口的权威事实 | 每次入站先写 `tb_integration_log`,仅保存正文摘要;覆盖 `invalid_payload/not_found/conflict/success/failed` 终态,并通过 pending 租约恢复中断处理 | 仅合法成功报文进入公共 `ApplyCardObservation`;实名事实首次变化时同事务写入 Outbox,重复成功不重复写事件 |
|
||||
| 联通实名成功回调 | N/A(Audit Event 已移出本 Change;不复制旧 `inner_callback`、第三方推送或 Gateway 二次确认) | `tb_iot_card` 是实名状态、首次实名时间和逆转窗口的权威事实;上游 `dateChanged` 只用于幂等和留痕 | 每次入站先写 `tb_integration_log` 正文摘要;覆盖 `invalid_payload/not_found/conflict/success/failed`,关闭时记录 `ignored` | 仅合法成功报文进入公共 `ApplyCardObservation`;实名事实首次变化时同事务写入 Outbox,重复成功不重复写事件 |
|
||||
| 电信实名结果回调 | 实名状态首次实际变化时写 `iot_card.realname_callback_sync`,使用 `external_system/callback`,关联 IoT 卡和入站 Integration Log;Audit Event 与卡状态、首次实名时间及实名变化 Outbox 同事务,审计失败回滚。已解析卡后的业务失败写独立短事务;重复成功不伪造事件 | `tb_iot_card` 是实名状态、首次实名时间和逆转窗口的权威事实 | 每次入站先写 `tb_integration_log`,仅保存正文摘要;覆盖 `invalid_payload/ignored/not_found/conflict/success/failed` 终态;未改变实名状态时只保留 Integration Log | 实名事实首次变化时由公共 `ApplyCardObservation` 同事务写入实名状态变化 Outbox;重复成功不重复写事件 |
|
||||
| 移动实名成功回调 | 实名状态首次实际变化时写 `iot_card.realname_callback_sync`,使用 `external_system/callback`,关联 IoT 卡和入站 Integration Log;Audit Event 与卡状态、首次实名时间及实名变化 Outbox 同事务,审计失败回滚。已解析卡后的业务失败写独立短事务;重复成功不伪造事件 | `tb_iot_card` 是实名状态、首次实名时间和逆转窗口的权威事实 | 每次入站先写 `tb_integration_log`,仅保存正文摘要;覆盖 `invalid_payload/not_found/conflict/success/failed` 终态,并通过 pending 租约恢复中断处理;未改变实名状态时只保留 Integration Log | 仅合法成功报文进入公共 `ApplyCardObservation`;实名事实首次变化时同事务写入 Outbox,重复成功不重复写事件 |
|
||||
| 联通实名成功回调 | 实名状态首次实际变化时写 `iot_card.realname_callback_sync`,使用 `external_system/callback`,关联 IoT 卡和入站 Integration Log;Audit Event 与卡状态、首次实名时间及实名变化 Outbox 同事务,审计失败回滚。已解析卡后的业务失败写独立短事务;重复成功不伪造事件 | `tb_iot_card` 是实名状态、首次实名时间和逆转窗口的权威事实;上游 `dateChanged` 只用于幂等和留痕 | 每次入站先写 `tb_integration_log` 正文摘要;覆盖 `invalid_payload/not_found/conflict/success/failed`,关闭时记录 `ignored`;未改变实名状态时只保留 Integration Log | 仅合法成功报文进入公共 `ApplyCardObservation`;实名事实首次变化时同事务写入 Outbox,重复成功不重复写事件 |
|
||||
| 联通解除实名回调 | N/A(只识别并留痕外部解除通知,不把单次回调作为本地实名逆转事实) | `tb_iot_card` 保持原实名状态、首次实名时间、检查时间及逆转计数,回调不写领域事实 | 每次入站先写 `tb_integration_log` 正文摘要;覆盖 `invalid_payload/not_found/conflict/ignored/failed` 终态并支持 pending 租约恢复 | N/A(不调用公共实名观测,不产生状态变化、停机或套餐事件) |
|
||||
|
||||
## 七月确认范围增量登记
|
||||
@@ -182,6 +182,22 @@
|
||||
- 轮询配置与人工动作已切换统一 Writer:轮询配置创建、更新、删除和启停使用 `polling_config.create/update/delete/update_status`,并发配置更新与计数重置使用 `polling_concurrency.update/reset`,告警规则创建、更新和删除使用 `polling_alert.create_rule/update_rule/delete_rule`;成功事件与对应 PostgreSQL 配置事实共用 GORM 事务,审计失败回滚配置写入。Redis 并发计数重置无法与 PostgreSQL 原子提交,审计失败时恢复重置前计数;人工单卡去重键在日志/审计事务失败或队列写入失败时移除,避免阻断原有重试。
|
||||
- 单卡、批量、条件筛选人工触发和取消分别使用 `polling_manual_trigger.trigger_single/trigger_batch/trigger_by_condition/cancel_trigger`,记录真实后台账号、手动任务和实际卡资源;配置重名、每日触发上限、重复入队、越权取消和已结束任务取消等已定位资源的拒绝写独立短事务,二次失败保留原业务错误并记录 critical。`tb_polling_manual_trigger_log` 继续承担进度、结果与历史查询,不被 Audit Event 替代或停写;审计不复制 `CardIDs`、条件正文、通知渠道正文或其他安全凭据,只保存任务类型、触发方式、数量、状态及“条件/通知渠道是否配置”等安全事实。
|
||||
- 实名、流量和卡状态轮询的每次真实 Gateway 尝试继续写 Integration Log;套餐/保护期轮询自身不伪造 Gateway 尝试,实际停复机复用共享 `StopResumeService` 的 Audit/Integration 边界。轮询配置、并发状态、告警历史、人工任务状态/历史和监控页面等普通运行查询均为 N/A;通知投递、任务 ledger、Audit Event 与 Integration Log 保持独立事实。`polling_cleanup` 数据清理配置未包含在 8.5 明确边界,本轮不借轮询审计扩展其 CRUD 或手动清理动作,继续保留在覆盖清单等待对应显式切片。
|
||||
- 外部 Callback 已按当前生产路由收口:微信/支付宝/富友支付回调继续复用 7.4 的支付、订单和充值事务审计,企微审批回调继续复用 8.1 的权威终态审计;电信、移动、联通实名成功回调在共享 `ApplyCardObservation` 事务中使用 `iot_card.realname_callback_sync`,真实 actor 为各运营商 `external_system/callback`,关联 IoT 卡和入站 Integration Log。重复支付、重复审批、重复实名及无状态变化只保留 Integration Log,不伪造成功 Audit Event;联通解除实名仍仅留痕且不改变本地实名事实。本切片不修改支付、运营商或企微协议。
|
||||
- 当前 31 个 Asynq Worker 已按 8.7 逐项复核:`iot_card:import`、`device:import`、`order_package:invalidate`、`asset_package:batch_order`、`commission:calculate`、`package:first_activation`、`package:queue_activation`、`order:expire`、`notification:cleanup`、`auto_purchase:after_recharge`、`wecom:approval:sync`、`wecom:approval:recovery`、`agent_recharge:recovery` 已复用前序纵向切片的统一 Audit Event;本切片新增 `card_observation:series` 及 `polling:realname/carddata/card_status` 的 `system_task/worker` 上下文,仅在实名、流量、网络或设备字段/当前卡槽实际变化时分别写 `iot_card.worker_realname_sync`、`iot_card.worker_traffic_sync`、`iot_card.worker_network_sync`、`device.worker_observation_sync`,并关联对应 Gateway Integration Log。`polling:package/protect` 不另造轮询动作,实际停复机继续复用 `iot_card.auto_stop/auto_start/auto_stop_reason_update`。上述链路传播 request/correlation/parent;重试失败写 failed 短事务,无实际变化仅保留 Integration Log 或任务运行事实,不伪造 success。
|
||||
- Worker N/A 与后续边界:`email:send` 仅模拟邮件投递;`export:dispatch/shard/finalize` 仅做导出技术装配;`commission_stats:update/sync/archive` 仅维护 Redis/PostgreSQL 统计投影;`polling:alert_check` 仅生成告警运行事实;`polling:data_cleanup` 仅执行既有轮询数据清理;`package:expiry_reminder` 仅生成可靠通知 Outbox;`daily_traffic:flush` 仅把 Redis 日流量 Domain Ledger 落盘,均不重复创建 Audit Event。`outbox:deliver` 自身是可靠投递技术入口,Relay/投递事实 N/A;其各业务消费者是否形成新业务事实按任务 8.9 逐项收口,不在 8.7 提前迁移。Scheduler 仅投递或创建任务的边界留给 8.8。
|
||||
- Scheduler 已按当前注册清单逐项复核:代理在线充值恢复、订单过期关闭和企微审批恢复在真实业务事实变化时使用 `scheduled_job/scheduler`;轮询 Scheduler 直接执行的套餐到期、后续权益接续、流量周期重置及套餐到期停机检查同样保留 `scheduled_job/scheduler` 操作者。套餐到期后的异步停机检查使用不受调度 tick 取消影响的原审计上下文,继续传播 actor、correlation 和 parent,不伪造人工操作者。
|
||||
- Scheduler N/A 与幂等边界:Asynq 周期注册、轮询心跳、队列深度检查、分片/手动队列出队、重复调度的 `Unique` 去重与失败回队只是技术调度或任务事实,不写 Audit Event,也不把后续 Worker 结果伪装成 Scheduler 成功。告警检查、轮询数据清理、通知保留清理、套餐临期提醒和日流量落盘继续按 8.7 的 Worker/Domain Ledger/Outbox 边界处理;重复调度依赖既有状态条件、领取租约、稳定事件 ID 和 Asynq `Unique`,无实际变化不伪造 success。Worker 消费逻辑未在 8.8 迁移。
|
||||
- 当前 14 个 Outbox 事件注册、12 个消费者实现已按 8.9 逐项复核:企微审批提交终态、审批标准决策分发、卡实名/流量/网络变化后续处理、代理在线充值入账和三类站内通知生成会形成新的内部业务事实,均通过 `outbox:deliver` 入口取得 `system_task/worker` actor,并沿用信封的 request/correlation/parent;实际变化继续复用 8.1、7.2、7.6 和 8.4 已接入的同事务 Audit Event。状态条件、处理租约、稳定事件 ID、业务唯一键和通知 `CreateIdempotent` 保证至少一次投递不会伪造重复 success;消费者返回成功只代表本次业务处理完成,Outbox 的 delivered 状态仍是独立投递事实。
|
||||
- Outbox 消费者 N/A 边界:卡观测序列请求仅幂等创建后续观测任务,代理主钱包预占/入账/退款消费者仅复核既有 Domain Ledger,扣款消费者仅复核流水并按阈值幂等追加新的通知 Outbox,均不把“校验通过、任务触发或二次投递成功”写成业务 Audit Event;后续观测或通知实际改变业务事实时由对应 Worker/Application 自身写 Audit Event。Relay 的领取、入队、续租、delivered/failed、退避和重投保持技术投递事实,不在 8.9 修改或审计化。
|
||||
- request/correlation 组合时间线只按非空稳定 ID 精确读取 `tb_audit_event`、`tb_integration_log` 和 `tb_outbox_event`,以 `record_source` 保留 Audit、外部交互及可靠投递边界;Outbox 只展示当前投递摘要,不把 delivered 解释为业务成功。Asynq 没有通用 PostgreSQL 历史表,Query 仅从已落库的导入、批量购包、套餐失效、设备批量和导出任务资源生成 `asynq_task` 摘要,不扫描 Redis、不展示技术重试。订单、支付、退款、充值、钱包/流水、套餐权益、审批和佣金等只生成 `domain_ledger_ref` 稳定引用,金额与状态仍以业务表为准并留给 9.2 专业资金视角。Access Log 只返回 request ID 供开发检索,不读取日志文件;历史缺少 request/correlation/parent、直接 Audit 关联或稳定资源时通过 fidelity 标记原样降级,不按相近时间、相似资源或相同 correlation 猜测技术尝试。节点统一按发生时间、`record_source`、稳定节点 ID 升序排列。
|
||||
- 资金调查时间线以平台只读 Query 组合 Audit Event、代理/资产钱包流水、代理钱包预占、订单、支付、退款、代理/个人资产充值、佣金、提现和审批当前业务事实;支持从店铺、钱包、订单、支付、退款、充值、审批、第三方交易号、操作者、时间或 correlation 中任一稳定条件进入,并在服务端解析已持久化关联,不要求前端补齐整条链路。节点按发生时间、`record_source`、稳定节点 ID 倒序分页,统一返回调查跳转引用;钱包流水的 `amount/balance_before/balance_after` 及各业务表金额字段明确标记为权威,Audit Event 金额只作操作摘要,冲突时不改写历史事件并以对应 Domain Ledger 为准。平台身份复用统一审计 Query 的 SuperAdmin/Platform 后端校验,不增加店铺数据范围,也不提供资金重算、状态修改、导出或恢复能力。
|
||||
- 风险调查视角只读聚合统一 Audit Event:高/严重风险、涉及订单/支付/退款/充值/钱包/佣金等资金资源、安全类别,以及 `failed/denied/partial/unknown` 结果进入固定风险集合;普通低风险成功事件明确排除。overview 在最长 31 天的显式时间范围内按风险、结果、action、来源和小时/日趋势聚合,events 复用统一事件批量投影、稳定倒序分页及 `investigation_refs`,可继续跳转事件、资源、actor 和 correlation。该视角不读取或修改业务状态,不产生 Audit Event、Domain Ledger、Integration Log 或 Outbox,也不提供处置工单、自动封禁、导出或恢复能力。
|
||||
- 跨视角查询性能仅补已确认路径的 PostgreSQL B-tree:保留事件时间、actor、scope、correlation 和资源时间线既有索引,补 action、result、risk、category、source 的稳定倒序分页索引,将 request/parent 索引补齐时间与 ID,并为资源 type+id/key 到事件的反向关联补索引。全局、actor、资源和风险事件先分页事件 ID,再批量投影事件与资源;Integration 列表同样先分页 ID,再批量读取列表字段,不加载正文 JSON。第一阶段不增加 JSONB 任意搜索、Redis 结果缓存、月分区或冷热联合查询。
|
||||
- 跨视角 HTTP 契约复用既有平台 `AuditHandler` 和生产/文档装配,仅新增 request、correlation、finance、risk 的只读 GET Handler/DTO/RouteSpec;身份继续只取认证上下文,未增加写路由、导出、处置、恢复或前端实现。前端导航文档逐行冻结 design 8.1-8.4 的源页面、前置接口、`response.data` 字段、入口可见条件、目标参数和降级规则,并以资产、订单、退款、钱包、通知、风险节点演示完整调用链。
|
||||
- Audit Event 与 Event Resource 每日冷归档使用独立 `audit:daily:archive` Asynq 任务和 `tb_log_archive_run` 轻量账本:按 `Asia/Shanghai` 前一完整自然日、事件 `created_at` 半开区间分页读取,每行保存一个完整事件及其全部 `resources[]`,生成 JSONL+gzip、manifest 和 SHA-256;对象 Key 按日期与 revision 稳定生成,上传后回读 metadata 核对大小、hash、事件数和资源数,成功重复任务直接复用,失败或对象不一致使用新 revision 且不覆盖旧对象。该基础设施任务不写业务 Audit Event,不读取 Integration/Access/Domain Ledger/Outbox/旧 operation log,不清理数据库,也不向业务 Writer 注入对象存储;对象存储失败只更新归档账本并由 Asynq 重试,业务审计写入继续正常执行。
|
||||
- Integration Log 冷归档复用同一对象存储、归档 Service 和 `tb_log_archive_run`:`integration:daily:archive` 按 `created_at` 保存前一自然日的结构化 JSONL+gzip 创建日快照;`integration:monthly:finalize` 在月初逐日按数据库当前内容重新生成并比较记录数与 SHA-256,首次终结、内容变化或对象 metadata 不一致时创建新的不可变 revision,旧对象不覆盖。月度复核仅把无 `pending` 记录且最终对象、manifest 均复核成功的日期标记 `is_final`;`pending`、对象损坏或复核失败会使任务失败并明确阻止后续清理。该切片不修改 Integration Writer、恢复语义或业务状态,也不删除 PostgreSQL 数据、不提供对象存储查询/恢复接口。
|
||||
- 月度留存清理使用 `audit:monthly:retention` Asynq 任务,在 `Asia/Shanghai` 每月 1 日 06:00 处理上一完整自然月:先补齐最后一日 Audit/Integration 归档并完成 Integration 最终 revision,再逐日核对 ledger、manifest、对象 metadata、压缩对象实际大小/SHA-256 及数据库数量。全月硬门禁通过后仅按 Event Resource → Audit Event → Integration Log 顺序对 `tb_audit_event_resource`、`tb_audit_event`、`tb_integration_log` 以 1000 行有界批次执行 GORM 物理删除,并复用 `tb_log_archive_run.cleanup_started_at/cleaned_at` 断点续跑;对象存储归档和 manifest 长期保留。清理结果以 `retention_worker/system_task` 写当月 `audit.retention_cleanup` Audit Event,资源为 `log_archive_month`;Domain Ledger、Integration Log 新写、Outbox 均为 N/A,因该事实是内部留存执行结果,不是业务状态、外部交互或可靠投递。Access Log、订单/支付/退款/钱包等 Domain Ledger、Outbox、Asynq 运行事实、手动轮询、旧 operation log 及其他业务表明确不删除。
|
||||
- 在线审计查询以 `tb_log_archive_run.cleaned_at/range_end` 作为真实清理边界:平台 Audit/Integration、request/correlation/finance/risk 及代理/企业活动响应统一返回 `retention{online_from,archived_before,timezone}`;缺省时间范围只查 PostgreSQL 在线窗口,显式早于或跨越边界返回 `CodeAuditDataArchived` 和当前边界。稳定事件或 Integration ID 只在在线库查找,不存在仍返回资源不存在;历史资源快照搜索和 Integration 尝试序列同样受边界限制。该 Query 切片不访问对象存储,不新增归档下载、恢复、冷热联合查询、导出或写路由,普通读取仍为 Audit Event/Domain Ledger/Integration Log/Outbox N/A。
|
||||
|
||||
### 与审计接入分开保留的独立修复
|
||||
|
||||
|
||||
Reference in New Issue
Block a user