WIP Arbitration phase 3 - #394
Open
edwardhorsford wants to merge 18 commits into
Open
Conversation
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
force-pushed
the
arbitration-phase-3
branch
from
August 6, 2026 11:09
0548c25 to
b7ab77c
Compare
…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.
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Checklist