Files
wyndham-ARR/database/APPLIED_MIGRATIONS.md
2026-08-04 12:37:26 +08:00

228 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ARR 测试数据库已执行记录
更新时间2026-08-04
状态008015 已提交014/015 已通过迁移回滚探针、正式应用、结构/数据复核及真实 PostgreSQL 草稿激活外层回滚验收。016 已提交代码、待在测试机 booking_test 应用并完成 OSS 月报验收。首次真实业务工作簿激活仍待操作员授权。
## 目标与隔离
- PostgreSQL`<ARR_DB_HOST>:5432`
- 数据库:`booking_test`
- 当前测试用户:`<TEST_DB_OWNER>`(数据库 owner、非超级用户尚非生产最小权限账号
- schema`ingestion``booking``finance``reporting`
- `public` 用户对象0
- 共享维护数据库 `postgres`:未修改
- 当前配置:`/path/to/private/booking-test-db.env`,权限 `0600`
- 旧 LAN 源库:`<LEGACY_DB_HOST>:5433/booking_test`,只读保留作临时回退
- 旧 LAN 配置:`/path/to/private/booking-test-lan-db.env`,权限 `0600`
应用和后续专项默认使用远程配置;只有明确执行回退核查时才使用 LAN 配置。本文不记录密码。
## 当前权威迁移
| 迁移 | SHA-256 | 状态 |
|---|---|---|
| `008_arr_mvp_v1_rebuild.sql` | `a29df928a2bcfca262216a9d53260528374b830266b3285f3687199cb802a530` | 已提交并验收 |
| `009_source_read_grants.sql` | `69c1dcea29b5148f4bf4aab4bd7e606109547849f6722d59bffd1ac756ecd8f8` | 已提交并验收 |
| `010_mcp_result_ingestion.sql` | `480a9d1c039d1b45aaa86e90470ef3f7057972be056731f0513a372588bffcf1` | 已提交并验收 |
| `011_artifact_object_identity.sql` | `dab8b2eb155161ab7c1400bd95655fed5b5a9c395174df97e10a5e8f333a08e7` | 已提交并验收 |
| `012_monthly_report_publication.sql` | `5f6da06031f9bc8ad1a7e37bf5c58bd7f777eb7b6f71cbd03c693b884960849f` | 已提交并验收 |
| `013_daily_upload_filename.sql` | `f7ea18d6b844d9bd90fa757a4cf8428d1dd5833c088ae23444ac81fbe204fb0a` | 已提交并验收 |
| `014_booking_current_source_batch.sql` | `23bf0fcc880225ca276d4d7d871057be4f7950e761ddbeed1df2a3c6e25463b5` | 2026-07-31 已通过同事务回滚探针后由受控连接正式应用;数据复核通过 |
| `015_booking_excel_review_drafts.sql` | `a80689c4ecc3b6b3502e8f094a8c175af38df8c09f9d2c64412a9aec55bae12a` | 2026-07-31 已由受控连接正式应用;真实 PostgreSQL 草稿编辑/激活外层回滚通过 |
| `016_monthly_report_oss_artifacts.sql` | `70ca052f71da9f88e83fe8bccf0a6682cdd3138c3525981c80eebc868e401626` | 代码已提交;尚未在远程 `booking_test` 应用 |
## 014/015 最新核查状态
- 正式应用前014/015 在一个事务内完成应用与回滚探针;回滚后两个草稿关系不存在,历史 Booking 数据未变。
- 正式应用后,`current_source_batch` 选择历史 accepted batch 1当前房间明细 867 行、348 个 Group Code、
数量合计 867两张 extraction draft 表均为 0 行。
- 新表字段、外键、CHECK/UNIQUE 约束与当前 014/015 源文件结构一致,所有相关约束均已验证。
- 真实 PostgreSQL 事务探针创建 2 个提取项、保留 1 个待确认项,编辑为 `EXTRA BED` 后激活为 1 条来源行、
数量 3外层回滚后 active batch 仍为 1合成草稿、来源和工件残留均为 0。
- 当前 8766 进程已加载新 composition认证健康检查的数据库、处理、月报、下载、公司报表和公司来源上传
readiness 全为 true草稿接口返回未打开。尚未用真实用户工作簿替换当前业务来源。
- 015 是基础单操作员 latest-state 草稿模型,没有 reviewer/reason/revision/history若要求可审计确认仍需
新增迁移。
`008``booking_test` 内仅重建 `ingestion``booking``finance` 三个 schema。它取代 001007 所形成的旧 schema 状态001007 文件只保留为历史记录,不得再对当前库补跑。
执行门禁:
- `current_database()` 必须为 `booking_test`
- 执行前核对旧库表计数和备份 manifest
- 整个重建在一个事务内完成;
- 不触碰 `public` 或其他数据库。
当前对象23 张基础表(`ingestion=8``booking=8``finance=4``reporting=3`)和 8 个视图012 另增加月报发布/子表不可变保护触发器。
## 009/010 增量迁移
`009` 新增 `ingestion.source_read_grants`,用于受控运行时的短时、单次源 XML 取件授权。表内不保存 OSS 密钥、URL 或 XML 内容。
`010` 按当前数据量收敛为单一 MCP 工具 `arr_submit_processing_result` 的入库账本:
- 新增 `ingestion.result_submission_grants``ingestion.result_submissions`
- 不创建 batch 表,也不保存明文 grant、数据库密码或 OSS 密钥;
- 单次 structured payload 上限为 3 MiB必须显式包含与 `record_count` 一致的 `records` 数组;
- grant 最长 30 分钟,只能在有效期内消费,且绑定唯一 processing attempt
- `payload_sha256` 索引故意不唯一,允许同一份 XML 在不同 run/attempt 下反复联调;
- 同一 attempt 仍由唯一 grant/submission 约束幂等,最终 Finance 事实继续使用现有版本身份去重;
- 终态必须清除可能含住客字段的临时 `payload_json`,只保留哈希、计数、状态和最小回执;
- `processing_runs``daily_versions` 新增 `result_delivery_mode`,旧行全部默认为 `artifact_callback`,新链路显式使用 `direct_mcp`
`010` 正式提交前已完成未提交事务探针、已提交 up/down 演练和独立恢复验证。正式提交后两张新表均为空旧表计数不变batch 表不存在,所有约束均已验证。
`010_mcp_result_ingestion.down.sql` SHA-256`ec937b7c046eaaaccc1e95466ef3e9367cab622cddceaecbab0e9570bbbc5c79`。回滚脚本只允许在新表无任何记录且无 `direct_mcp` 业务数据时使用。
## 011 工件对象身份迁移
`011` 修正了同一份 XML 跨任务重复上传时的工件身份冲突:
- 删除 `ingestion.artifacts (artifact_kind, sha256)` 的唯一约束,保留同名普通查询索引;
- 同内容哈希可以属于不同 run 的不同私有 OSS 对象;
- `artifacts_storage_identity_unique` 继续保证同一存储地址只有一条工件记录;
- 应用层以 storage provider、bucket alias、object key 和版本身份查找工件,仍会核对类型、文件名、哈希、字节数和 MIME。
迁移正式提交前已在单一事务内完成 up/down 回滚演练。正式提交后 `artifacts` 仍为 12 行,未改动业务数据。`011_artifact_object_identity.down.sql` SHA-256`c6accbb8c91887fabc5290ad758916c66211479bdcb2a3d9503579d648ba2fa7`;当已出现同类型、同哈希的多 OSS 对象时,回滚会拒绝恢复错误的唯一约束。
## 012 月报发布元数据迁移
`012` 在不复制月报业务/住客行的前提下增加:
- `reporting.monthly_runs`:月份内顺序版本、状态、最大 `ARRIVAL` 水位、规则/快照身份与两个工件引用;
- `reporting.monthly_run_daily_versions`:生成时使用的 Finance 日版本 lineage
- `reporting.monthly_channel_manifest`:工作表顺序和隐私最小化行数清单;
- `ingestion.artifacts.storage_provider` 的受控 `local` 值,用于当前单机共享输出卷。
激活约束要求 workbook/result 工件、lineage 和连续渠道清单同时存在;同月只能有一个 active 版本,已发布子记录不可变。`as_of_date` 的数据库语义明确为月报实际纳入数据中的最大 `ARRIVAL`,不得来自 XML 文件名或当前时间。
正式提交前已完成完整 up/down 事务回滚探针和合成 active 发布探针。由于环境没有 `pg_dump`,使用不含业务行和凭据的元数据 checkpoint`runtime/backups/booking_test_pre_012_20260730T151922+0800/manifest.json`SHA-256 `230206eb074fd5877132744eb592b3dc6cd6638d12a3dd4d71a8101a9bd2998e`
`012_monthly_report_publication.down.sql` SHA-256`e696888ffa9525fa345210123894c1b13acbd930fefbdc7effdd6b349bcb63d6`。一旦已有 reporting/local 工件数据,回滚脚本会拒绝破坏性删除。
## 013 日报上传文件名来源字段
`013` 在不改变源工件身份和处理器输入契约的前提下增加:
- `ingestion.processing_runs.uploaded_filename`:保存浏览器提交并通过校验的 XML basename
- 历史任务保持 `NULL`,不使用内部 `source.xml` 进行错误回填;
- `ingestion.artifacts.original_filename` 继续保持规范内部名 `source.xml`
- 日报历史与任务日志只读取任务上的上传文件名,缺失时由页面显示 `—`
正式提交后 `processing_runs=25``uploaded_filename` 非空行数为 0新约束已验证。一个完整事务内的 Unicode 文件名探针证明日报列表与任务日志读取上传名、源工件仍为 `source.xml`,随后已整体回滚且未留下测试数据。
`013_daily_upload_filename.down.sql` SHA-256`663d287e36bb99533d28918d8ead7a2b03e8bbf7e7d682a527400d11f0ee3fbf`。一旦存在非空上传文件名,回滚脚本会拒绝丢弃该来源信息。
## 远程完整迁移
2026-07-28 已把完整 MVP v1 结构、数据、identity sequence 状态和处理审计从旧 LAN 测试库迁移到当前远程测试库。
- 执行记录:`database/REMOTE_MIGRATION_20260728.md`
- 迁移前备份:`<PRIVATE_BACKUP_ROOT>/booking_test_pre_remote_migration_20260728T180747+0800`
- manifest SHA-256`db8ca84fed52123d10151b475aca31659be237c6e7d513484e4f25b1d9a89c4d`
- 双端结构 signature`0d64002b919d439dbbbbf78d1f5c5fab86d8f815f80dc6225f17a91ab5455e38`
- 双端 14 表内容 hash bundle`42faf898d67b3015e85baf00bbd66a1fa4448d80daa7f5d9d0207a4004fad35c`
- 迁移方式:完整事务回滚演练通过后正式提交;提交后再由独立只读连接复验
- 源库:未修改、未删除,观察期内保留
## 重建前备份
- 目录:`<PRIVATE_BACKUP_ROOT>/booking_test_pre_mvp_v1_20260728T161638+0800`
- manifest SHA-256`af0e7bec364ccbfe342bbb20ea5e3d44a31ba8fe22134b91a3f79d4bac3c1a7c`
- 内容:旧 20 张基础表的 gzip JSON 数据,以及列、约束、索引、视图和 sequence 元数据
- 完整性:逐文件 SHA-256 与 gzip 校验均通过
该备份可用于人工恢复旧测试基线;未执行恢复。
## 已导入预订样本
来源:`outputs/res_comment_20260727/RES_COMMENT_TYPE_OF_ROOM.md`
- 文件 SHA-256`ec2302170c5657d3e465691997e17f7694eb5a7f76feba7e43261632209b8c23`
- source batch1
- source rows867
- accepted parse versions867
- current row parses867
- room items867
- 不同 Group Code348
- 重复 Group Code122
- 工作表6
867 条来源行逐行保存,没有按 Group Code 合并;每条都保留工作表、行号、原文、数量和行哈希。重复导入返回 `already_applied_and_verified`,没有新增重复记录。
当前 MD 是用于跑通流程的预期结果样本,每行已经给出一个可查询房型,因此当前每行对应一个 room item。真实预订 Excel 现在由确定性 parser 2.0 从 `Tour Code`/`โรงแรม` 提取一个或多个 room items未知项先进入人工复核草稿不经过 Agent。
## 已导入 Finance 合成日报
受控 fixture`outputs/database_fixtures/2026-07-27`
- DeliveryEnvelope SHA-256`dc227c099b15c559874a3612dbda398494962b4200a8af15c973f7e84850a2`
- 业务日期:`2026-07-27`
- source records3
- outcomes`retained=1``duplicate=1``excluded_rate_code=1`
- current daily version1
- 正式 retained 事实1
- 月报投影1 行
- 渠道明细投影1 行
- 公司报表源投影1 行
- Group Code`LT260720GAA`
- Booking Room 查询结果:`DBL × 1`
- `total_price`5400`1800 × 1 × 3 = 5400`
该 fixture 只含合成字段不含真实住客数据。它通过真实日报处理器、ARR 独立复验和正式 PostgreSQL repository 落库。幂等复跑计数不变。
## 最终验收
只读数据库验收结果:
- `booking`867/867/867/867 source/parse/current/item
- `finance`1 daily version、1 current pointer、3 all-outcome records
- 业务视图中非 retained 泄漏0
- 总价公式违规0
-`file_objects``processing_jobs``report_versions` 等关系0
- 未验证约束0
- `public` 用户对象0。
应用只读验收结果(最初合成基线):
- 渠道 BI1 个渠道、1 条预订;
- 渠道明细1 行;
- 月报生成源1 行;
- QBD 公司报表源1 行Booking Room 为 `【DBL】1`
- Web 日报列表1 条;
- Web 月度数据源投影1 条。
该段为 008011 初始验收快照2026-07-30 的 012/月报验收见下节。
## 2026-07-30 月报发布验收
- 首次验收时为 2 个 daily version、120 条 active daily facts两个事件均由独立 worker 在首次尝试后标记为 `published`
- 首次两个事件幂等汇聚到 report ID 1/version 1`as_of_date=2026-07-27`、120 行、5 个渠道;
- 首次 workbook 重新打开后为 120 个授权 `TOTAL PRICE` 公式、0 个缺失/错位/越权公式20,741 字节及 SHA-256 均与登记值一致;
- 同日后续两个真实上传安全生成 V02/V03。最新只读状态为 4 个已发布事件、V03 active、V02/V01 superseded
- V03 为 308 行、6 个渠道,`as_of_date=max(ARRIVAL)=2026-07-27`;其 308 个公式全部正确40,635 字节及 SHA-256 `494fb78283f68cb7bffce2501b3531613c494d148a56a7ccc8d2aabe46b1e29c` 与登记值一致;
- Web 列表显示 V03/V02/V01 与下载链接;页面无月报刷新按钮,可见时约每 4 秒自动读取新版本。
- 最终完整发现运行 291 项测试全部通过7 项仅因环境/未打包私有 fixture 而跳过。
## 2026-07-31 Booking 当前源与复核结构
受控连接先完成 014/015 同事务应用/回滚探针,再正式应用权威 SQL。`booking.current_source_batch` 指向
accepted source batch 1`booking.extraction_drafts``booking.extraction_draft_items` 可读且为空;正式应用前后
867 条房间明细、348 个 Group Code 和数量合计 867 均未变化。
- `014_booking_current_source_batch.sql` SHA-256`23bf0fcc880225ca276d4d7d871057be4f7950e761ddbeed1df2a3c6e25463b5`
- `014_booking_current_source_batch.down.sql` SHA-256`fa64a251e1a018e536c8b361bb81b18daffdbcbef8abc839fe0c95ccfa7d045b`
- `015_booking_excel_review_drafts.sql` SHA-256`a80689c4ecc3b6b3502e8f094a8c175af38df8c09f9d2c64412a9aec55bae12a`
- `015_booking_excel_review_drafts.down.sql` SHA-256`7643f0bda8b8c15cf40afa76d89d396bdf2a7654ba8eb73df872c7a838fc809d`
真实 PostgreSQL 事务探针完成 draft create/edit/activate 全路径后由外层回滚,恢复 batch 1 且无合成残留。
Port 8766 于 11:30:46 +08 加载当前复核程序;认证 readiness/source-draft 检查通过PATCH/DELETE 已到达
应用层。首个真实用户工作簿上传/人工复核/激活仍未执行,因此当前业务来源未被替换。
## 当前模型的重要含义
- PostgreSQL 保存已验收的工件身份、预订事实、全部日报 outcome、current 指针和渠道指标。
- 月报行、渠道明细行、公司 10 日报表行由普通程序查询当前事实生成;`reporting` 只保存版本、lineage、清单和工件身份。
- 月报 XLSX/JSON 当前保存在受控共享输出目录并登记为 `local` 工件,但不是重复的数据库业务事实。
- 后续变更必须新增迁移,不得编辑已执行的 `008``015`