Files
wyndham-ARR/arr-opera-daily-ingest/references/structured-output.md
2026-07-29 16:38:05 +08:00

3.2 KiB

Structured Result Contract

Purpose

structured-result.json version 3.0 is the daily fact payload consumed by the trusted ARR adapter. It contains every XML source reservation, including filtered, duplicate, invalid, and unmatched rows.

result.json is the Agent/front-end run result. Do not add database records to it. Do not reconstruct database rows from the XLSX.

Transport boundary

  • fetch_oss_file and its OSS credentials belong to the Agent runtime, not this Skill.
  • The Agent passes the fetched local XML path into the processor.
  • ARR already knows the job/source-file identity from the upload context and binds that identity to this payload after comparing the XML hash.
  • Structured artifact objects contain no local absolute path, OSS key, signed URL, AccessKey, or database credential.
  • Agent-local paths are ephemeral orchestration data and must not be persisted as business facts.

Batch fields

The payload includes:

  • business_date
  • processor_version
  • rule_set_sha256
  • result_schema_version
  • source_rows
  • removed_by_rate_code
  • removed_as_duplicates
  • output_rows
  • five-outcome reconciliation
  • channel counts
  • path-free XML/daily/result/exception artifact metadata
  • every XML source record in original order
  • structured errors

rule_set_sha256 hashes only resources that determine daily processing: Skill instructions, processor, independent validator, daily contracts/Schemas, price table, and daily template.

The structured file does not hash itself, avoiding self-hash recursion.

Outcomes and lineage

Allowed outcomes:

  • retained
  • excluded_rate_code
  • duplicate
  • validation_failed
  • price_unmatched

Duplicates point to an earlier source_sequence. decision_codes explain deterministic choices.

For direct XML:

  • source_sequence is continuous and one-based;
  • source_location = reservation[N];
  • source_worksheet = null;
  • source_row_no = null.

Finance/booking semantics

  • effective_rate_amount comes from XML/daily EFFECTIVE_RATE_AMOUNT.
  • real_price comes from the approved price rule.
  • total_price = real_price * no_of_rooms * nights.
  • nights may be zero; it may not be negative for retained rows.
  • kb_amount = no_of_rooms * 100 only when channel_key = DY-AI-Easy-KB.
  • room_category_label remains the Opera actual room category.
  • group_code_key comes only from normalized RES_COMMENT.
  • Non-empty Group Codes begin with booking_source_match_status = not_checked; empty values use missing_group_code.

ARR performs the later exact booking lookup:

structured group_code_key
= booking.booking_source_rows.group_code_key

It may then expose booking.booking_source_rows.hotel_raw as the original booking type_of_room text. It must not overwrite room_category_label.

Activation boundary

activation_eligible: true means only that the deterministic file pipeline passed. It does not mean database commit succeeded.

ARR must revalidate the Schema and hashes, write file/version/record/channel/lookup rows in one transaction, and switch the current daily version last. A rerun of the same business date creates a new immutable version; only the successful committed version becomes current.