---
module: transactions.browser
title: Transactions Browser
tab: Internal
order: 20
audience: internal
---

Ops / support / admin view of the fleet-wide transaction browser (`transactions.bcos.cloud`, port 5178). This screen is a thin Svelte SPA; **all transaction data is owned by `hiveops-journal`** (DB `hiveiq_journal`). If a customer says "no transactions" or "wrong data," the problem is almost always in journal ingest/parsing or institution scoping — not in this frontend.

## Who can see what (roles)

Reads are gated by `@PreAuthorize("isAuthenticated()")` on the journal controller — **any valid JWT can list transactions**, but results are scoped by institution:

- **BCOS_ADMIN / ADMIN / USER** → `InstitutionContext.resolveScope()` returns `null` → sees **all institutions**.
- **CUSTOMER** → scoped to their **single** institution key.
- **MSP_ADMIN** → scoped to the list of institution keys granted in the JWT credentials.

So an MSP admin who "can't see an ATM's transactions" is usually missing that institution key in their token, or the ATM's rows carry a different `institution` value.

## Admin-only actions (from the Settings gear)

Journal rule/parse management lives behind `hasAnyRole('MSP_ADMIN','BCOS_ADMIN')` (journal `AdminController`, base `/api/journal/admin`):

- **Journal Parsing / Processing Rules** — `GET/PUT /rules`, `POST /reload-rules`, `GET /rules/structured`, `PUT /rules/structured`, `GET /types`.
- **TCR Parsing / Rules** — `GET/PUT /tcr-rules`, `GET/PUT /tcr-rules/raw`, `POST /tcr-rules/reload`.
- **Reparse** — `POST /reparse-all?atmId=&journalType=` re-queues files through the parser (use after a rule change).
- **File list** — `GET /api/journal/files?atmId=&page=&size=&journalType=` shows `parseStatus` / `parseError` per uploaded file.

## First things to check when it misbehaves

1. **Empty list for one user only** → institution scope. Check the JWT role + granted institution keys vs the `institution` column on `journal_transactions`. MSP_ADMIN/CUSTOMER are scoped; BCOS_ADMIN is not.
2. **Empty list for everyone on an ATM** → journal parsing. Look at `GET /api/journal/files?atmId=…` for `parseStatus=FAILED` / `parseError`, or files stuck `PENDING`. After any journal redeploy run the reconcile: `POST /api/journal/admin/reconcile` (re-queues stranded files).
3. **"Journal service unavailable" banner** → the frontend got a 502/503. The journal **upload-role** container is down (only `journal.role=upload` serves these controllers — worker containers do not). Check `hiveiq-journal`.
4. **Old data won't load / "Archived Data" dialog** → queries older than **90 days** hit the cold `journal_transactions_archive` table and prompt for confirmation. This is expected and can be slow.
5. **Wrong transaction type / amounts** → parsing rules, not the UI. Amounts are stored in **cents** (`amountCents`) and divided by 100 for display; `SEQ #` of `0` is intentionally stored null and rendered `-`.
6. **Adoons "Analyze" fails / button hidden** → the frontend probes `/adoons/status`; a 503 or unavailable AI backend hides/disables it. This is non-fatal to the browser itself.

## Common failure modes + fixes

| Symptom | Likely cause | Fix |
|---|---|---|
| One institution/ATM shows nothing | JWT institution scope mismatch | Verify granted keys vs `journal_transactions.institution` |
| Everyone sees nothing for an ATM | File not parsed / stranded PENDING | Check `/api/journal/files`; `POST /api/journal/admin/reconcile` |
| 502/503 banner | Journal upload container down | Restart `hiveiq-journal` (upload role) |
| Amount filter returns 500 | Non-integer dollars in Min/Max | Enter whole-dollar amounts (see Architect notes) |
| TCR rows missing under ATM filter | `journalType` only applied when no single ATM selected | Use Device Type = TCR with "All ATMs" |
| Cheque images blank on a deposit | No `cheque_image` rows for that seq | Confirm agent uploaded cheque metadata for that ATM |

## Good to know

- **Auto-refresh** re-pulls every 60s (toggle persisted in `localStorage`); the manual refresh button forces a reload.
- **Device Type** ATM vs TCR maps to `journalType=JRN_ATM` / `NH_TCR`, but only when no specific ATM is chosen.
- **Foreign only** = surcharge/fee > $0.
- The browser never writes transaction data — the only write it makes is caching an Adoons analysis back onto the transaction (`PATCH …/adoons-analysis`).
