Files
wyndham-ARR/DATABASE_SCHEMA_DICTIONARY.md
2026-07-31 15:11:42 +08:00

12 KiB
Raw Permalink Blame History

ARR 数据落库 MVP v1 数据字典

更新时间2026-07-28
权威 DDLdatabase/008_arr_mvp_v1_rebuild.sql
已部署目标:<ARR_DB_HOST>:5432/booking_test(远程测试库)

1. 模型边界

数据库只保存三类内容:

  1. ingestion:私有 OSS/本地 fixture 工件身份、Agent 处理运行、交付验收与 outbox
  2. booking:预订附件来源行、行级 Agent 解析版本和房型明细;
  3. finance:日报不可变版本、每条 XML 记录的全部 outcome、current 指针和渠道计数。

月报、渠道明细和每 10 日公司用房表均从只读视图/普通程序生成,不建 report_versions 或报表行表。第一版不包含多酒店、账户权限、RSVN 任务卡、邮件元数据和前端追溯页面。

统一类型:主键为 bigint identity,业务日期为 date,时间为 timestamptz,金额为 numeric(18,2),完整 JSON 为 jsonb

2. ingestion schema

ingestion.artifacts

只保存不可变私有对象的元数据,不保存文件字节、签名 URL 或凭据。

字段 类型 含义
id bigint 工件 ID
artifact_kind text booking_source_mdbooking_excelopera_xmldaily_xlsxmonthly_xlsxchannel_detail_xlsxcompany_ten_day_xlsxexception_xlsxresult_jsonstructured_result_json
storage_provider text osss3local_fixture
bucket_alias text 内部 bucket 别名,不含路径符
object_key text 私有对象键;禁止绝对路径、..、查询串和 fragment
object_version_id text? 对象存储版本号
etag text? provider ETag内容身份仍以 SHA-256 为准
original_filename text 安全原文件名
sha256 char(64) 内容哈希
byte_size bigint 文件大小,允许 0
mime_type text? MIME
created_at timestamptz 登记时间

唯一性:artifact_kind + sha256;同时约束 provider/bucket/object/version 身份唯一。

ingestion.processing_runs

ARR 拥有的一次逻辑处理运行,不是 RSVN 任务卡。

关键字段:run_keypipeline_typeopera_daily/booking_source_import)、源/结果工件 ID、run_status、请求及交付 processor/rule/schema 版本、delivery_sha256delivery_jsonbusiness_date、安全失败码/消息和完整时间线。

终态规则accepted 的 Opera 日报必须具备结果工件、营业日、交付版本、规则哈希和交付哈希rejected/failed 必须有失败码。

ingestion.processing_attempts

一次运行的可重试尝试。

关键字段:processing_run_idattempt_noattempt_status、64 位 idempotency_key、可选 remote_run_id、安全失败字段和时间线。运行内 attempt 序号唯一idempotency key 全局唯一。

ingestion.processing_deliveries

ARR 收到并验收的 DeliveryEnvelope。

关键字段:delivery_key、run/attempt、envelope_sha256、完整 envelope_jsondelivery_statusresult_status、processor/rule/schema、营业日、五类输入/输出工件 FK、daily_version_id、失败字段和接收/验收/提交时间。

同一个 delivery key 只能代表同一份交付;相同 attempt + envelope 哈希不得重复。

ingestion.outbox_events

与业务事务一起提交的隐私最小化可靠事件。

关键字段:event_keyaggregate_typeaggregate_idevent_typepayload、发布状态/次数/可用时间/发布时间和最后失败码。payload 只放 opaque ID、日期、计数和安全状态不放住客字段。

3. booking schema

booking.source_batches

一份预订 Excel 或当前 MD fixture 的导入批次。

字段:source_artifact_idsource_kindexpected_fixture/booking_excel)、source_format_version、可选参考年月、batch_status、source/accepted/failed 计数、失败字段和时间线。一个工件只能形成一个批次。

booking.current_source_batch

单行指针,指向公司报表当前使用的完整、已验收 Booking 批次。新工作簿只有在全部人工项确认或删除并完成原子激活后才替换该指针;历史批次保持不可变。

booking.extraction_drafts

上传工作簿的持久化提取草稿。关键字段包括 draft_id、私有源工件、draft_statusreviewing/activated/superseded、processor/rule/source 哈希、源行/工作表/Tour Code/提取项计数以及激活后的批次 ID。reviewing 草稿不会改变 current_source_batch

booking.extraction_draft_items

一条记录对应一个提取出的房型项目保留工作表、原行号、item 顺序、Tour Code、酒店原文、房型原始标识、标准/人工房型、数量、源片段和 automatic 标志。

review_statusconfirmedpendingdeleted:待人工项目保留已经识别到的数量但不进入有效 Booking 房量;人工填写房型并保存后转为 confirmed;删除是草稿内软删除,启用时只写入仍为 confirmed 的项目。

booking.source_rows

一行对应原文件中的一行,重复 Group Code 也必须分行保存。

字段 类型 含义
id bigint 来源行 ID
source_batch_id bigint 所属导入批次
source_worksheet text 原工作表
source_row_no integer 原行号
group_code_raw text 原始 Group Code/Tour Code
group_code_key text generated upper(btrim(group_code_raw)),精确关联键
type_of_room_raw text 原始 TYPE OF ROOM/โรงแรม 文本
no_of_rooms integer 该来源行总房数,必须大于 0
source_row_sha256 char(64) 来源坐标和业务值的确定性哈希
created_at timestamptz 落库时间

唯一性只针对“批次 + worksheet + 行号”和“批次 + 行哈希”,不把 Group Code 设为唯一。

booking.parse_versions

一条来源行的不可变程序解析版本。

字段:source_row_idversion_noparse_statusaccepted/needs_review/failed)、结果 Schema、processor 名称/版本、规则哈希、输入行哈希、结果哈希、完整已验收 result_json、失败字段和验收时间。版本唯一键为 source_row_id + version_no

精确 JSON 合同:database/contracts/booking-row-parse-result.schema.json

booking.room_items

程序提取并确认后可按 Group Code 查询的房型项目;一条来源行可拆出多项。

字段 类型 含义
parse_version_id bigint 所属解析版本
item_no integer Agent 输出顺序
room_type_raw text 原始房型显示
room_type_code text? 可选标准房型码
quantity integer 房数,必须大于 0
unit_price numeric? 解析单价;未知可为空
currency_code char(3)? ISO 三位大写币种
price_token_raw text? 例如 12,用于解释 1200
source_fragment text? 对应原文片段
created_at timestamptz 落库时间

同一解析版本内 item_no 唯一。

booking.current_row_parses

每条来源行唯一指向一个当前 accepted parse。触发器同时验证批次已 accepted、parse 已 accepted、所有 room item 数量合计等于来源行 no_of_rooms

Booking 视图

  • booking.v_current_room_items:逐来源行返回当前 accepted 的全部 room item 和来源坐标。
  • booking.v_group_room_item_summary:查询时按 group_code_key + 房型 汇总数量;不修改原始行。
  • booking.v_group_booking_rooms:生成 booking_room 展示串、总预订房数和命中来源行数。

4. finance schema

finance.daily_versions

一次 ARR 验收结果形成一个不可变日报版本。

字段:营业日/版本号、processing_run_id、源 XML/日报/result/structured-result/异常工件 FK、version_status、processor/rule/schema、result_sha256、五类 outcome 计数、失败字段和创建/验收/激活/替换时间。

五类计数必须严格满足:

source_rows = retained_rows
            + excluded_rate_code_rows
            + duplicate_rows
            + validation_failed_rows
            + price_unmatched_rows

验收成功版本状态为 validated/active/superseded失败交付可保存为 rejected但绝不能成为 current。

finance.daily_records

保存 structured-result 中每一条 XML reservation包括未进入正式日报的记录。

来源与处理字段:

字段 含义
daily_version_id 所属不可变版本
source_sequence Agent 连续源序号
source_location reservation[1]
source_worksheet/source_row_no Excel 型输入坐标;直接 XML 必须同时为空
outcome retainedexcluded_rate_codeduplicatevalidation_failedprice_unmatched
decision_codes 处理决定码数组
duplicate_of_record_id duplicate 指向同版本原记录

日报业务字段:

字段 类型
block_code text
adults / children integer
company_name / company_key text
confirmation_no text
disp_room_no text
effective_rate_amount numeric(18,2)
full_name text
res_comment text
group_code_key generatedupper(btrim(res_comment));空值为 null
trace_text text
no_of_rooms integer
products text
rate_code text
normalized_rate_code generated规范化 rate code
room_category_label text
arrival / departure date
nights integer
real_price / total_price / kb_amount numeric(18,2)
channel_key / pricing_method text

预订关联字段:booking_source_match_statusmatched/unmatched/missing_group_code/not_checkedbooking_source_match_count。重复 Group Code 命中多条来源行仍是 matched并记录实际命中数。

retained 记录强制约束:日期/晚数一致、金额非负、去重键完整、预订查询已检查,并且:

total_price = real_price × no_of_rooms × nights

finance.daily_channel_metrics

每个日报版本的渠道名称、确定性顺序和 retained 行数。主键为 daily_version_id + channel_key;同版本 channel_order 唯一。

finance.current_daily_versions

每个营业日唯一指向当前 active 版本。触发器阻止指向未激活或日期不一致的版本。同日修正先完整落新版本,最后原子切换该指针。

5. 业务只读视图

  • finance.v_active_daily_facts:仅 current daily version + outcome='retained';所有普通业务查询的权威源。
  • finance.v_monthly_report_rows:月报 20 列投影;RATE_AMOUNTROOM_CATEGORY 为字段别名,Booking Room 来自预订 Group Code 查询,TOTAL PRICE 直接使用日报值。
  • finance.v_channel_detailsARRIVAL、DEPARTURE、NIGHTS、BLOCK_CODE、RES_COMMENT、Booking Room、Total Booking Price 等Total Booking Price 等于该日报行 total_price,不按 Group Code 二次汇总。
  • finance.v_company_report_source:公司 10 日报表程序使用的 Finance 日期/价格事实和预订房型补充。
  • finance.v_daily_processing_audit:当前与历史版本的全部 outcome、决定码、duplicate lineage、源文件哈希、processor/rule/schema 和验收时间;用于以后追溯页面。

6. 精确关联规则

upper(trim(finance.daily_records.RES_COMMENT))
  = booking.source_rows.group_code_key

禁止使用 BLOCK_CODE 代替,禁止模糊匹配。预订数据只提供 Booking RoomFinance 自己提供到离日期、晚数、实际房数、价格和 total_price