Skip to content

The cases CSV carries every cycle while the open and staff-closed lists carry one #603

Description

@Taleef7

#602 made the cases CSV carry every filter the work list sends, and a frontend test compares the two
query strings so they cannot drift. One width difference is left, and it is the one that test cannot
see: the period default is a server-side default with no query parameter.

What is wrong

isCurrentCycleDefault (backend-ts/src/case/worklist-read-model.ts) makes the open, blank
and staff-closed lists show the per-measure current compliance cycle. /api/exports/cases
applies no period logic at all — §6.3 says so explicitly for staff_closed, and it is true for every
status.

So:

one OPEN case, evaluation_period 2025-01-01 (a prior cycle), nothing else

GET /api/cases?status=open                      → 0 rows, X-Total-Count: 0
GET /api/exports/cases?format=csv&status=open   → contains the case

The screen says "0 cases loaded" and the button under it downloads a file with a row in it.

On ?status=staff_closed this is unbounded rather than incidental: staff closures accumulate across
years, CYCLE_ROLLED_OVER never sweeps them, the tab shows only the current cycle, and its three
header counts describe that cycle — while the CSV taken from it carries every prior year's closures
beside them.

Why it was not fixed in #602

Two reasons, and the second is the real one:

  1. It needs a decision rather than a fix. Making the export match the list would change what
    /api/exports/cases has always returned, and the endpoint is documented as all-history (§6.3) —
    something downstream may depend on that. Making the list match the export is obviously wrong.
    A third option is an explicit ?period= on the export plus the button sending the list's default,
    which keeps the endpoint's default behaviour and closes the screen/file gap.
  2. The parity test in fix(export): the cases CSV describes the list it was taken from #602 compares query strings. A server-side default appears in neither, so
    whatever is decided here needs a different kind of test — a result-set comparison over one
    fixture, the way ADR-084's two work-list loaders are pinned against each other.

Also in scope, small

site is compared case-sensitively by the list (worklist-read-model.ts, c.site === filters.site)
and case-insensitively by the export (export-csv.ts, both sides lower-cased). Before #602 the
export's site filter was only reachable by hand-writing a URL; now the button sends it on every
export. The practical risk is low — the options are built from the directory's own strings — but a
directory holding two sites differing only in case would export both under a heading naming one.
Pick one comparison and share it, as matchesCaseSearch now is.

Recorded

§6.3 in docs/DATA_MODEL_CONTRACTS.md now states the period difference rather than implying parity,
so nothing in the always-loaded contract claims this is closed.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions