# ARR 数据库最终架构冻结 更新时间:2026-07-28 状态:已按 `database/008_arr_mvp_v1_rebuild.sql` 实施,不再是候选方案。 ## 最终数据链 ```text 用户上传 XML → ARR 后端存入私有 OSS → SuperAgent 获取 XML → Agent 调用确定性日报 Skill → 生成 structured-result.json 和正式工件 → ARR 后端重新校验 Schema、哈希、公式和处理语义 → 单事务写入 PostgreSQL → 普通程序查询数据库 ├─ 生成月报 XLSX ├─ 查询渠道明细/渠道 BI └─ 生成每 10 日公司用房表 预订 Excel/当前 MD fixture → 私有 OSS/受控 fixture → 行级 Agent 解析 → ARR 验收 → PostgreSQL booking 来源行 + room items → 按 RES_COMMENT/Group Code 为报表补充 Booking Room ``` Agent、Skill 和 SuperAgent 永远不持有数据库凭据,也不直接写 PostgreSQL。ARR 后端是唯一写入方。 ## 已实施的 schema 归属 | schema | 职责 | |---|---| | `ingestion` | 工件身份、处理运行/尝试/交付、幂等和 outbox | | `booking` | 预订来源行、不可变解析版本、当前解析和房型明细 | | `finance` | 日报不可变版本、全部 source outcome、渠道指标和 current 指针 | ## 关键冻结决策 1. 只使用独立 `booking_test`,不把 ARR 表放进共享维护库 `postgres`。 2. 预订来源行按原 worksheet/row 逐行保存;同一 Group Code 可以重复。 3. 预订原文和完整 Agent 行级 JSON 保留,同时把 room items 结构化供查询。 4. 日报 structured-result 的全部 outcome 都落库;业务视图只读 current + retained。 5. 同日重跑形成不可变新版本,全部验收通过后才切 current;失败不影响旧 current。 6. `TOTAL PRICE = REAL PRICE × NO_OF_ROOMS × NIGHTS` 由 ARR 重算并由数据库约束再次保护。 7. 精确关联键为 `upper(trim(XML.RES_COMMENT)) = booking.group_code_key`;不用 `BLOCK_CODE`,不用模糊匹配。 8. Booking 数据只补充 Booking Room;Finance 提供日期、晚数、实际房数和价格。 9. 月报、渠道明细、BI 和公司 10 日报表是程序投影,不复制一套 report rows/version facts。 10. 文件字节保存在私有 OSS;PostgreSQL 只保存不可变对象身份、哈希、大小和血缘。 ## 为什么保留 `artifacts`、批次和解析版本 - `ingestion.artifacts` 让 ARR 能验证 Agent 所称的 XML、日报和 JSON 是否确实是同一批交付,并实现幂等和追溯。 - `booking.source_batches/source_rows` 记录“哪一份附件、哪个 worksheet、哪一行”产生了预订信息,不能只留最终 Group Code 汇总。 - `booking.parse_versions.result_json` 保存 Agent 已验收的结构化输出;`room_items` 是供普通 SQL 查询的可计算拆分。 - 这些字段是数据血缘,不是任务卡状态。 ## 报表处理口径 | 输出 | 数据来源 | 是否重复落库 | |---|---|---| | 日报 | Agent structured-result,经 ARR 验收 | 是,作为 Finance 权威日事实 | | 月报 | current + retained 日事实,加 Booking Room | 否,程序生成 | | 渠道明细/BI | current + retained 日事实 | 否,视图/程序查询 | | 每 10 日公司用房表 | Finance 日期/价格 + booking 房型 | 否,程序生成 | 渠道明细的 `Total Booking Price` 直接等于对应日报行的 `total_price`,不是同 Group Code 合计,也不使用预订附件价格重算。 ## 本轮明确不做 - 多酒店/多租户; - 用户、角色和最小权限 DDL; - RSVN 任务卡; - 邮件发件人、主题、Message-ID 等元数据; - 报表数据库版本表; - 日报追溯前端。 ## 生产前门禁 当前使用远程测试地址和数据库 owner 用户,只用于测试;它不是面向应用的最小权限角色。生产前仍需: - 创建 ARR writer、业务 reader 等最小权限角色; - 接入正式私有 OSS provider/bucket 与 Secret 管理; - 完成 SuperAgent 文件句柄、回调验签和共享幂等协议; - 清理合成测试数据并导入真实但合规的数据; - 做备份恢复、并发、失败注入、权限和隐私回归。 生产是否继续使用同一物理地址不是数据库模型能自动决定的事项;上线时必须显式核对环境、库名、账号和备份,不能只“清空测试数据”后默认当生产。