Skip to content

feat: show series progress and redirect subjects after a remote assignment - #1866

Open
joshunrau wants to merge 4 commits into
DouglasNeuroInformatics:mainfrom
joshunrau:feat/1849-1862-series-progress-and-assignment-redirect
Open

joshunrau wants to merge 4 commits into
DouglasNeuroInformatics:mainfrom
joshunrau:feat/1849-1862-series-progress-and-assignment-redirect

Conversation

@joshunrau

@joshunrau joshunrau commented Nov 4, 2026 •

Copy link
Copy Markdown
Collaborator

Closes #1849. Closes #1862.

Series progress bar (#1849)

SeriesInstrumentRenderer now shows a bar labelled "Instrument N of M" above every item. It appears on the form screen as well as the interstitial, so a skipProgress series shows progress too; both built-in series are skipProgress, so they previously showed none. It starts at a resumed assignment's initialSeriesIndex, and it stays mounted between items so it animates each advance. It replaces the old "Instruments Completed" text and is always on, with no new params flag.

Redirect after a remote assignment is completed (#1862)

  • An assignment can carry an optional redirectUrl. It can be set in the single-assignment dialog, once per request in the bulk wizard, or through POST /v1/assignments and /bulk.
  • $AssignmentRedirectUrl accepts only https:// URLs of up to 2000 characters. It normalizes them to ASCII, because the gateway's root props go through btoa.
  • The URL is validated when the assignment is created and validated again when the gateway stores it. The forms show zod's localized Must start with "https://" message.
  • Once the completing PATCH succeeds, the gateway shows a 5-second countdown with a "Continue now" link below the completion screen, then calls location.replace. A completing PATCH means a scalar submit, the last series item, or terminate(). react-core is untouched.
  • build(gateway) commit: the gateway image now runs prisma db push on every start. Previously run.sh copied a template database only onto an empty volume, so an existing deployment would never have received the new column. Additive changes now apply themselves, and a change that would lose data stops the container. apps/gateway/AGENTS.md documents the rule.

Also

  • test(web) commit: fixes WalkthroughProvider.test.tsx, broken on main since 5fa1391a2 retitled the dismiss button. Its "hidden on the last step" assertion had been passing without checking anything.

Verification

  • Lint and coverage: pnpm lint passes. pnpm test:coverage passes at 100% on all four metrics.
  • Unit tests:
    • SeriesProgressBar.test.tsx and SeriesInstrumentRenderer.test.tsx
    • assignment.test.ts (schemas)
    • assignments.service.test.ts, plus the API integration suite 05-assignment-redirect.suite.ts
    • Gateway: CompletionRedirect.test.tsx, Root.test.tsx, root.router.test.ts and api.router.test.ts
    • Web: validation.test.ts, remote-assignment.test.tsx, TimepointsStep.test.tsx, ReviewStep.test.tsx and useBulkAssignmentWizard.test.ts
  • E2E: pnpm test:e2e passes.
    • The first local run used the default parallel workers. 39 tests unrelated to this change then hit the API's login throttle (429, 50 logins a minute).
    • Those 39, plus 2 that did not run, all passed on a --workers=1 re-run, which is how CI runs the suite.
    • New specs:
      • series-instrument.spec.ts
      • gateway-assignment.spec.ts: the subject is redirected after completion
      • remote-assignment.spec.ts: the dialog rejects http://
      • remote-assignments-wizard.spec.ts: the wizard holds back review
      • bulk-remote-assignments.spec.ts: the API applies the URL to each assignment in a batch
  • Gateway image: I built it from this branch and booted it four ways:
    • Empty volume: it creates the database with redirectUrl, and / returns 200.
    • A volume from main's schema, holding an outstanding row: it adds the column on start, and the row survives with a null redirectUrl. GET /api/assignments still returns that row.
    • Assignments through the image's API: POST /api/assignments with https://exämple.com/done stores https://xn--exmple-cua.com/done. The assignment page renders with it in its root props. An http:// redirect gets a 400, and nothing is written.
    • A schema change that would drop a column holding data: db push refuses, the container exits 1, and the data is untouched.

Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com

joshunrau and others added 4 commits November 4, 2026 16:07
The only position feedback a series gave was an "Instruments Completed"
counter on the interstitial screen, which never appears while a form is
showing and never appears at all for a skipProgress series. Replace it
with a bar above every item, filled by the items completed and labelled
with the item in progress. It starts at a resumed assignment's position
and stays mounted between items so it animates each advance.

Closes DouglasNeuroInformatics#1849

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
run.sh copied a template database only onto an empty volume, so a
deployed gateway never received a schema change made after it was first
started. Install the Prisma CLI the lockfile resolved into the runner
image and have run.sh run `prisma db push` before the server: it creates
the database on an empty volume, brings an existing one up to date, and
stops the container rather than drop data.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ent is completed

A remote assignment ended on a static completion screen, leaving a
subject who arrived from a study portal or clinic page no way back. An
assignment can now carry an optional https redirect URL, set when it is
created in the single-assignment dialog, the bulk wizard or the API
(one URL per bulk request). The gateway stores it and, once the
completing submission is recorded, shows a five-second countdown under
the completion screen before replacing the page with that URL.

The URL is validated once, when the assignment is created, and is
normalized to ASCII so it survives the gateway's latin1-only page props.

Closes DouglasNeuroInformatics#1862

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5fa1391 retitled "Don't show again" to "Don't Show Again" without
updating its tests. One then failed to find the button, and the one
asserting the button is hidden on the last step passed without
checking anything, since no button ever had the old name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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.

Redirect the client to a configurable URL after a subject completes a series instrument Progress bar for series instruments

1 participant