S-26/#162 · Werkbak refreshes itself when a registration is ready for beoordeling #164

Merged
not merged 6 commits from feat/162-werkbak-live-refresh into main 2026-09-04 09:34:15 +00:00
6 Commits
Author SHA1 Message Date
notandClaude Opus 5 3628efc17a test(e2e): open the werkbak before the registration is ready for beoordeling (refs #162)
CI / build (pull_request) Successful in 1m4s
CI / lint (pull_request) Successful in 1m23s
CI / unit (pull_request) Successful in 1m24s
CI / frontend (pull_request) Successful in 3m8s
CI / mutation (pull_request) Successful in 6m18s
CI / verify-stack (pull_request) Successful in 10m15s
The happy path visited the behandel portal only after the documents were
supplied, so the row was already in the werkbak at page load — dropping the
reload proved nothing. Now the behandelaar logs in first, asserts the row is
NOT there yet, and only then does the citizen supply the documents that route
it to Beoordelen. The row can therefore only reach that already-open,
never-reloaded page by the werkbak refreshing itself.

Verified both ways against a live stack: with the interval stubbed out the
spec fails at "Goedkeuren <ref> … element(s) not found" after 30s; with it,
the behandel nginx logs the poll that delivers the row.

The werkbak page is foregrounded before the assertion — Chromium throttles
timers in a hidden tab.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 11:12:30 +02:00
notandClaude Opus 5 fc843a419a docs(portal-behandel): ADR-0032 + demo note for the self-refreshing werkbak (refs #162)
Records why the werkbak polls rather than being pushed to (proposal #163):
nothing notifies the BFF either, so SSE/WebSockets would poll the domain
inside the BFF for the same freshness plus connection state, a dependency and
a stateful BFF. Names the ceiling (fixed 5s interval, per open page, keeps
polling in a hidden tab) and the upgrade path (publish task events, then swap
the interval for a stream).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 11:00:21 +02:00
notandClaude Opus 5 3f8b438500 feat(portal-behandel): let a successful refresh clear the load failure (refs #162)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 10:46:41 +02:00
notandClaude Opus 5 d906e2c111 test(portal-behandel): a refresh must clear a stale load failure (refs #162)
If the first read fails the werkbak shows its error until the behandelaar
reloads — the very thing this slice removes. Fails with "expected <p
utrecht-paragraph …> to be null".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 10:46:28 +02:00
notandClaude Opus 5 e38bf62b43 feat(portal-behandel): refresh the werkbak on an interval while it is open (refs #162)
`interval(WERKBAK_REFRESH_MS)` re-reads the existing BFF werkbak endpoint,
scoped to the page's lifetime with `takeUntilDestroyed()`. A background read
leaves the rows and states on screen alone until it has an answer, so a tick
neither flashes the loading state over rows being read nor swaps the list for
the failure alert on a blip — only a foreground read (on open, after a
decision) speaks for whether the werkbak is readable at all.

No new endpoint, dependency or server state: rxjs and the endpoint are both
already here (ADR-0032).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 10:46:02 +02:00
notandClaude Opus 5 cd3faaf638 test(portal-behandel): the werkbak must show a new registration without a reload (refs #162)
A registration only reaches the Beoordelen task after the citizen supplies its
documents, so it lands in an already-open werkbak asynchronously — today a
behandelaar has to reload to see it.

Component spec: one interval passes and the werkbak has re-read itself, the new
row is on screen, and the loading state has not flashed over the rows being
read. Fails with "expected vi.fn() to be called 2 times, but got 1 times".
Two guards go with it — a failing background poll must not replace the list
with the load-failure alert, and the refresh must stop when the page is
destroyed.

E2E: the happy path now waits for the werkbak row WITHOUT reloading the page.
The removed `staff.reload()` is the assertion.

Refs the accepted mechanism in #163 (ADR-0032, landing with the implementation).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 10:45:17 +02:00