Skip to content

Let reviewers pull answers from their appraisal of the same study on another outcome - #847

Merged
InfinityBowman merged 3 commits into
mainfrom
feat/846-per-question-pull
Sep 19, 2026
Merged

InfinityBowman merged 3 commits into
mainfrom
feat/846-per-question-pull

Conversation

@InfinityBowman

@InfinityBowman InfinityBowman commented Sep 19, 2026

Copy link
Copy Markdown
Owner

Closes #846

Problem

RoB 2 and ROBINS-I are appraised per outcome, so a study with three outcomes gets three appraisals from each reviewer against the same instrument on the same paper. Most answers do not vary by outcome: randomisation, deviations from intended interventions, confounding and selection of participants are properties of the trial, not of the outcome measured. Today nothing carries across, so the reviewer re-reads the paper and re-types the same answers and support text once per outcome. That is where self-inconsistency gets in, and it surfaces at reconcile looking like two reviewers disagreeing.

The constraint is that this stays a reviewer aid. Nothing fills in silently, and accepting a copied answer is never the path of least resistance.

Change

Two ways to pull, both explicit, both only from the reviewer's own appraisals of the same study and instrument on a different outcome.

A section copy, from the menu beside the checklist title. carry-over.ts declares which sections are study-level per instrument: RoB 2 preliminary considerations, domains 1 and 2; ROBINS-I planning and confounding, sections C and D, domains 1 to 3. Everything else is per outcome and always starts blank. planAnswerCopy decides what lands, and the menu shows the same plan before the click, so the two cannot disagree. A section only fills where the target is entirely blank, so nothing is overwritten. RoB 2 domain 2 and ROBINS-I domain 1 additionally require the effect of interest to match, since it decides which variant of the domain is being assessed.

The menu is a checkbox list: every section, the blocked ones disabled with the reason (Not answered there, Already answered here, Needs the same effect of interest). It re-plans against the current ticks, because leaving out a section can block one that relied on it landing alongside, so the button's count is what will actually land.

A single-question pull, from the copy icon beside each signalling question's response buttons. The popover lists the reviewer's answer and comment for that same question on each other outcome, with a button to take one. It renders on every editable question whenever a sibling exists, so the feature is discoverable from the first checklist a reviewer fills, and it says so when the question is assessed per outcome and the answers are expected to differ. A single-key pull is an explicit act on one field, so unlike a section copy it may replace what is there.

A copied answer is not marked as copied anywhere. It is the reviewer's answer the moment they keep it, and the reviewer chose to take it, so nothing labels it after the fact. No schema change: the sync schema stays at version 2 and this branch migrates nothing.

Notes

  • checklist.copyAnswers takes either sections or keys and validates both against the instrument, rejects a source that is not the reviewer's own on a different outcome of the same study and instrument, and refuses a target that is no longer editable.
  • Nothing renders on a single-outcome project, on AMSTAR 2, or on a consensus checklist.
  • Preliminary considerations can only be copied as a whole section, so once any of its fields is filled it is out of reach. Field-level pull for the non-signalling sections is not in this PR.

Verification

  • pnpm --filter @corates/shared test: 355 passed, including 22 covering the plan and the mutator
  • pnpm --filter web test: 324 passed
  • pnpm --filter workers test: 129 passed
  • pnpm typecheck, pnpm lint: clean

https://claude.ai/code/session_016p87n257PNHSzWmRoFLA65

Summary by CodeRabbit

  • New Features
    • Copy study-level answers between your appraisals for the same study in RoB 2 and ROBINS-I.
    • Review available sections, copy blockers, and source outcomes before copying.
    • View answers and comments from other outcomes directly within signalling questions.
    • See when domain answers were copied and their source.
    • Copied answers remain protected from overwriting existing responses; editing an answer removes its copied status.
  • Bug Fixes
    • Added clearer messages for unavailable or invalid copy actions.

…r outcome

Adds a per-instrument carry-over list, a checklist.copyAnswers mutator
that fills only blank sections of a reviewer's own sibling appraisal, and
a menu beside the checklist title offering those siblings. Sync schema
moves to version 3 for the optional copiedFrom provenance map.

Part of #846.

Claude-Session: https://claude.ai/code/session_01TAEtViwHmBCJSDSVKkzTD6
Adds a copy popover beside every signalling question, listing the
reviewer's answer and comment for that question on their other outcomes
with a button to take one. A single-key pull is an explicit act on one
field, so unlike a section copy it may replace what is there, and
writing a key by hand now clears its copied-from mark.

The bulk menu becomes a checkbox list of the study-level sections, each
with the reason it cannot copy where one applies. It re-plans against the
current ticks, because leaving out a section can block one that relied on
it landing alongside, so the count on the button is what will actually
land.

Part of #846.

Claude-Session: https://claude.ai/code/session_016p87n257PNHSzWmRoFLA65
@coderabbitai

coderabbitai Bot commented Sep 19, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 3a073125-ef02-48e2-a249-1d21c2a8c8a7

📥 Commits

Reviewing files that changed from the base of the PR and between 8c3bc69 and 539c617.

📒 Files selected for processing (22)
  • packages/docs/architecture/diagrams/04-data-model.md
  • packages/shared/src/checklists/carry-over.ts
  • packages/shared/src/checklists/index.ts
  • packages/shared/src/sync/__tests__/copy-answers.test.ts
  • packages/shared/src/sync/__tests__/schema-snapshot.json
  • packages/shared/src/sync/app.ts
  • packages/shared/src/sync/copy-answers.ts
  • packages/shared/src/sync/index.ts
  • packages/shared/src/sync/migrations.ts
  • packages/shared/src/sync/mutators.ts
  • packages/shared/src/sync/schema.ts
  • packages/web/src/components/checklist/ROB2Checklist/DomainSection.tsx
  • packages/web/src/components/checklist/ROB2Checklist/ROB2Checklist.tsx
  • packages/web/src/components/checklist/ROB2Checklist/SignallingQuestion.tsx
  • packages/web/src/components/checklist/ROBINSIChecklist/DomainSection.tsx
  • packages/web/src/components/checklist/ROBINSIChecklist/ROBINSIChecklist.tsx
  • packages/web/src/components/checklist/ROBINSIChecklist/SignallingQuestion.tsx
  • packages/web/src/components/checklist/copy-answers/CopyAnswersMenu.tsx
  • packages/web/src/components/checklist/copy-answers/QuestionSourcesPopover.tsx
  • packages/web/src/components/checklist/copy-answers/useCopySources.ts
  • packages/web/src/project/ConnectionPool.ts
  • packages/web/src/project/workspace-data.ts
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

A copied answer is the reviewer's answer once they keep it, and the marks
said otherwise on the domain header and beside every question. Removing
them takes the whole provenance mechanism with it: checklists.copiedFrom,
the clearing on a hand-written answer, and the sync schema bump to
version 3 that existed only to carry the field. The schema is back to
version 2, byte-identical to main's, so the branch no longer migrates
anything.

Part of #846.

Claude-Session: https://claude.ai/code/session_016p87n257PNHSzWmRoFLA65
@InfinityBowman
InfinityBowman merged commit 0d09fc5 into main Sep 19, 2026
9 checks passed
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.

Let reviewers pull answers from another appraisal of the same study on a different outcome

1 participant