From 42c70e77ed4533a1035438ed42a7cc3bfe72a7b8 Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 15 Jul 2026 17:23:15 -0400 Subject: [PATCH] docs(guide): customer-journey host_result normalisation + decline reason (#48) Document that the flow normalises host_result (SUCCESS->approved, FAIL/TIMEOUT ->declined) and surfaces a decline Reason, matching hiveops-transactions #49. Note the note-breakdown still needs raw_lines and a structured reason field remain follow-ups on #48. Co-Authored-By: Claude Opus 4.8 --- .../resources/content/transactions/customer-journey/claude.md | 1 + .../resources/content/transactions/customer-journey/internal.md | 1 + 2 files changed, 2 insertions(+) diff --git a/backend/src/main/resources/content/transactions/customer-journey/claude.md b/backend/src/main/resources/content/transactions/customer-journey/claude.md index eebcc00..8f6c272 100644 --- a/backend/src/main/resources/content/transactions/customer-journey/claude.md +++ b/backend/src/main/resources/content/transactions/customer-journey/claude.md @@ -49,6 +49,7 @@ Request body for analyze: `{transactionId, rawLines, atmId, atmVendor}`. Save PA ## Gotchas - Timeline is built **in the browser** from `rawLines`; there is no backend "journey" endpoint. Empty rawLines → "No event timeline found". +- **`host_result` is normalised** (`hostOutcome()`, #48): approved = `APPROVED`/`SUCCESS`/`SUCCESSFUL`/`COMPLETED`/`OK`; declined = `DECLINED`/`FAIL`/`FAILED`/`TIMEOUT`/`ERROR`/`REVERSED`/`REJECTED`. The journal (sim + real) writes `SUCCESS`/`FAIL`/`TIMEOUT` — the flow now renders *Host Approved / Cash Dispensed* (approved) and *Host Declined* (declined) for those. **Host Declined** shows a **Reason** taken from a `raw_lines` `Reason: …` line, else a friendly label (`Host timeout` / `Transaction failed` / `Declined by host`). A **structured failure-reason field is still a follow-up** (#48) — today the reason is only as good as `raw_lines`. - Adoons button hidden unless `GET /adoons/status` → `{available:true}` (i.e. ai `/actuator/health` reachable from incident). - `analyze-journey` read timeout = 270s in incident; failure → HTTP 503 → UI "Adoons is currently unavailable." - Verdict save is **fire-and-forget** (`.catch(()=>{})`); persistence failures are invisible in the UI — check journal logs for `Error saving Adoons analysis for transaction {id}`. diff --git a/backend/src/main/resources/content/transactions/customer-journey/internal.md b/backend/src/main/resources/content/transactions/customer-journey/internal.md index 37b498a..e1bb8b7 100644 --- a/backend/src/main/resources/content/transactions/customer-journey/internal.md +++ b/backend/src/main/resources/content/transactions/customer-journey/internal.md @@ -41,6 +41,7 @@ Ops/support view of the Customer Journey drawer (the per-transaction replay in t - **502/CORS on the whole app** — nginx is the CORS authority; the proxy disables app-level CORS. Check the `transactions.bcos.cloud` server block and the shared cors include, not the app. - **All journeys 401** — proxy forwards only `Authorization` + `Content-Type` headers; a stale/expired JWT or a dropped Authorization header breaks every downstream call. - **Cassette config right for one ATM, wrong for another** — it derives from that ATM's *latest* REPLENISHMENT only; a stale or mis-parsed replenishment yields wrong denominations. +- **Flow missing Host Approved / Cash Dispensed / Host Declined steps** — the flow normalises `host_result` (`SUCCESS`→approved, `FAIL`/`TIMEOUT`→declined) since #48; before that it only recognised `APPROVED`/`DECLINED`, so sim/real transactions (which use `SUCCESS`/`FAIL`/`TIMEOUT`) rendered no host step. The **note breakdown** still needs `raw_lines` dispense detail — sim transactions with null `raw_lines` show *Cash Dispensed* without denominations (follow-up on #48). A **decline reason** shows only if `raw_lines` has a `Reason:` line or from a friendly host_result label. ## Escalate to engineering (see [architect] tab) when