docs(spec): 领域边界闭合 spec 与配套文档修正
新增 docs/spec-boundary-closure.md:自包含 spec,内联展开所有 PRE/INV/CLM/D/C/US/PARAM/Q/错误分类/表结构/时间常数序引用, 覆盖 G-KAFKA-D3 / G-IGNORE / G-EVENT-RETENTION / G-BACKFILL-BACKOFF / G-PROC-HST 五个缺口的实现决策、验收与测试决策。 同步修正 design.md(归档段落改条件 DELETE、ARCHIVED 影子行、 SENT_AT 描述)与 user-stories.md US-11(AC1 改 UPDATED_AT、 AC2 删投递判据、AC3 补条件回滚语义)。
This commit is contained in:
+6
-6
@@ -23,8 +23,8 @@
|
||||
|
||||
| 记录 | 用途 | 关键约束 |
|
||||
|---|---|---|
|
||||
| `PROC_STATE` | 入站消息的处理状态、身份、尝试次数、错误原因与回填事实 | `MSG_ID = CMINMSGS_ID` 主键防重复入队;`IDENTITY_KEY` 唯一约束防业务重复;按最小未完成 `MSG_ID` 取队头;`BACKFILL_NEXT_AT` 非空 = 还欠一次回填,`BACKFILL_AT` 非空 = 标记已确认,`BACKFILL_ABANDONED_AT/REASON` 非空 = 已停止自动重试(**不等于**标记已确认);`RECEIVED_AT` 复制自信箱接收时间、**可能为 NULL**、仅用于对账与展示;`ENQUEUED_AT` 是本地入队时间、非空、是超期判据的唯一依据。 |
|
||||
| `MSG_EVENT` | 等待投递的事件(outbox) | `EVENT_ID` 对 `KAFKA:msg` 是稳定事件身份并决定投递顺序;对 `KAFKA:schd` 是每次接受 upsert 时替换的写代次。`TARGET` 区分 `KAFKA:msg` / `KAFKA:schd`;`PARTITION_KEY` 当前取 `FLID`(`Q4` 定案前为假定,见 `C-29`);`EVENT_TYPE` 区分 UPSERT 与 TOMBSTONE。`KAFKA:schd` 按 `FLID` 单行 upsert,只保留最新 `STATE_VERSION`。 |
|
||||
| `PROC_STATE` | 入站消息的处理状态、身份、尝试次数、错误原因与回填事实 | `MSG_ID = CMINMSGS_ID` 主键防重复入队;`IDENTITY_KEY` 唯一约束防业务重复;按最小未完成 `MSG_ID` 取队头;`BACKFILL_NEXT_AT` 非空 = 还欠一次回填,`BACKFILL_AT` 非空 = 标记已确认,`BACKFILL_ABANDONED_AT/REASON` 非空 = 已停止自动重试(**不等于**标记已确认);`RECEIVED_AT` 复制自信箱接收时间、**可能为 NULL**、仅用于对账与展示;`ENQUEUED_AT` 是本地入队时间、非空、是超期判据的唯一依据;归档后的去重影子行置 `STATE='ARCHIVED'`、只保留 `IDENTITY_KEY` 与 `MSG_ID`,不占队头、不触发回填、不参与积压聚合(`[G-PROC-HST]`)。 |
|
||||
| `MSG_EVENT` | 等待投递的事件(outbox) | `EVENT_ID` 对 `KAFKA:msg` 是稳定事件身份并决定投递顺序;对 `KAFKA:schd` 是每次接受 upsert 时替换的写代次。`TARGET` 区分 `KAFKA:msg` / `KAFKA:schd`;`PARTITION_KEY` 当前取 `FLID`(`Q4` 定案前为假定,见 `C-29`);`EVENT_TYPE` 区分 UPSERT 与 TOMBSTONE。`KAFKA:schd` 按 `FLID` 单行 upsert,只保留最新 `STATE_VERSION`;`SENT_AT` 在投递确认的同一条 UPDATE 内写入,是保留期判定的唯一基准(`[G-EVENT-RETENTION]`)。 |
|
||||
| `REQ_TRACK` | 上游请求及应答关联 | 状态 `PENDING / SENT / DONE / EXPIRED`;保存请求类型、覆盖运营日、发送方、出站信箱 ID 与发送/完成时间;**「同类只允许一个开放请求」的唯一键 = `(请求类型, 覆盖运营日, 发送方)`,且仅对开放状态生效**。登记、超时与应答匹配尚未实现 `[G-REQ-TRACK]`。 |
|
||||
| `REF_MASTER` | 静态参考数据(目标表) | `(RTYPE, RKEY)` 唯一;尚未建表,客户端与刷新流程见 user-stories US-13/US-14,US-14 两类映射的存储落点未定。 |
|
||||
| `FLIGHT_SCHD` | 航班标量及单值异常字段 | `FLID` 主键;`OPERATION_DAY` 一经确定不可变;版本与最近消息 ID 用于追踪。现有变长集合存于 8 张资源明细表与 `FLIGHT_ROUTE_POINT`;`SRVT`/`VIPF` 专用明细尚未实现 `[G-SRVT-VIPF]`,规则见 flight-state.md。 |
|
||||
@@ -57,7 +57,7 @@
|
||||
→ DEAD(重试耗尽,记录保留作 DLQ)
|
||||
```
|
||||
|
||||
`SUCCEEDED / SKIPPED / DEAD` 是处理终态,不再阻塞后续消息;`FAILED` 不是终态,仍占据队头。`DEAD` 表示需要处置,不等于业务成功。
|
||||
`SUCCEEDED / SKIPPED / DEAD` 是处理终态,不再阻塞后续消息;`FAILED` 不是终态,仍占据队头。`DEAD` 表示需要处置,不等于业务成功。`ARCHIVED` 不是处理态:它是终态行归档后留在主表的去重影子行,不占队头、不触发回填、不参与积压聚合(见「生命周期与清除」)。
|
||||
|
||||
| 错误类别 | 处理方式 |
|
||||
|---|---|
|
||||
@@ -344,12 +344,12 @@ PENDING → SENT → DONE
|
||||
|
||||
**处理终态归档**(`PROC_STATE` → `PROC_STATE_HST`)
|
||||
|
||||
候选 = 终态 **且** 回填已了结 **且** 终局后经过归档阈值。两处不可省:
|
||||
候选 = 终态 **且** 回填已了结 **且** 终局后经过归档阈值(基准是 `UPDATED_AT`:终态与了结都推进它,了结后不再更新)。两处不可省:
|
||||
|
||||
- **回填已了结** = `BACKFILL_AT` 非空,或已放弃 **且经人工对账**。放弃行不写标记,是 `C-8` 的清除授权证据,未对账前不得归档。
|
||||
- **删除前复查** = `DEAD` 可被人工重放改回 `PENDING`,故必须在 `PIPELINE_LOCK` 内复查 `STATE` 未变再删,与航班历史清理同形(`INV-18`)。
|
||||
- **写入前复查** = `DEAD` 可被人工重放改回 `PENDING`。人工重放走 `MessageLifecycleGate`、不取 `PIPELINE_LOCK`,因此该锁不构成复查依据:归档在同一事务内先 `INSERT INTO PROC_STATE_HST … SELECT`,再按候选时的 `STATE` 条件写主表;影响 0 行即整体回滚、该行跳过。重放先一步改回 `PENDING` 时谓词不匹配,天然互斥。批量归档不得持 `PIPELINE_LOCK`——那会阻塞主泵 FIFO,与「作业不使到期消息饥饿」冲突。
|
||||
|
||||
归档范围只含终态;归档后仍须保留业务去重能力(`INV-9`)——去重记忆期长于工作状态在线期,两者同行时只能二选一。
|
||||
归档范围只含终态;归档后仍须保留业务去重能力(`INV-9`)——去重记忆期长于工作状态在线期,实现取「主表保留去重影子行」:主行置 `STATE='ARCHIVED'`、只留 `IDENTITY_KEY` 与 `MSG_ID`,`IDENTITY_KEY` 唯一约束留在主表不动。队头推进、`backlog()` 与回填扫描的谓词显式排除 `ARCHIVED`,不靠状态包含列表隐式过滤。
|
||||
|
||||
**时间常数排序**(取值见 contracts.md)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user