You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
As a new team member going through onboarding, I want a knowledge check to feel rewarding when I pass it, and questions I got wrong to be re-asked in a dedicated place instead of inside the next phase's check, so that every check only asks about the phase I am actually in, and I still get re-tested on everything I missed before I count as onboarded.
As a PM, I want to see and edit a member's knowledge checks in the team member view, so that I can track whether they understood a phase and tailor the questions to the project.
Context & Motivation
Follow-up to #128. Three points came out of the review of the knowledge-check feature:
Passing a check gives almost no feedback. The result is a small static banner. Passing should feel like an achievement, not like a form submit.
The PM view is blind to knowledge checks. In Team Management → member detail, a PM sees the onboarding path and can edit steps, but no check status, no results, and no way to edit the questions — even though the backend endpoints for this already exist and are unused.
Carry-over of wrong answers is thematically wrong. Questions answered incorrectly are currently appended to the next phase's check, where they do not belong to the topic being tested. On top of that, a question missed in the last phase is silently dropped and never re-asked, which defeats the original "you get tested on everything in the end" goal.
For point 3 the fix is to decouple the repeats from the phases: collect them in a per-user review pool that can be answered at any time via a "Test your knowledge" entry point, and make an empty pool a second condition for finishing onboarding (next to passing the final phase check). Care is needed around onboarding detection, since the sidebar hides the onboarding tab as soon as the user counts as onboarded.
Acceptance Criteria
Positive feedback on passing
Passing a knowledge check shows a celebratory result (animated banner + confetti), not just a static "done" state
After submitting, the view scrolls back to the result so it is visible even when the user was at the last question
Failing a check still scrolls to the result and clearly shows score and required percentage
All animations respect prefers-reduced-motion
Review pool instead of next-phase carry-over
A phase check only contains that phase's own questions
Questions answered incorrectly land in a per-user review pool, independent of any phase
Questions missed in the path's final phase are collected as well (currently dropped)
A "Test your knowledge" entry point in the onboarding view opens the pool, badged with the number of open questions, and is only shown when something is open
Answering correctly removes a question from the pool permanently; answering wrong keeps it open
Answering only part of the pool is possible (no all-or-nothing submit)
A user counts as onboarded only when the final phase check is passed and the pool is empty
Completing the pool as the last open item finishes onboarding and triggers the completion celebration
Onboarding detection / sidebar visibility still behaves correctly with the new gate
PM view
The phase overview in the member detail view shows per phase whether a check exists and whether it was passed (icon + label, not color alone)
A PM can open a member's submitted attempts for a phase, incl. score and which questions were answered wrong
A PM can create and edit the check questions of a phase (multiple choice + short text, options, correct answers, explanation)
Validation errors (e.g. MC with fewer than 2 options) are surfaced before saving
The PM view shows the member's open review questions, so it is understandable why someone is not onboarded yet
General
Backend: ./gradlew clean check green, tests for the new behavior added
Frontend: npm run lint, npm run build, npm run test green
GET /api/v1/onboarding/me/review-check — the user's open pool (no correct answers)
POST /api/v1/onboarding/me/review-check/attempts — grade answers; no pass threshold, partial submissions allowed
GET /api/v1/onboarding/users/{userId}/review-check — PM/HR/Admin view of a member's pool
Onboarding completion (userApi.markOnboardingCompleted) has to be evaluated from both submit paths — passing the final check and clearing the last pool item — otherwise a user can get stuck.
Gotcha: a question must enter the pool at most once ever. The attempt history counts a question as "once wrong" forever, so deduplicating only against open items resurrects an already cleared question when the phase check is retaken — with the new gate that blocks onboarding permanently.
Gotcha:PhaseCheckReviewItem.targetPhaseId becomes meaningless but cannot simply be dropped. The schema is managed by Hibernate ddl-auto: update (no Flyway at runtime), which never drops columns nor relaxes NOT NULL — removing the field works on a fresh schema and breaks inserts on every existing one. Keep it (write sourcePhaseId into it) or add a real migration.
No AI-service changes needed; short-text grading via /grade-answers stays as is.
Frontend (sprintstart-frontend)
The PM-facing endpoints already existed unused in onboardingService.ts: fetchPhaseCheckForEditing, savePhaseCheck, fetchPhaseCheckAttempts. getUserOnboardingPath already returns phases[].checkSummary — the member view just never rendered it.
PUT /phases/{phaseId}/checks is implicitly per-user: onboarding paths are per-user instances, so a phase belongs to exactly one member. No extra plumbing needed for "edit this member's check".
Attempt answers only carry questionId; join the question text from fetchPhaseCheckForEditing. Questions replaced since an attempt are no longer resolvable — handle that case.
Completion must come from a backend flag (onboardingCompleted), not from deriving "was this the last phase?" in the frontend, since an open pool keeps the journey running past the final check.
Sidebar visibility hangs off hasCompletedOnboarding via auth/accessPolicy.ts (isOnboardingAccessible); the profile is deliberately not refreshed immediately so the celebration can play before the onboarding UI is gated away.
Question rendering should be shared between the phase check and the review check instead of duplicating the question card.
User Story
As a new team member going through onboarding,
I want a knowledge check to feel rewarding when I pass it, and questions I got wrong to be re-asked in a dedicated place instead of inside the next phase's check,
so that every check only asks about the phase I am actually in, and I still get re-tested on everything I missed before I count as onboarded.
As a PM,
I want to see and edit a member's knowledge checks in the team member view,
so that I can track whether they understood a phase and tailor the questions to the project.
Context & Motivation
Follow-up to #128. Three points came out of the review of the knowledge-check feature:
For point 3 the fix is to decouple the repeats from the phases: collect them in a per-user review pool that can be answered at any time via a "Test your knowledge" entry point, and make an empty pool a second condition for finishing onboarding (next to passing the final phase check). Care is needed around onboarding detection, since the sidebar hides the onboarding tab as soon as the user counts as onboarded.
Acceptance Criteria
Positive feedback on passing
prefers-reduced-motionReview pool instead of next-phase carry-over
PM view
General
./gradlew clean checkgreen, tests for the new behavior addednpm run lint,npm run build,npm run testgreenTechnical Notes
Backend (
sprintstart-backend, moduleonboarding)PhaseCheckService; the pool entityPhaseCheckReviewItemalready exists from [Story]: Knowledge checks at onboarding milestones #128 and only needs to be decoupled from the phase.GET /api/v1/onboarding/me/review-check— the user's open pool (no correct answers)POST /api/v1/onboarding/me/review-check/attempts— grade answers; no pass threshold, partial submissions allowedGET /api/v1/onboarding/users/{userId}/review-check— PM/HR/Admin view of a member's pooluserApi.markOnboardingCompleted) has to be evaluated from both submit paths — passing the final check and clearing the last pool item — otherwise a user can get stuck.PhaseCheckReviewItem.targetPhaseIdbecomes meaningless but cannot simply be dropped. The schema is managed by Hibernateddl-auto: update(no Flyway at runtime), which never drops columns nor relaxesNOT NULL— removing the field works on a fresh schema and breaks inserts on every existing one. Keep it (writesourcePhaseIdinto it) or add a real migration./grade-answersstays as is.Frontend (
sprintstart-frontend)onboardingService.ts:fetchPhaseCheckForEditing,savePhaseCheck,fetchPhaseCheckAttempts.getUserOnboardingPathalready returnsphases[].checkSummary— the member view just never rendered it.PUT /phases/{phaseId}/checksis implicitly per-user: onboarding paths are per-user instances, so a phase belongs to exactly one member. No extra plumbing needed for "edit this member's check".questionId; join the question text fromfetchPhaseCheckForEditing. Questions replaced since an attempt are no longer resolvable — handle that case.onboardingCompleted), not from deriving "was this the last phase?" in the frontend, since an open pool keeps the journey running past the final check.hasCompletedOnboardingviaauth/accessPolicy.ts(isOnboardingAccessible); the profile is deliberately not refreshed immediately so the celebration can play before the onboarding UI is gated away.