Skip to content

WIP Arbitration phase 3 - #394

Open
edwardhorsford wants to merge 18 commits into
mainfrom
arbitration-phase-3
Open

WIP Arbitration phase 3#394
edwardhorsford wants to merge 18 commits into
mainfrom
arbitration-phase-3

Conversation

@edwardhorsford

Copy link
Copy Markdown
Contributor

Description

Checklist

  • Tested against our testing policy (Resolution, Browser & Accessibility)
  • CHANGELOG entry

@edwardhorsford
edwardhorsford temporarily deployed to manage-breas-arbitratio-js3fqw August 5, 2026 10:16 Inactive
Setup (alone or panel with user picker), per-case compare with agree
actions, a different-outcome page, and a session overview showing
provisional outcomes. Sessions and outcomes are stubbed under
data.arbitrationSessions rather than written as real reads.
Arbitration sessions are reading sessions of type 'arbitration': setup
claims the backlog and records each case's release, the per-case flow
runs through the standard workflow with a new arbitration-compare step
(agree adopts a read's outcome and details), a different outcome goes
via the reused opinion and details pages, and every decision confirms
on the review page. Compare-first or opinion-first is a setting. The
session overview is the reading one with arbitration wording and
participant links. An unfinalised arbitration read is
awaiting_finalisation, not concluded.
filterAppointmentsByUserCanReadOrHasRead counted reads under two, so
released cases fell out of prev/next navigation. The status bar tag is
now Arbitration (orange) in arbitration sessions.
- Generate ~32 discordant cases for arbitration (was ~4) by drawing second
  reads from clinics 5-8 with forced disagreement
- Fix opinion-details-complete redirecting to review inside modal: wrap all
  three opinion-type redirects with modalBreakout()
- Panel mode passes skipUserFilter so all awaiting-arbitration cases are
  included in the session regardless of who read them
- Start page shows solo count hint when it differs from the total
- canUserReadCase accepts panelArbitration option to skip user check
- Case URL skips the existing-read redirect for arbitration sessions
- save-opinion finds next un-arbitrated case directly for arbitration
- isEditingExistingRead in arbitration checks for arbitration read, not
  original reads (panel members may have been original readers)
A panel arbitration is decided by several people together, but the read
only carried a single readerId. buildRead now stamps panelUserIds from the
session, and the case view names the panel in the read byline and as an
'Arbitrated by' row in the read summary.
@edwardhorsford
edwardhorsford temporarily deployed to manage-breas-arbitratio-js3fqw August 6, 2026 11:09 Inactive
…lazy

An arbitration read is made by everyone arbitrating together, so it now
carries arbitratorIds rather than a single readerId plus a panel list.
getReadAuthorIds gives display code one way to ask who made a read.

Arbitration settles a case once for everyone, so progress is how many of
the session's cases have been arbitrated - not what the current user has
read. Panel members who gave one of the original opinions were being
counted as already done, so a fresh session reported most of its cases
complete before any arbitration had happened.

Sessions no longer force lazy loading off, so they hold one case at a time
and release each case as it is reached rather than claiming the whole
backlog up front.
Arbitration sessions were excluded from the existing-read redirect, so
going back to a settled case restarted the compare flow. The redirect now
asks whether the case has been arbitrated rather than whether the user has
any read on it.

The page shows the arbitration read as the one being viewed and changed,
with the two original reads below as read-only context - reading keeps its
blind-reading gate and still doesn't show them.
Prev/next navigation dropped a case from the list once it was arbitrated,
so the links pointed at the current case and there was no way back to it.

The opinion page prefilled from the current user's own read, so amending an
arbitration outcome started from blank, or from a panel member's original
read.

An arbitration read's first summary row now reads Outcome rather than
Opinion - it settles the case rather than being one of several opinions -
and the existing-read page no longer lists the reads it arbitrated.
A case released into arbitration keeps its original reads unfinalised, so
it derived awaiting_finalisation and caseNeedsArbitration returned false.
The session could then find no candidates to top up with, and the overview
showed 'session complete' while still reporting cases remaining. A released
case now counts as needing arbitration until it has an arbitration read.

Saving an arbitration also treated every panel member who had read the case
originally as editing an existing read, so it returned to the existing-read
page instead of moving on. That check now looks for the arbitration read.

The next-case search wraps, so a case passed over earlier isn't stranded,
and the end-of-session page is worded for arbitration.
The status bar counted the current user's own reads, so it sat at '0 read'
however many cases the session had arbitrated. It now uses the session
progress doneCount, which counts arbitrated cases in an arbitration session.

Skipping used the reading predicate to find the next case, which rejects
cases a panel member originally read. With nothing found it fell through to
the end-of-session skipped-review page instead of moving on. The skip link
was also hidden on cases a panel member had read, offering plain next
navigation on a case they still had to arbitrate.
@edwardhorsford
edwardhorsford temporarily deployed to manage-breas-arbitratio-js3fqw August 6, 2026 15:13 Inactive
Deferring or requesting priors in an arbitration session used the reading
predicate to find the next case. That rejects cases a panel member read
originally, so with nothing found both fell through to the end-of-session
skipped-review page instead of moving on.

The same question was being answered in six places, two of which had
already been fixed for arbitration by hand. getNextCaseInSession and
getFirstOutstandingCaseInSession now answer it once, branching on the
session type, so a new caller can't get the arbitration case wrong.
…sion

Deferring or requesting priors settles a case, but only writeReading took
one off the session's skipped list. A case skipped and then deferred stayed
on the list, so the session claimed a skipped case remained when there was
nothing left to do on it. Affected regular reading as much as arbitration.

The arbitration next-case search also wrapped to the start, which meant it
kept finding skipped cases and never reached the end of the session - so
the skipped-review interstitial never appeared. It now looks forward only
and passes over skipped cases, matching reading.
The arbitration overview now has its own template rather than bending
reading's: no tabs, a single case list at /reading/session/:id showing
both original reads against the outcome, and outcome summary cards.
Reading's session.html loses the arbitration branches it no longer needs.

Finalisation was only half-built for arbitration. The unfinalised-reads
lookup found reads by readerId, but an arbitration read carries
arbitratorIds instead, so it matched nothing - the count was always zero
and the session panel always claimed everything was finalised. It now
matches on getReadAuthorIds, as withReadFinalised already did.

Finalisation is also visible and actionable per case: the existing-read
page says whether the read has finalised and when it will, and offers to
finalise it now. Once finalised it can no longer be changed, so the
summary drops its change links and records when it was finalised.
Picks up getOriginalReads, getAutoFinaliseTime and finaliseReadOnCase,
and refreshes the line numbers the arbitration work shifted.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant