Initial commit

This commit is contained in:
windyboy
2026-04-15 14:48:14 +08:00
commit 42b6f73d1e
97 changed files with 16997 additions and 0 deletions
+252
View File
@@ -0,0 +1,252 @@
# AODB 事件 Schema 草案
## 1. 文档定位
本文档定义 AODB MVP 阶段的统一事件信封和关键事件 payload 草案,用于实现、联调和消费者契约评审。
## 2. 统一事件信封
所有事件必须使用统一 envelope:
```json
{
"event_id": "uuid",
"event_type": "PublishedFactUpdated",
"schema_version": 1,
"occurred_at": "2026-04-13T16:00:00Z",
"produced_at": "2026-04-13T16:00:01Z",
"source": {
"system": "aodb-flight-service",
"organization": "airport-ops",
"channel": "internal"
},
"idempotency_key": "string",
"correlation_id": "string",
"aggregate_type": "FlightOperation",
"aggregate_id": "flight_123",
"quality": {
"confidence": "confirmed",
"flags": []
},
"payload": {}
}
```
## 3. 字段说明
| 字段 | 说明 | 必填 |
| --- | --- | --- |
| `event_id` | 全局唯一事件 ID | 是 |
| `event_type` | 事件类型 | 是 |
| `schema_version` | schema 版本 | 是 |
| `occurred_at` | 业务发生时间 | 是 |
| `produced_at` | AODB 产出时间 | 是 |
| `source` | 来源系统和组织 | 是 |
| `idempotency_key` | 幂等键 | 是 |
| `correlation_id` | 关联链路 ID | 是 |
| `aggregate_type` | 聚合类型 | 是 |
| `aggregate_id` | 聚合 ID | 是 |
| `quality` | 可信度和数据质量标记 | 否 |
| `payload` | 事件负载 | 是 |
## 4. 事件列表
### 4.1 `FlightImported`
用途:
- 表示计划航班已进入 AODB 标准化流程。
```json
{
"payload": {
"flight_id": "flight_123",
"flight_key": "MU-1234-2026-04-13-1",
"op_date": "2026-04-13",
"carrier": "MU",
"flight_number": "1234",
"leg_no": "1",
"batch_id": "ssim_batch_001"
}
}
```
### 4.2 `MilestoneObserved`
用途:
- 表示接收到一条原始或标准化里程碑观测。
```json
{
"payload": {
"observation_id": "obs_001",
"flight_id": "flight_123",
"milestone_type": "ALDT",
"observed_value": "2026-04-13T15:22:00Z",
"source_sequence": "aidx-889",
"raw_message_ref": "msg_777"
}
}
```
### 4.3 `PublishedFactUpdated`
用途:
- 表示 Published Fact 发生变化,是对外共享的关键事件。
```json
{
"payload": {
"flight_id": "flight_123",
"field_name": "ALDT",
"previous_value": "2026-04-13T15:20:00Z",
"current_value": "2026-04-13T15:22:00Z",
"decision_ref": "decision_321",
"published_state_version": 9
}
}
```
### 4.4 `TurnaroundLinked`
用途:
- 表示到离港航班形成过站关联。
```json
{
"payload": {
"turnaround_id": "ta_001",
"arrival_flight_id": "flight_arr_001",
"departure_flight_id": "flight_dep_001",
"tail_number": "B-1234",
"link_confidence": "estimated"
}
}
```
### 4.5 `ResourceAssigned`
用途:
- 表示资源分配已生效。
```json
{
"payload": {
"allocation_id": "alloc_001",
"resource_id": "stand_12",
"resource_type": "Stand",
"flight_id": "flight_123",
"turnaround_id": "ta_001",
"lock_type": "hard",
"assignment_source": "manual",
"validity_window": {
"start_at": "2026-04-13T15:00:00Z",
"end_at": "2026-04-13T16:30:00Z"
}
}
}
```
### 4.6 `ResourceConflictDetected`
用途:
- 表示资源冲突被识别出来。
```json
{
"payload": {
"resource_id": "stand_12",
"resource_type": "Stand",
"conflict_type": "time_overlap",
"affected_allocations": ["alloc_001", "alloc_002"],
"affected_flights": ["flight_123", "flight_456"],
"rule_ref": "resource.time-window.v1"
}
}
```
### 4.7 `AlertRaised`
用途:
- 表示告警进入打开状态。
```json
{
"payload": {
"alert_id": "alert_001",
"alert_type": "resource_conflict",
"severity": "high",
"related_aggregate_type": "ResourceAllocation",
"related_aggregate_id": "alloc_001",
"summary": "Stand 12 conflict detected"
}
}
```
### 4.8 `ManualDecisionRecorded`
用途:
- 表示人工裁决已经完成。
```json
{
"payload": {
"decision_id": "decision_321",
"decision_type": "field_override",
"target_aggregate_type": "FlightOperation",
"target_aggregate_id": "flight_123",
"field_name": "ALDT",
"selected_value": "2026-04-13T15:22:00Z",
"reason": "tower confirmation",
"operator": "ops_user_007"
}
}
```
### 4.9 `ReviewTaskOpened`
用途:
- 表示复核任务已创建。
```json
{
"payload": {
"review_task_id": "review_001",
"review_type": "milestone_conflict",
"target_aggregate_type": "FlightOperation",
"target_aggregate_id": "flight_123",
"reason": "conflicting ALDT observations"
}
}
```
## 5. 版本演进规则
- `schema_version` 必须随破坏性变更升级。
- 非破坏性新增字段只允许追加,不允许重定义现有字段含义。
- 下游必须按“忽略未知字段”实现兼容。
- 被废弃字段必须至少保留一个发布周期。
## 6. Topic 建议
| Topic | 用途 | 分区键 |
| --- | --- | --- |
| `aodb.flight.events` | FlightOperation 和 Published Fact 事件 | `flight_id` |
| `aodb.resource.events` | 资源分配和冲突事件 | `flight_id` |
| `aodb.alert.events` | 告警和处置事件 | `alert_id` |
| `aodb.review.events` | 人工复核和裁决事件 | `target_aggregate_id` |
## 7. 消费者要求
- 必须按 `event_id` 去重。
- 必须处理至少一次投递。
- 必须把 `quality.flags` 作为强语义,而不是展示附注。
- 不得把查询接口结果当作事件流补偿来源。
@@ -0,0 +1,65 @@
# AODB 字段级权威矩阵
## 1. 文档定位
本文档用于定义 AODB 关键字段的来源优先级、更正规则、人工覆盖规则和对外可见性。它是 Published Fact 生成和测试用例设计的直接依据。
## 2. 适用原则
- 规则粒度以字段为准,而不是以“整条航班记录”统一处理。
- 原始 Observation 永不改写。
- Published Fact 只能由字段级权威矩阵和裁决逻辑生成。
- 人工覆盖必须事件化和审计化。
## 3. 字段矩阵
| 字段 | 字段类别 | 主来源 | 次来源 | 默认可信度规则 | 过期规则 | 更正规则 | 人工覆盖规则 | 对外可见性 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| SIBT / SOBT | 计划时间 | SSIM / 计划导入 | 人工计划调整 | 计划导入为 `reported`,人工调整为 `confirmed` | 新计划版本到达后旧计划失效 | 新批次或更高版本覆盖旧计划 | 允许,必须记录变更原因 | 返回当前值 + 来源 |
| EOBT | 预计时间 | 航司计划源 | 机场运行 | 航司上报优先 | 超过配置阈值后降为 `suspect` | 新版本或更正报文优先 | 允许 | 返回当前值 + 来源 + 可信度 |
| TOBT | 协同计划时间 | 航司 / 地服 | 机场运行 | 航司 / 地服 `confirmed` 高于机场运行 `reported` | 若长时间未更新且实际进度明显偏离,则标记 `suspect` | 显式更正优先 | 允许,必须给出裁决摘要 | 返回当前值 + 裁决摘要 |
| TSAT | 系统计算时间 | AODB / PDS | 机场运行人工调整 | 系统计算缺省 `estimated` | 新一轮计算生成后旧值过期 | 高版本计算结果覆盖低版本 | 允许,需记录算法版本和人工原因 | 返回当前值 + 算法版本 |
| TTOT | 系统计算时间 | AODB / PDS | 机场运行人工调整 | 同 TSAT | 同 TSAT | 同 TSAT | 同 TSAT | 返回当前值 + 算法版本 |
| ELDT | 预计到达时间 | ANSP / 外部运行态 | 系统预测 | ANSP 上报高于系统预测 | 若距当前时间过远且无更新,可信度下降 | 新版本或更正优先 | 允许 | 返回当前值 + 可信度 |
| ALDT | 实际到达时间 | ANSP / 机场运行 | 航司 | ANSP / 机场运行 `confirmed` 优先 | 实际时间不过期,但可被更正 | 明确更正或更高序列覆盖 | 允许,需进入人工裁决 | 返回当前值 + 来源 |
| AIBT | 实际到位时间 | 地服 / 机场运行 | 航司 | 地服 / 机场运行优先 | 实际时间不过期,但可被更正 | 更正优先 | 允许,需人工裁决 | 返回当前值 + 来源 |
| EIBT | 预计到位时间 | 系统计算 | 运行动态派生 | 系统计算缺省 `estimated` | 新估算生成后旧值过期 | 新估算覆盖旧估算并留历史 | 允许 | 返回当前值 + 可信度 |
| AOBT | 实际推出时间 | 地服 / 机场运行 | 航司 | 地服优先 | 实际时间不过期,但可更正 | 更正优先 | 允许,需人工裁决 | 返回当前值 + 来源 |
| ATOT | 实际起飞时间 | ANSP | 航司 / 机场运行 | ANSP 优先 | 实际时间不过期,但可更正 | 更正优先 | 允许,需人工裁决 | 返回当前值 + 来源 |
| Flight Status | 航班状态摘要 | Published Fact 推导 | 人工裁决 | 由里程碑和取消状态综合推导 | 状态持续有效直到新事实生成 | 更正走 Published Fact 重新计算 | 允许,需生成裁决事件 | 返回当前值 + 裁决摘要 |
| Cancelled Flag | 取消标记 | 航司 / 计划源 | 机场运行 | 航司取消优先 | 取消后持续有效,直到明确恢复 | 恢复必须有显式更正 | 允许,需高级别审计 | 返回当前值 + 来源 |
| Turnaround Link | 航班配对 | 系统配对 | 人工配对修正 | 人工修正高于自动配对 | 当关联航班变化时旧配对失效 | 更正产生 `TurnaroundCorrected` | 允许 | 返回当前值 + link_confidence |
| Stand Assignment | 资源分配 | 机场运行系统 | 人工调度 | 自动分配默认为 `estimated`,人工为 `confirmed` | 时间窗失效后不再生效 | 新分配替换旧分配并保留历史 | 必须支持 | 返回当前值 + 覆盖摘要 |
| Gate Assignment | 资源分配 | 机场运行系统 | 人工调度 | 同上 | 同上 | 同上 | 必须支持 | 返回当前值 + 覆盖摘要 |
| Belt Assignment | 资源分配 | 机场运行系统 | 人工调度 | 同上 | 同上 | 同上 | 必须支持 | 返回当前值 + 覆盖摘要 |
| Counter Assignment | 资源分配 | 机场运行系统 | 人工调度 | 同上 | 同上 | 同上 | 必须支持 | 返回当前值 + 覆盖摘要 |
## 4. 冲突裁决优先级
当多个 Observation 竞争同一字段时,按以下顺序裁决:
1. 字段权威来源优先级
2. 明确更正 / 更高版本号
3. `confidence`
4. `occurred_at`
5. `source_sequence``ingest_sequence`
6. 人工裁决
## 5. 最小输出契约
对外查询至少返回:
- `current_value`
- `source`
- `confidence`
- `last_decision_summary`(可空)
- `updated_at`
- `data_quality_flags`
## 6. 测试场景
1. ALDT 出现 ANSP 与航司冲突,系统自动按来源优先级裁决。
2. TOBT 出现多个地服更正,系统按更正版本和时间序列更新。
3. Stand Assignment 在延误后重新分配,旧分配转历史,新分配变当前值。
4. Turnaround 自动配对后被人工修正,系统产生 `TurnaroundCorrected`
5. Cancelled Flag 被恢复时,必须有显式更正,不允许静默取消取消状态。
@@ -0,0 +1,176 @@
# AODB 最小部署拓扑草案
## 1. 文档定位
本文档给出 AODB MVP 的最小部署拓扑、关键高可用策略和恢复思路,用于细化高层设计中的部署、SLO 和容灾约束。
## 2. 目标
- 以单机场私有化部署为前提
- 优先满足当前态统一、事件不丢、审计可回放
- 用最少组件完成可恢复、可观测、可演练的运行形态
## 3. 逻辑拓扑
```text
+-------------------------+
| External Systems |
| SSIM / AIDX / AFTN |
+------------+------------+
|
v
+-------------------+
| Kong Gateway |
+-------------------+
|
+---------------+----------------+
| | |
v v v
+----------------+ +----------------+ +------------------+
| Flight Service | | Milestone Svc | | External API Svc |
+----------------+ +----------------+ +------------------+
| | |
+-------+-------+----------------+
|
v
+----------------------+
| PostgreSQL/Timescale |
| Current + Audit + |
| Outbox |
+----------+-----------+
|
v
+---------------+
| CDC/Publisher |
+-------+-------+
|
v
+-------+
| Kafka |
+---+---+
|
+----------+-----------+
| |
v v
+----------------+ +----------------+
| Resource Svc | | Alert Service |
+----------------+ +----------------+
+----------------+
| Redis Cache |
+----------------+
+-------------------------------+
| Prometheus / Grafana / Loki |
+-------------------------------+
```
## 4. 部署分区建议
### 4.1 状态层
- PostgreSQL / TimescaleDB
- Kafka
- Redis
要求:
- 与无状态服务分离部署
- 具备独立备份和恢复策略
### 4.2 无状态业务层
- Flight Operation Service
- Milestone Service
- Resource Service
- Alert Service
- External API Service
- CDC / Publisher
要求:
- 多副本
- 滚动升级
- 配置和密钥外置
### 4.3 平台观测层
- Kong
- Keycloak
- Prometheus
- Grafana
- Loki
## 5. 高可用建议
### 5.1 PostgreSQL / TimescaleDB
- 主备部署
- 定期全量备份 + WAL / PITR 能力
- 演练主备切换
### 5.2 Kafka
- 多 broker
- `replication factor >= 3`
- `min ISR >= 2`
- 消费位点外部可追踪
### 5.3 Redis
- 主从或哨兵
- 缓存失效不应影响核心写链路
### 5.4 无状态服务
- 至少 2 副本
- 健康检查 + 自动重启
- 发布器必须支持重复执行幂等
## 6. 最小恢复策略
### 6.1 数据库故障
- 切换到备实例
- 根据最近备份和 WAL 进行恢复
- 恢复后执行 Published Fact 与 Outbox 对账
### 6.2 Kafka 堆积或单 broker 故障
- Broker 恢复后消费者追赶
- 重点检查订阅延迟、DLQ 率、CDC 积压
### 6.3 CDC / Publisher 中断
- 根据 Outbox 位点断点续传
- 保证重复发布不产生重复副作用
### 6.4 查询层异常
- 核心写链路不中断
- 对外查询可降级,但订阅恢复后必须可补偿
## 7. 关键观测指标
| 指标 | 含义 |
| --- | --- |
| ingest_to_publish_latency_p95 | 接入到发布的 P95 延迟 |
| outbox_backlog | Outbox 堆积量 |
| cdc_publish_retry_count | 发布重试次数 |
| kafka_consumer_lag | 消费滞后量 |
| dlq_rate | 解析失败和旁路率 |
| conflict_mttr | 冲突平均处置时间 |
| review_task_open_count | 未关闭复核任务数 |
## 8. 关键演练场景
1. PostgreSQL 主备切换
2. Kafka 单 broker 故障恢复
3. CDC 中断和断点恢复
4. 订阅端断线重连与游标补偿
5. 关键字段回放抽检
## 9. 与高层设计的关系
- 本文档细化 `开源机场运营数据库(AODB)高层设计文档.md` 中的部署与 SLO 章节。
- 它不是最终部署手册,但必须足以支撑架构评审、容灾设计和运维基线定义。
+111
View File
@@ -0,0 +1,111 @@
# AODB 核心需求提炼
## 1. 文档定位
本文档定义 AODB 的业务目标、范围边界、核心能力和约束条件,作为高层设计和技术选型的上位输入。
- 目标对象:年旅客吞吐量 500 万至 3000 万的中型机场
- 目标系统:机场运营数据库(AODB)及其核心协同能力
- 使用方式:作为 `开源机场运营数据库(AODB)高层设计文档.md``开源技术栈选型决策.md` 的上位需求输入
## 2. 业务目标与范围
### 2.1 业务目标
1. 建立航班运营单一事实源(SSOT),消除多系统数据不一致。
2. 支撑航班计划、动态运行、资源分配和里程碑协同的闭环运营。
3. 通过事件驱动架构实现秒级数据传播,提升调度响应效率。
4. 以开源技术栈实现可控成本、可持续演进和私有化可部署能力。
### 2.2 范围边界
MVP(首期必须):
- 航班计划导入(SSIM)与动态更新(AIDX/AFTN
- 机位/登机口/行李转盘/值机柜台基础资源分配
- A-CDM 核心里程碑管理与变更发布
- 运营告警(延误、资源冲突)
- 外部数据共享接口(查询 + 事件订阅)
- 审计、裁决、人工复核闭环
非 MVP
- 高级优化排班(全局优化/仿真)
- 深度 AI 预测(跨季节模型、异常解释)
- 多机场统一调度与集团化运营
- 起飞排序和复杂流处理平台化能力
### 2.3 范围约束
- 单机场优先,跨机场能力不作为 MVP 前提。
- MVP 聚焦“当前态统一、事件可追溯、人工可介入”,不以复杂优化能力为前提。
- 若外部系统稳定性不足,必须预留灰度、手工复核和数据质量标记兜底流程。
- 首期不要求深度历史迁移,只要求新接入链路具备统一主键、幂等和审计能力。
## 3. 功能需求清单
| 功能域 | 核心能力 | 输入 | 输出 | MVP |
| --- | --- | --- | --- | --- |
| 航班数据管理 | 航班计划导入、动态更新、历史回放、航班配对(Linking | SSIM、AIDX、AFTN | 标准化航班主数据与状态流 | 是 |
| 资源管理 | 机位/登机口/行李转盘/值机柜台分配与冲突检测 | 航班状态、资源可用性、规则 | 资源分配结果、冲突事件 | 是 |
| A-CDM 里程碑 | 里程碑采集、校验、发布、追踪 | ANSP/航司/地服事件 | 里程碑状态、时序记录 | 是 |
| 裁决与复核 | 数据冲突复核、人工覆盖、事件重放 | 冲突事件、复核任务 | 裁决记录、发布事实 | 是 |
| 告警与预警 | 延误告警、冲突告警、超阈值告警 | 实时事件、规则配置 | 告警通知、处置状态 | 是 |
| 信息共享(ACISP) | 面向航司/管制/地服的数据查询与订阅 | 业务实体与事件 | 外部查询/订阅接口 | 是 |
| 实时计算增强 | EIBT/EXIT/EXOT 预测、TSAT 计算 | 运行态事件、历史统计 | 预测结果、排序建议 | P1 |
| 起飞排序(PDS | TSAT/TTOT/EXOT 规则计算与可追溯 | 里程碑、滑行预测、管制约束 | 排序建议与调整记录 | P1 |
## 4. 标准与集成要求
- AIDXAviation Information Data Exchange):用于航班动态交换。
- SSIM Chapter 7:用于季节性时刻表批量导入。
- AFTN/SITA Type B:用于传统航电与运行消息接入。
- ACARS(可选):用于补充机载状态数据接入。
集成约束:
1. 所有外部输入必须经过标准化映射层,生成统一内部事件模型。
2. 所有关键写入必须具备幂等键和可追溯来源字段。
3. 解析失败消息必须进入死信队列并提供人工复核入口。
4. 当前权威值不得直接由多个系统并行写入,必须经过字段级权威矩阵和裁决逻辑。
## 5. 非功能需求
| 维度 | 目标值 | 最低可接受值 | 说明 |
| --- | --- | --- | --- |
| 可用性 | 月度 99.95% | 月度 99.9% | 保障核心运行时段可用 |
| 事件处理延迟 | P95 <= 2 秒 | P95 <= 5 秒 | 覆盖接入到发布事实主链路 |
| 数据一致性 | 关键实体强一致 | 最终一致 <= 30 秒 | 当前态和事件流必须可对账 |
| 恢复能力 | RTO <= 30 分钟,RPO <= 5 分钟 | RTO <= 2 小时,RPO <= 15 分钟 | 支撑单机场容灾恢复 |
| 审计追踪 | 100% 关键变更可追溯 | 99.9% 可追溯 | 覆盖自动裁决和人工动作 |
| 安全 | OIDC/OAuth2 + RBAC + 传输加密 | RBAC + 传输加密 | 对外查询和订阅必须受控 |
## 6. 架构约束
- Flight 当前态必须只有一个写主,不允许多个系统直接并行改写权威字段。
- 所有关键写入必须带来源、时间、幂等键和关联 ID。
- 原始观测、裁决记录、发布事实必须分层保存,不允许只保留当前值。
- 查询接口和事件订阅接口必须分离,不允许把查询层当作事实流输出。
- 人工覆盖、回滚和复核必须事件化、审计化。
## 7. 术语与缩写(权威定义)
| 缩写 | 定义 |
| --- | --- |
| AODB | Airport Operational Database,机场运营数据库 |
| SSOT | Single Source of Truth,单一事实源 |
| A-CDM | Airport Collaborative Decision Making,机场协同决策 |
| TSAT | Target Start-up Approval Time,目标放行时间 |
| TTOT | Target Take-off Time,目标起飞时间 |
| EXOT | Estimated Taxi-Out Time,预计滑出时间 |
| EXIT | Estimated Taxi-In Time,预计滑入时间 |
| EIBT | Estimated In-Block Time,预计靠桥时间 |
| Turnaround | 航班过站对象,关联到达航班、离港航班与飞机周转上下文 |
## 8. 关联文档
- `airport-wiki/concepts/aodb/开源技术栈选型决策.md`
- `airport-wiki/concepts/aodb/开源机场运营数据库(AODB)高层设计文档.md`
- `airport-wiki/concepts/aodb/AODB 字段级权威矩阵.md`
- `airport-wiki/concepts/aodb/AODB 事件 Schema 草案.md`
- `airport-wiki/concepts/aodb/AODB 最小部署拓扑草案.md`
@@ -0,0 +1,24 @@
# ADR-001 MVP 不引入 Flink
## 状态
Accepted
## 背景
首期目标是完成单机场 AODB 核心闭环,规模为 500 万至 3000 万旅客机场,优先解决当前态统一、资源冲突和审计问题。
## 决策
MVP 不引入 Flink。首期只保留 Kafka 事件骨干和应用服务内流式处理逻辑。预测、CEP 和复杂有状态计算推迟到 P1。
## 原因
- 首期复杂度应优先让位于交付确定性。
- 预测与复杂流处理不是首期闭环前提。
- Flink 会显著提高部署、运维和故障恢复复杂度。
## 后果
- MVP 中实时计算能力受限。
- 事件契约和聚合边界必须为未来引入 Flink 预留演进空间。
@@ -0,0 +1,24 @@
# ADR-002 Kafka 作为唯一事件骨干
## 状态
Accepted
## 背景
AODB 需要支撑事件可回放、订阅分发、补偿和审计。
## 决策
Kafka 作为唯一事实事件骨干。所有对外事件订阅都以 Kafka 上的标准化事件为源头,禁止多路事件源头并存。
## 原因
- 统一重放和补偿语义。
- 避免“写库成功但未发布”或“已发布但未落库”的治理空洞。
- 降低外部消费者理解成本。
## 后果
- 事件可靠发布必须依赖 Outbox + CDC。
- 查询 API 不能被下游误当作事件事实源。
@@ -0,0 +1,24 @@
# ADR-003 事实分层模型
## 状态
Accepted
## 背景
AODB 需要同时处理多源观测、字段裁决和对外权威事实发布。
## 决策
采用 `Observation / Decision / Published Fact` 三层模型。
## 原因
- 让 SSOT 真正表示“经过治理后发布的事实”。
- 保证原始观测、人工覆盖和当前值三者不互相污染。
- 便于审计、回放和责任归因。
## 后果
- 数据模型和事件模型会更明确,但设计和实现复杂度略有上升。
- Published Fact 的任何变更都必须可追溯到 Observation 和 Decision。
@@ -0,0 +1,24 @@
# ADR-004 FlightOperation 写主归属
## 状态
Accepted
## 背景
原方案中 Flight、Milestone、Resource、Alert 边界存在写入重叠风险。
## 决策
Flight 当前权威态只能由 `Flight Operation Service` 写入,其他服务只能产生观测、候选事实、资源事实或告警事实。
## 原因
- 避免多个服务共同修改同一当前态。
- 降低一致性和回放复杂度。
- 方便将 Published Fact 聚合到单一领域对象。
## 后果
- Milestone 和 Resource 服务必须通过事件影响 Flight 当前态。
- Flight Service 需要承担更明确的聚合协调责任。
@@ -0,0 +1,24 @@
# ADR-005 Turnaround 独立建模
## 状态
Accepted
## 背景
仅以单航班建模无法充分表达到离港配对、机尾号上下文和资源联动。
## 决策
`Turnaround` 作为首期核心领域对象,引入最小独立建模。
## 原因
- 支撑航班配对(Linking)需求。
- 提高资源分配和时序解释能力。
- 为换机、延误联动和周转分析提供上下文。
## 后果
- 文档和模型复杂度上升。
- 配对修正和不完整配对需要额外的事件和审计语义。
@@ -0,0 +1,24 @@
# ADR-006 资源锁定模型
## 状态
Accepted
## 背景
单纯的资源时间窗分配无法表达建议分配、已确认分配和人工强制覆盖。
## 决策
ResourceAllocation 支持 `soft lock``hard lock` 两种锁定语义。
## 原因
- 表达自动建议和人工强制分配的区别。
- 支持冲突检测、覆盖和回滚的可解释性。
- 为未来优化排班预留空间。
## 后果
- 冲突检测和分配逻辑需要区分锁定强度。
- 人工覆盖必须伴随审计和事件输出。
@@ -0,0 +1,24 @@
# ADR-007 查询与订阅分离
## 状态
Accepted
## 背景
将 GraphQL Subscription 或查询层直接作为事实流会混淆读取和事件分发语义。
## 决策
对外查询接口和事件订阅接口分离设计。
## 原因
- 查询和事件分发的稳定性、回放、限流语义不同。
- 便于明确外部消费者的消费契约。
- 降低把查询接口误当权威事件骨干的风险。
## 后果
- 需要独立设计事件订阅网关或分发适配层。
- API 文档要分别描述查询和订阅契约。
@@ -0,0 +1,24 @@
# ADR-008 Outbox 与 CDC
## 状态
Accepted
## 背景
AODB 必须避免“写库成功但没发事件”或“发了事件但没落库”。
## 决策
采用 `Outbox Pattern + CDC` 作为写库与发事件一致性策略。
## 原因
- 能把数据库状态变化和事件发布绑定到同一事务边界。
- 适合首期 Kafka 作为唯一事件骨干的架构。
- 支持失败重试、断点恢复和事件回放。
## 后果
- 需要部署 CDC / 发布器组件。
- 发布流程和 Outbox 堆积需要专门监控。
@@ -0,0 +1,24 @@
# ADR-009 PostgreSQL HA
## 状态
Accepted
## 背景
Published Fact、审计和 Outbox 都依赖 PostgreSQL,数据库可用性直接决定系统可用性。
## 决策
MVP 必须采用 PostgreSQL 高可用部署,并具备备份恢复和 PITR 或等价能力。
## 原因
- 满足 RTO / RPO 目标。
- 为审计、重放和一致性提供稳定基础。
- 避免首期把可靠性寄托在应用层补偿上。
## 后果
- 部署和运维门槛上升,但这是首期必须承担的复杂度。
- 需要单独演练主备切换和恢复流程。
@@ -0,0 +1,24 @@
# ADR-010 人工裁决事件化
## 状态
Accepted
## 背景
AODB 中数据冲突、资源覆盖和解析失败都可能需要人工参与。
## 决策
所有人工裁决、人工覆盖和人工复核动作必须事件化和审计化,禁止仅通过数据库备注或日志留痕。
## 原因
- 人工动作是业务事实的一部分。
- 需要对外解释当前值为何成立。
- 便于回放、对账和合规审计。
## 后果
- Case 流程和审计模型需要更完整。
- 首期必须实现最小人工复核状态机。
@@ -0,0 +1,101 @@
# 开源技术栈选型决策
## 1. 决策目标与原则
本文档用于对 AODB 技术栈做唯一主选决策,避免多方案并列导致实施阶段反复。
决策原则:
1. 满足中型机场场景下的稳定性与可维护性。
2. 优先选择成熟开源生态和团队可落地能力。
3. 对核心路径采用单一主选,备选仅定义触发条件。
4. 支持私有化部署和后续多机场扩展。
5. MVP 优先收敛复杂度,不以技术先进性替代交付确定性。
## 2. 技术栈总览
### 2.1 MVP 主选
| 分层 | 主选方案 | 说明 |
| --- | --- | --- |
| 主数据存储 | PostgreSQL 16 | 关键业务数据强一致事务 |
| 时序存储 | TimescaleDB | 里程碑、观测与审计时间序列 |
| 缓存与热点读 | Redis 7 (Valkey) | 高频读、短期缓存、去重辅助 |
| 事件总线 | Apache Kafka 3.x | 统一事件骨干和可回放能力 |
| 协议集成 | Apache Camel | AIDX / AFTN / SITA 协议适配 |
| API 网关 | Kong Gateway OSS | 鉴权、限流、路由治理 |
| 认证授权 | Keycloak 24 | OIDC / OAuth2 与 RBAC |
| 可观测性 | Prometheus + Grafana + Loki | 指标、看板、日志观测 |
| 容器平台 | Kubernetes + Helm | 标准化部署与环境一致性 |
### 2.2 后续启用组件
| 组件 | 定位 | 启用触发条件 | 当前决策 |
| --- | --- | --- | --- |
| Flink | 有状态流处理、预测、CEP | EIBT / EXIT / EXOT 预测进入上线范围,且简单流式处理无法满足延迟和可恢复性目标 | P1 |
| Drools | 复杂规则平台 | 规则量、规则变更频率和回放需求超过代码化规则可维护边界 | P1 |
| Temporal | 长流程编排与补偿 | 人工复核、跨系统补偿和状态机复杂度超出单服务事务编排能力 | P1 |
| Hasura | 快速 GraphQL 查询与订阅暴露 | 前端字段裁剪、实时订阅和权限编排复杂度显著上升 | 可选 |
| OpenSearch | 搜索与分析投影 | 全文检索、复杂检索、跨字段搜索成为上线能力 | P1 |
| Linkerd | 服务间 mTLS 与服务治理 | 服务数量、零信任要求和多团队治理复杂度显著增加 | 可选 |
| MinIO | 对象存储 | 需要保存批量导入文件、报文附件和复核证据对象 | 可选 |
| React + TypeScript + PWA | 运营终端前端栈 | 本期建设自研终端而非只做系统接口时启用 | 可选 |
## 3. 关键决策与备选触发条件
| 决策项 | 主选 | 备选 | 触发备选条件 | 说明 |
| --- | --- | --- | --- | --- |
| 搜索引擎 | 暂不纳入 MVP | OpenSearch | 上线阶段需要全文检索、复杂筛选和日志联动检索时 | MVP 不为未来检索需求预埋过重组件 |
| GraphQL 引擎 | 暂不纳入核心路径 | Hasura / PostGraphile | 面向运营终端的字段选择和订阅编排复杂度上升时 | 查询接口与事件骨干分离 |
| 工作流引擎 | 暂不纳入 MVP | Temporal | 人工复核和补偿流程演进为复杂长事务时 | MVP 先用应用服务内状态机 |
| 服务网格 | 暂不纳入 MVP | Linkerd / Istio | 服务间零信任、mTLS 和流量治理要求增强时 | 中型机场首期不引入服务网格 |
| 流处理引擎 | 暂不纳入 MVP | Flink | 预测 / CEP / 大规模乱序处理成为上线前提时 | 首期不以预测能力为闭环前提 |
| 规则引擎 | 代码化规则 + 版本化配置 | Drools | 规则规模和运营配置频率显著增长时 | 降低首期认知与运维成本 |
## 4. 分层选型理由(精要)
### 4.1 数据层
- PostgreSQL + TimescaleDB 统一 SQL 体验,降低多数据库运维复杂度。
- Redis 负责热点读、去重辅助和临时缓存,减轻主库读取压力。
- 首期不引入搜索引擎,避免为非关键路径增加一套额外状态系统。
### 4.2 消息与处理层
- Kafka 作为唯一事件骨干,保障事件可回放与可追溯。
- 首期不引入 Flink,先聚焦标准化、裁决、发布事实和资源冲突闭环。
- 首期规则逻辑采用应用内代码化实现,并以版本化配置和回放测试约束演进。
### 4.3 集成与接口层
- Camel 统一协议适配,减少自研连接器维护成本。
- Kong 提供统一北向入口及治理能力。
- 查询接口和事件订阅接口分离,避免将查询层误用为事实事件骨干。
### 4.4 安全与基础设施层
- Keycloak 提供统一身份与授权管理。
- Kubernetes + Helm 提供标准化部署与环境一致性。
- 可观测性先聚焦指标、日志和告警,链路追踪和服务网格在服务规模扩大后再引入。
## 5. 风险与缓解
| 风险 | 影响 | 缓解措施 |
| --- | --- | --- |
| Kafka 运维门槛高 | 实施初期效率下降 | 提供最小可运行拓扑、标准化 Topic 规划和 SRE Runbook |
| 多协议接入数据质量不稳定 | 里程碑发布事实误差 | 建立标准化校验、死信队列和人工复核流程 |
| 规则逻辑散落在服务代码 | 规则可维护性下降 | 统一规则目录、版本化配置和回放测试 |
| 未来再引入 Flink / Temporal 成本上升 | 迁移复杂度提升 | 通过事件契约、聚合边界和 ADR 先锁死演进接口 |
| 文档与实现偏离 | 评审通过后落地失真 | 将关键决策同步为 ADR 并纳入变更流程 |
## 6. 版本与升级策略
- 技术栈版本采用“年度主版本评审 + 季度补丁更新”策略。
- 升级优先级:安全补丁 > 稳定性修复 > 新功能。
- 升级前必须完成回归测试、性能基线对比和回滚演练。
## 7. 与架构文档的边界
- 本文档回答“首期选什么、为什么选、何时启用后续组件”。
- 具体数据模型、事件契约、流程编排细节在 `开源机场运营数据库(AODB)高层设计文档.md` 中定义。
- 本文档不替代 ADR;关键决策以 `airport-wiki/concepts/aodb/adr/` 下文件为准。
@@ -0,0 +1,510 @@
# 开源机场运营数据库(AODB)高层设计文档
## 1. 文档目标
本文档定义 AODB MVP 的技术方案基线,重点回答以下问题:
1. AODB 在 MVP 内承载哪些业务闭环,以及哪些能力明确不做。
2. 系统如何划分聚合、服务、数据流和事件边界。
3. 航班、里程碑、资源、告警等核心对象如何建模。
4. 发布事实如何在观测、裁决、审计和订阅之间保持一致。
5. 查询、订阅、部署、容灾和可观测性如何落到可实现架构。
适用范围:年旅客吞吐量 500 万至 3000 万机场,优先支持单机场部署。
## 2. 设计原则
- 单一事实源:AODB 对外发布单一当前权威事实,不暴露“谁最后写入”式伪一致。
- 事实分层:原始观测、裁决记录、发布事实必须分层建模。
- 写主清晰:每个核心聚合只允许一个服务写入,避免跨服务共享可变状态。
- 事件驱动:状态变化通过事件传播,系统通过契约解耦。
- 规则可解释:字段权威、冲突裁决、人工覆盖必须可追溯、可回放、可解释。
- 渐进复杂度:MVP 先建立稳定闭环,不引入复杂优化平台和长事务编排平台。
## 3. 范围定义
### 3.1 MVP 范围
首期只覆盖以下闭环:
- 航班计划导入与实时状态更新
- 航班配对与过站上下文最小建模
- 基础资源分配:Stand、Gate、Belt、Counter
- 关键里程碑跟踪与发布事实治理
- 延误、资源冲突和数据质量告警
- 对外查询接口与事件订阅
- 审计、人工裁决、重放与复核闭环
### 3.2 非 MVP 范围
首期不纳入以下能力:
- 全局优化排班和复杂资源优化求解
- 深度 AI 预测和自适应调度
- Flink 驱动的复杂 CEP 平台
- Temporal 驱动的复杂长事务工作流平台
- 多机场统一调度中心能力
## 4. 总体架构
### 4.1 架构分层
| 层级 | 主要能力 | MVP 主路径组件 | 说明 |
| --- | --- | --- | --- |
| 接入层 | 外部系统接入、协议解析、统一北向入口 | Kong Gateway、Apache Camel、SSIM 导入器 | 接收计划、动态、资源和人工操作输入 |
| 业务层 | 航班当前态、观测治理、资源分配、告警处置、外部接口 | Flight Operation Service、Milestone Service、Resource Service、Alert Service、External API Service | 承担领域逻辑和对外契约 |
| 事件层 | 事件骨干、重放、订阅分发 | Kafka、Outbox/CDC 发布器 | 负责异步传播和回放 |
| 数据层 | 事务存储、时序存储、缓存 | PostgreSQL、TimescaleDB、Redis | 保存当前态、审计链路和热点读模型 |
| 平台层 | 认证鉴权、部署、观测 | Keycloak、Kubernetes、Prometheus/Grafana/Loki | 提供运行时底座 |
### 4.2 核心技术链路
MVP 主链路采用“接入标准化 -> 观测入库 -> 裁决生成 -> 发布事实更新 -> 事件发布 -> 查询/订阅消费”的结构:
1. 外部计划或运行动态通过接入层进入系统。
2. Milestone Service 将输入标准化为 Observation,并按幂等键写入。
3. 规则引擎根据字段权威矩阵和当前上下文生成 Decision。
4. Flight Operation Service 更新 Published Fact 和当前状态摘要。
5. 同一事务内写入 Outbox,由 CDC 发布到 Kafka。
6. External API Service 对外提供查询接口和事件订阅接口。
7. 告警、人工裁决和重放都沿同一事实链路工作,不直接绕过 Published Fact。
### 4.3 领域划分与聚合边界
为避免多服务共同修改同一业务对象,MVP 采用以下聚合边界:
| 聚合 | 职责 | 主键 | 写主 | 发布事件 | 只读依赖 |
| --- | --- | --- | --- | --- | --- |
| FlightOperation | 航班当前权威态、运行状态、发布事实 | `flight_id` | Flight Operation Service | `FlightUpdated``PublishedFactUpdated` | Turnaround、MilestoneObservation、ResourceAllocation |
| MilestoneObservation | 里程碑原始观测、标准化观测、候选事实 | `observation_id` | Milestone Service | `MilestoneObserved``MilestoneNormalized` | FlightOperation |
| Turnaround | 到达航班、离港航班、飞机周转上下文 | `turnaround_id` | Flight Operation Service | `TurnaroundLinked``TurnaroundCorrected` | FlightOperation |
| ResourceAllocation | 资源占用、锁定、冲突、覆盖 | `allocation_id` | Resource Service | `ResourceAssigned``ResourceUnassigned``ResourceConflictDetected` | FlightOperation、Turnaround |
| AlertCase | 告警和处置对象 | `alert_id` | Alert Service | `AlertRaised``AlertAcknowledged``AlertCleared` | FlightOperation、ResourceAllocation |
边界约束:
- Flight 当前权威态只能由 `Flight Operation Service` 写入。
- Milestone Service 负责观测和候选事实,不直接改写 Flight 当前态。
- Resource Service 只拥有资源占用与冲突事实,不直接修改 Flight 当前态中的非资源字段。
- Alert Service 不产生业务事实,只管理处置状态和告警生命周期。
### 4.4 核心服务职责
- `Flight Operation Service`
- 管理 FlightOperation 当前态。
- 维护 Published Fact。
- 负责 Turnaround 建模和关联修正。
- `Milestone Service`
- 接收外部运行动态。
- 解析、标准化并形成 MilestoneObservation。
- 依据字段权威矩阵给出候选事实。
- `Resource Service`
- 管理资源主数据和资源分配。
- 进行适配校验、冲突检测、人工覆盖和回滚。
- `Alert Service`
- 管理告警、确认、关闭、抑制和处置轨迹。
- `External API Service`
- 提供查询接口。
- 提供事件订阅接口或订阅分发适配层。
- 不作为权威事实生成者。
## 5. 核心模型
### 5.1 核心标识约定
- Flight
- `flight_key``carrier + flight_number + op_date + leg_no`
- `flight_id`:内部不可变主键
- Turnaround
- `turnaround_id`
- 可关联一个到达航班和一个离港航班
- MilestoneObservation
- `observation_id`
- 幂等键优先使用上游报文 ID、序列号或批次 + 行号
- Resource
- `resource_id`
- `resource_type + resource_code` 唯一
- ResourceAllocation
- `allocation_id`
- 幂等键由 `resource_id + validity_window + assignment_source + correlation_id` 组合约束
### 5.2 核心实体与关系
- FlightOperation:指定运行日上的航班运行对象,包含当前发布事实和状态摘要。
- Turnaround:将到达航班、离港航班和飞机周转上下文关联起来,用于资源和时序联动。
- MilestoneObservation:里程碑观测记录,保留原始来源、标准化结果和候选事实。
- Resource:资源主数据,MVP 覆盖 Stand、Gate、Belt、Counter。
- ResourceAllocation:资源分配记录,含有效窗口、锁定类型、来源和覆盖原因。
- AlertCase:告警对象,关联 FlightOperation 或 ResourceAllocation。
- DataQualityFlag:对冲突、低可信度、超窗乱序、待裁决等问题做结构化标记。
关系约束:
- 一个 FlightOperation 对应多个 MilestoneObservation。
- 一个 Turnaround 可关联一个到达航班和一个离港航班,也允许只有单侧航班待补全。
- 一个 Resource 在时间轴上可关联多个 ResourceAllocation,但硬冲突不允许同时生效。
- AlertCase 可关联具体 FlightOperation、Turnaround 或 ResourceAllocation。
### 5.3 FlightOperation 最小字段组
- 主键:`flight_id``flight_key`
- 属性:`carrier``flight_number``op_date``leg_no``direction`
- 机体上下文:`aircraft_type``tail_number`(可空)
- 状态:`flight_status`
- 发布事实:计划 / 预计 / 实际时间类字段
- 当前资源摘要:Stand / Gate / Belt / Counter
- 质量摘要:冲突标记、待裁决标记、最近裁决摘要
- 关联:`turnaround_id`(可空)
### 5.4 Turnaround 最小字段组
- `turnaround_id`
- `arrival_flight_id`
- `departure_flight_id`
- `tail_number`
- `aircraft_type`
- `turnaround_status`
- `link_source`
- `link_confidence`
约束:
- 配对可以晚于航班导入发生。
- 配对修正必须产生 `TurnaroundCorrected` 事件并保留审计。
- 若未知配对,FlightOperation 仍可独立运行,但资源和里程碑解释能力下降。
## 6. 事实分层模型
### 6.1 三层模型
| 层 | 含义 | 是否可变 | 用途 |
| --- | --- | --- | --- |
| Observation | 上游原始或标准化观测 | 否 | 追溯、回放、取证 |
| Decision | 规则或人工裁决结果 | 否 | 解释为什么当前事实成立 |
| Published Fact | 当前对外权威事实 | 是 | 查询、订阅、共享 |
### 6.2 SSOT 定义
AODB 的 SSOT 不等于“数据库中的最后一次写入”,而是:
- 由 Observation 输入
- 经字段级权威矩阵与裁决逻辑处理
- 最终形成并发布的 Published Fact
### 6.3 状态写入三元信息
所有关键状态写入都必须附带:
- `source`
- `confidence`
- `decision`(可空)
其中:
- Observation 必须保存原始来源和原始时序。
- Decision 必须保存裁决者、依据、原因和裁决时间。
- Published Fact 必须能追溯到 Observation 和 Decision。
### 6.4 字段级权威矩阵(最小集)
| 字段 | 主来源 | 次来源 | 更正规则 | 人工覆盖 | 对外可见性 |
| --- | --- | --- | --- | --- | --- |
| ALDT | ANSP / 机场运行 | 航司 | 明确更正或高版本号优先 | 允许 | 返回当前值 + 来源 |
| AIBT | 地服 / 机场运行 | 航司 | 同上 | 允许 | 返回当前值 + 来源 |
| EIBT | 系统计算 | 运行动态派生 | 新计算覆盖旧计算并留历史 | 允许 | 返回当前值 + 可信度 |
| TOBT | 航司 / 地服 | 机场运行 | 最新有效更正优先 | 允许 | 返回当前值 + 裁决摘要 |
| TSAT | AODB / P1 PDS | 机场运行 | 新计算版本优先 | 允许 | 返回当前值 + 算法版本 |
| Stand Assignment | 机场运行系统 | 人工调度 | 人工覆盖优先并保留原因 | 必须审计 | 返回当前值 + 覆盖摘要 |
| Gate Assignment | 机场运行系统 | 人工调度 | 同上 | 必须审计 | 返回当前值 + 覆盖摘要 |
| Belt Assignment | 机场运行系统 | 人工调度 | 同上 | 必须审计 | 返回当前值 + 覆盖摘要 |
| Counter Assignment | 机场运行系统 | 人工调度 | 同上 | 必须审计 | 返回当前值 + 覆盖摘要 |
## 7. Flight 状态模型
### 7.1 最小状态机
- Planned:已导入计划但尚无有效运行动态。
- Active:已有运行动态、里程碑或资源变更。
- Completed:已达到收敛里程碑并进入归档策略。
- Cancelled:取消或无效,但保留完整历史。
### 7.2 状态迁移原则
- 状态迁移由 Published Fact 驱动,而不是由单个外部系统直接声明。
- 若存在冲突或裁决,不回滚 Observation 历史,只更新 Published Fact 和当前状态摘要。
- 状态修正必须能通过事件和审计链路回放。
## 8. 历史、审计与回放
### 8.1 数据存储视图
- `ObservationLog`
- 保存原始或标准化观测
- `DecisionLog`
- 保存规则命中和人工裁决
- `PublishedCurrentState`
- 保存当前对外权威事实
- `AuditTrail`
- 保存 `who / what / when / why`
### 8.2 基本约束
- PublishedCurrentState 的任何关键字段变更都必须能在 ObservationLog 和 DecisionLog 中找到原因链路。
- 人工覆盖不得改写原始 Observation,只能新增 Decision 并更新 Published Fact。
- 历史回放以事件和日志为准,不以任意时点快照为首期前提。
## 9. 资源模型与冲突治理
### 9.1 Resource 模型
每个 Resource 至少具备:
- `resource_id`
- `resource_type`
- `resource_code`
- `status`
- `capability_profile`
- `compatibility_constraints`
- `parent_resource_id`(可空)
- `operational_calendar`
### 9.2 ResourceAllocation 模型
每个 ResourceAllocation 至少具备:
- `allocation_id`
- `resource_id`
- `flight_id`
- `turnaround_id`(可空)
- `allocation_status`
- `assignment_source`
- `lock_type``soft` / `hard`
- `validity_window`
- `override_reason`(可空)
- `derived_from_event`
- `conflict_flags`
### 9.3 冲突分类
| 冲突类型 | 说明 | 是否阻断 | 是否允许人工覆盖 |
| --- | --- | --- | --- |
| 时间冲突 | 占用时间窗重叠 | 是 | 是 |
| 适配冲突 | 机型、能力或运行属性不匹配 | 是 | 受限 |
| 状态冲突 | 资源停用、维护、冻结 | 是 | 否 |
| 策略冲突 | 本地策略或运营规则违反 | 视规则 | 是 |
### 9.4 四类资源规则口径
- Stand
- 关注机型适配、拖曳、到离港时间窗、过站联动。
- Gate
- 关注旅客流程时间窗、国际国内属性、步行距离和能力约束。
- Belt
- 关注到港时序、机型、行李量经验参数和恢复能力。
- Counter
- 关注值机开放窗口、航司差异化规则和共享柜台能力。
### 9.5 人工覆盖原则
- 自动分配只产生建议或默认分配。
- 人工覆盖必须记录原因、证据、操作者和影响范围。
- 回滚必须和覆盖一样事件化和审计化。
## 10. 事件模型与一致性
### 10.1 事件分类
| 事件类别 | 说明 | 示例 |
| --- | --- | --- |
| Domain Events | 聚合内部事实变化 | `FlightUpdated``ResourceAssigned` |
| Integration Events | 对外共享的标准化事件 | `PublishedFactUpdated``AlertRaised` |
| Audit Events | 审计和裁决事件 | `ManualDecisionRecorded` |
| Case Events | 人工复核和告警处置状态变化 | `ReviewTaskOpened``AlertAcknowledged` |
### 10.2 MVP 事件清单
- `FlightImported`
- `FlightUpdated`
- `TurnaroundLinked`
- `TurnaroundCorrected`
- `MilestoneObserved`
- `MilestoneNormalized`
- `PublishedFactUpdated`
- `ResourceAssigned`
- `ResourceUnassigned`
- `ResourceConflictDetected`
- `AlertRaised`
- `AlertAcknowledged`
- `AlertCleared`
- `DataQualityFlagged`
- `ManualDecisionRecorded`
- `ReviewTaskOpened`
- `ReviewTaskClosed`
### 10.3 事件归属表
| 事件 | 归属聚合 | 触发条件 | 是否对外发布 | 是否可回放 |
| --- | --- | --- | --- | --- |
| `MilestoneObserved` | MilestoneObservation | 收到有效运行动态 | 否 | 是 |
| `PublishedFactUpdated` | FlightOperation | 当前权威事实发生变化 | 是 | 是 |
| `ResourceAssigned` | ResourceAllocation | 资源分配生效 | 是 | 是 |
| `ResourceConflictDetected` | ResourceAllocation | 检测到冲突 | 是 | 是 |
| `ManualDecisionRecorded` | Decision / Audit | 人工裁决完成 | 是 | 是 |
| `AlertRaised` | AlertCase | 达到告警条件 | 是 | 是 |
### 10.4 统一事件信封
所有业务事件必须具备:
- `event_id`
- `event_type`
- `schema_version`
- `occurred_at`
- `produced_at`
- `source`
- `idempotency_key`
- `correlation_id`
- `aggregate_id`
- `payload`
### 10.5 幂等、顺序和更正语义
- 所有写入事件必须携带 `idempotency_key`
- 顺序保证以 `flight_id` 为最小粒度。
- 更正必须显式表达,不允许静默覆盖已发布事实。
- 乱序允许在可配置窗口内重排,超窗进入审计旁路并打数据质量标记。
### 10.6 写库与发事件一致性
MVP 采用 `Outbox Pattern + CDC`
- 业务服务在同一事务内更新 PublishedCurrentState 并写入 Outbox。
- CDC / 发布器将 Outbox 可靠发布到 Kafka。
- 发布失败必须可重试、可恢复、可审计。
## 11. 查询接口与事件订阅
### 11.1 接口分离原则
- 查询接口负责读取 Published Fact、历史明细和告警状态。
- 事件订阅负责分发标准化事件流。
- 查询接口不是事实流;订阅接口不承担读模型查询职责。
### 11.2 查询接口
最小查询对象:
- FlightOperation 当前态
- MilestoneObservation 明细
- ResourceAllocation 生效集
- AlertCase 生命周期
最小要求:
- 支持按 `op_date``flight_id / flight_key`、资源类型、状态过滤
- 返回更新时间和数据版本
- 关键字段返回 `source / confidence / decision summary`
### 11.3 事件订阅接口
最小要求:
-`event_type``flight_id``op_date` 过滤
- 至少一次投递
- 支持断线重连和补偿
- 基于 `event_id` 或游标回放
- 支持租户隔离、连接数和推送速率限流
### 11.4 消费者契约
- 顺序仅保证到 `flight_id`
- 消费者必须按 `event_id` 去重
- 消费者必须处理数据质量标记和裁决摘要
- 回放窗口和游标语义必须文档化
## 12. 规则体系与人工复核
### 12.1 规则分类
- `authority rules`
- `validation rules`
- `conflict rules`
- `alert rules`
- `allocation heuristics`
### 12.2 规则最小模板
每条规则都必须定义:
- 输入
- 输出
- 优先级
- 命中条件
- 可解释字段
- 回放测试方式
### 12.3 人工复核对象
- 解析失败复核
- 里程碑冲突复核
- 资源冲突裁决
- 人工覆盖审批
### 12.4 Case 状态机
- `open`
- `assigned`
- `reviewing`
- `decided`
- `replayed`
- `closed`
原则:
- 所有人工动作都必须事件化。
- 所有人工动作都必须形成审计记录。
## 13. 非功能与部署
### 13.1 最小 SLO
| 指标 | 目标值 | 最低可接受值 |
| --- | --- | --- |
| 可用性 | 月度 99.95% | 月度 99.9% |
| 事件处理延迟 | P95 <= 2 秒 | P95 <= 5 秒 |
| 容灾恢复 | RTO <= 30 分钟,RPO <= 5 分钟 | RTO <= 2 小时,RPO <= 15 分钟 |
| 审计覆盖率 | 100% 关键变更可追溯 | 99.9% 可追溯 |
### 13.2 最小部署拓扑
| 组件 | 部署方式 | 高可用方式 | 失败影响 | 恢复方式 |
| --- | --- | --- | --- | --- |
| PostgreSQL / TimescaleDB | Stateful 部署 | 主备切换 + 定时备份 | 当前态和审计写入受影响 | 备份恢复 + 故障切换 |
| Kafka | 多副本集群 | 副本和 ISR 保障 | 事件流中断或降级 | Broker 恢复 + 消费追赶 |
| CDC / 发布器 | 无状态服务 | 多副本 + 幂等发布 | Outbox 堆积 | 断点续传 + 重试 |
| API / 业务服务 | 无状态部署 | 多副本 | 查询或写入能力降级 | 滚动恢复 |
| Redis | 主从或哨兵 | 缓存级高可用 | 热点查询性能下降 | 重建缓存 |
### 13.3 关键容灾约束
- PostgreSQL 必须具备 PITR 或等价恢复能力。
- Kafka 必须明确 `replication factor``min ISR`、保留窗口和重放策略。
- Outbox / CDC 必须具备断点恢复和重复投递幂等能力。
- 容灾演练必须覆盖数据库切换、事件堆积、订阅重连和回放。
### 13.4 可观测性要求
- 所有写路径必须具备请求追踪、事件追踪和审计追踪三类关联 ID。
- 关键链路必须暴露延迟、失败率、积压量和重试次数指标。
- 人工裁决、资源覆盖和更正事件必须进入统一审计检索视图。
- 订阅接口必须暴露连接数、滞后量、推送速率和补偿次数指标。
## 14. 文档边界与引用
- 本文档定义首期可开工的技术方案,不展开字段级数据字典和实现细节。
- 技术栈主选和启用条件以 `airport-wiki/concepts/aodb/开源技术栈选型决策.md` 为准。
- 需求边界以 `airport-wiki/concepts/aodb/AODB 核心需求提炼.md` 为准。
- 字段级权威矩阵以 `airport-wiki/concepts/aodb/AODB 字段级权威矩阵.md` 为准。
- 事件 envelope 和 payload 草案以 `airport-wiki/concepts/aodb/AODB 事件 Schema 草案.md` 为准。
- 最小部署拓扑和恢复策略草案以 `airport-wiki/concepts/aodb/AODB 最小部署拓扑草案.md` 为准。
- 关键设计取舍以 `airport-wiki/concepts/aodb/adr/` 下 ADR 为准。