ADORSYS-GIS / ADORSYS-GIS/converse-frontends
[Ticket]: wiremock fixtures answer JSON to a CBOR-only console — the mock server loads nothing
- 主要语言
- TypeScript
- 星标
- 0
- 派生
- 0
- 平均合并
- 1 小时 49 分钟
- 30 天内合并 PR
- 253
描述
### Type
Bug
### Summary
We need to make `wiremock/mappings/*.json` answer the codec the console actually speaks, because
today `docker compose up wiremock` produces a console that loads **nothing** — every RPC call is
made and every response is discarded.
Expected result:
> With the wiremock service up and the console pointed at it, `/accounts`, `/admin/refills-queue`
> and every other RPC-backed screen render the stubbed fixtures instead of an error/empty state,
> and no `codec: failed to decode CBOR body` appears in the browser console.
### Intent
The wiremock service exists so a developer can bring the console up with no backend. It has been
dead since the RPC transport moved to CBOR: the fixtures were written for the JSON transport that
no longer exists on either side of the wire. Nobody notices, because the failure is silent and
looks exactly like "the backend has no data" — which is the failure mode a mock server is
supposed to eliminate. Either the fixtures are made to work or the service is deleted; a stub
that cannot answer is worse than no stub, because it costs an afternoon to discover.
### Source of truth (links)
- https://github.com/ADORSYS-GIS/converse-frontends/pull/504 — the "filters outside cards" PR
whose CI fallout (see https://github.com/ADORSYS-GIS/converse-frontends/pull/506) prompted the
sweep of `apps/lci` and the local-dev tooling in which this was found.
- lightbridge-authz **ADR-0013** — CBOR is the ONLY transport codec for the RPC/CRUD surface;
`authz-api`/`authz-budget` answer a JSON `Accept` with `406 Not Acceptable` and a JSON body with
`415`. Restated in this repo at `packages/authz-rpc/src/codec.ts`'s module doc.
### Current Behavior
Both mapping files answer with WireMock's `jsonBody`, i.e. `Content-Type: application/json`:
- `wiremock/mappings/mapping.json` — `POST /rpc/model.Account.list`, `…Project.list`, etc.
- `wiremock/mappings/console-budget.json` — `POST /budget/rpc/procedure.listPendingAugmentationRequests`, etc.
The console's RPC client is CBOR-only. `packages/authz-rpc/src/codec.ts` selects
`createCborCodec()` from `@cratestack/cbor` for every consumer and documents that the JSON codec
"is not selected by either app's runtime"; `packages/authz-rpc/src/runtime.test.ts` pins the
request's `content-type` to `application/cbor`, and the generated runtime
(`packages/authz-rpc/generated/src/runtime.ts`, `matchesContentType`) compares the response's media
type against the codec's own `contentType` **exactly**.
So every stubbed response is rejected before it is read, and the screen falls back to its
empty/error state with `codec: failed to decode CBOR body` in the console. Nothing in
`compose.yml` or the fixtures says so — the service starts, answers 200, and is useless.
### Expected Behavior
`docker compose up wiremock` yields a console that renders the fixtures. Concretely, one of:
1. **Serve CBOR.** Replace `jsonBody` with `base64Body` (or `bodyFileName` + a binary file) holding
the CBOR encoding of the same payloads, plus an explicit
`"headers": { "Content-Type": "application/cbor" }`. A small committed script that encodes the
JSON fixtures to CBOR with `@cratestack/cbor` keeps the fixtures readable and the bodies
correct — hand-maintained base64 would rot on the first schema change.
2. **Or delete the service and its fixtures**, and say in `docs/knowledge/development-setup.md`
that local console development needs a real `lightbridge-authz`. A hard cutover beats a stub
that cannot answer.
Whichever is chosen, `compose.yml`'s `wiremock` service gets a comment stating which codec the
fixtures are in, so the next transport change breaks loudly.
### Acceptance Criteria
- [ ] Given `docker compose up wiremock` and the console pointed at it, when `/accounts` is opened,
then the stubbed accounts render — no empty state, and no `codec: failed to decode CBOR body`
in the browser console.
- [ ] Given the same, when `/admin/refills-queue` is opened, then the stubbed pending augmentation
requests render.
- [ ] Every mapping answers `Content-Type: application/cbor`, or the service is removed entirely
(no half-migrated state where some mappings answer JSON).
- [ ] If option 1: the JSON→CBOR encoding step is a committed, runnable script, not hand-pasted
base64.
- [ ] `compose.yml`'s `wiremock` service states which codec its fixtures are in.
- [ ] Error cases are handled safely — a fixture that fails to encode fails the script loudly
rather than writing a truncated body.
- [ ] Existing behavior is not broken: no change to `packages/authz-rpc`, and the console's real
backend path is untouched.
- [ ] Verification evidence is provided (screenshot of a populated screen served by wiremock, or
the removal diff plus the docs change).
### Out of Scope
- Any change to the transport itself. CBOR-only is ADR-0013 and is not being revisited here.
- Adding a JSON fallback codec to `packages/authz-rpc` "just for local dev" — that is a second,
untested wire path in production code to serve a fixture directory.
- Fixture COVERAGE (which procedures are stubbed). This ticket is about the ones that exist
answering at all; whether the set is complete is a separate question.
### Technical Context
- `compose.yml` — the `wiremock` service (`wiremock/wiremock:3.13.2`, `./wiremock` mounted at
`/home/wiremock`, port `18888:8080`).
- `wiremock/mappings/mapping.json`, `wiremock/mappings/console-budget.json` — the fixtures.
- `packages/authz-rpc/src/codec.ts` — `JsonCodec` exists but is explicitly not selected at runtime;
`getCborCodec()` / `ensureCborCodecReady()` are what both apps use.
- `packages/authz-rpc/generated/src/runtime.ts` — `matchesContentType()` compares the media type
exactly (deliberately, so `application/cbor` never matches `application/cbor-seq`), which is why
a JSON response is not merely mis-parsed but rejected.
- WireMock's `base64Body` / `bodyFileName` (`__files/`) are the two ways to serve a binary body.
### Risks
- A CBOR fixture is unreadable in a diff, so a stale fixture is harder to spot than a stale JSON
one. Mitigation: keep the JSON as the source and generate the CBOR, so the readable file stays
the one under review.
- The encoder is `@cratestack/cbor`, whose native/WASM backend is environment-selected; a script
run under Node uses `@cratestack/cbor-node`, which needs glibc-compatible Node (the same
constraint the console's own image documents).
### Test Plan
- Manual: `docker compose up wiremock`, point the console at `http://localhost:18888`, open
`/accounts` and `/admin/refills-queue`, check the network tab for `200 application/cbor` and the
browser console for the absence of the decode error.
- If a generation script lands: a unit test that round-trips one fixture through
`getCborCodec().decode()` and asserts it equals the JSON source — otherwise nothing catches a
fixture that encodes to garbage.
- Regression: `pnpm -r --no-bail test` stays green (no production code is touched by either option).
### Verification evidence
Evidence that the fixtures are dead today, gathered while hotfixing #506:
- `wiremock/mappings/*.json` use `"jsonBody"` for every stub — WireMock serves those as
`application/json`. No mapping sets a `Content-Type` header of its own.
- `packages/authz-rpc/src/codec.ts` (module doc): "`JsonCodec` … is not selected by either app's
runtime"; CBOR is "THE codec for both `apps/console` and `apps/self-service`".
- `packages/authz-rpc/generated/src/runtime.ts` `matchesContentType()` — exact media-type match
against the codec's `contentType`, so an `application/json` response is rejected outright.
- Symptom to look for: `codec: failed to decode CBOR body`.
Not yet run: a live `docker compose up wiremock` against the console — the mismatch is provable
from the fixtures and the client's own pinned tests, and reproducing it is the first step of the
ticket rather than a prerequisite for filing it. Stated plainly so nobody reads this as more
verified than it is.
### Human accountable owner
@stephane-segning
### AI Usage Declaration
Drafting the ticket, Understanding code
### Human verification completed
- [x] I understood the intent
- [x] I checked the source of truth
- [x] I reviewed all AI-generated text/code
- [ ] I verified the implementation manually
- [x] I verified the tests
- [x] I checked for hallucinated assumptions
- [x] I documented remaining risks
- [x] I am the accountable owner and accept responsibility for this ticket.
贡献指南
评估
这个 Issue 还没有评估数据。