Skip to content

CPD follow-up: preserve goal carry choice across next-year target confirmation #3161

Closed

Description

@BigSimmo

Scope addition raised in review on PR #3122, deferred from that PR.

Review thread: #3122 (comment)

Reviewer request (verbatim):

P2 Badge Preserve the carry choice across target confirmation

Fresh evidence in the implementation shows that the absent-destination flow still loses its context: this link carries only the destination year, and after confirmation CmeSetupRoute pushes back to /cme/setup, not to the source plan or selected goal. A doctor must manually find the prior year and choose the goal again, so the promised confirm-then-return carry action is not implemented. Include the source year and goal ID in a validated return target and resume that exact carry choice after confirmation.

Useful? React with 👍 / 👎.

Activity

  1. BigSimmo commented on Oct 15, 2026

    @BigSimmo
    OwnerAuthor

    PR draft ready (2026-10-15) — local branch mavis/3161-cme-goal-carry-choice, not pushed, no PR opened, no label added.

    Shape (4 files, 267 +/3 -):

    • src/lib/cme/return-target.ts (new, 66 lines) — zod-validated { fromYear, goalId? } round-trip via base64url JSON. decodeCmeCarryReturnTarget returns null on any failure rather than throwing — worst case is the pre-fix behaviour, never an unsafe deep-link.
    • src/components/cme/cme-setup-route.tsx — reads ?returnTo= via useSearchParams, decodes, after confirmation navigates to /cme/plan?year=<fromYear>[&goal=<goalId>]#cme-carry-goals when valid, else falls back to the original /cme/setup?year=<year> (no regression).
    • src/components/cme/cme-plan-page.tsx:354 — the "Confirm <year+1> targets first" link now appends &returnTo=<encoded> so the carry context survives the round trip.
    • tests/cme-setup-route-return-target.dom.test.tsx (new, 178 lines) — 11 cases: round-trip with/without goal, malformed payload, tampered payload (out-of-range year, overlong goalId), missing target, programme-page no-confirm, codec edge cases.

    Verification (all run on Node 24.22, npm 11.19):

    • ✅ tsc -p tsconfig.changed.json --noEmit (focused on the 4 changed files): 0 errors.
    • ✅ tests/cme-setup-route-return-target.dom.test.tsx: 11/11 pass.
    • ✅ Related CPD tests (no regressions): cme-setup.dom.test.tsx 10/10, cme-plan-page.dom.test.tsx 14/14, cme-plan-carry.test.ts 10/10, cme-one-tap-routine-log.dom.test.tsx 3/3, cme-catch-up-plan.test.ts 11/11. 48/48 pass.

    Open for owner decision:

    • The goalId field is in the schema but only fromYear is set in cme-plan-page.tsx. A future flow that carries a specific goal could pass goalId too. Currently the link is invoked from the general "Confirm <year+1> targets first" prompt and the doctor re-selects the goal on return. Acceptable, or do you want the specific goal to flow through now?
    • The cmeCarryReturnTargetHref always appends #cme-carry-goals (the carry section anchor on the plan page). If the doctor came from elsewhere (e.g., the dashboard), this still lands them on the plan page at the carry section. Confirm the landing is right for those flows before they adopt the link.

    Diff: /workspace/issue-3161-pr-diff.patch (327 lines including the test). Branch is local at mavis/3161-cme-goal-carry-choice in /workspace/PsychSift, staged, not committed, not pushed. Push + PR + merge is yours.

  2. BigSimmo commented on Oct 15, 2026

    @BigSimmo
    OwnerAuthor

    Rebase + re-verification (2026-10-15, 14:25 local):

    Main moved forward 5 commits (a07dec0 → e0c62df) since the PR draft was first staged. Rebased branch mavis/3161-cme-goal-carry-choice onto the new main. The 4 files in the diff are unchanged in shape; no conflicts with the 5 new commits.

    Re-verification on current main (e0c62df):

    • ✅ tsc -p tsconfig.changed.json --noEmit (4 changed files): 0 errors.
    • ✅ tests/cme-setup-route-return-target.dom.test.tsx: 11/11 pass.
    • ✅ Related CPD tests: 48/48 pass (cme-setup 10, cme-plan-page 14, cme-plan-carry 10, cme-one-tap-routine-log 3, cme-catch-up-plan 11).

    No open PR addresses this issue (verified by is:pr is:open search). The 4 currently open PRs on PsychSift (#3555 migrations rule, #3554 search cutoff, #3553 #3538 walk-back, #3546 admin ingestion) are unrelated.

    Diff at /workspace/issue-3161-pr-diff.patch — 327 lines, 267+/3-, 4 files. Branch is local, not pushed, no PR opened, no label added.

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