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
Copy file name to clipboardExpand all lines: CLAUDE.md
+30Lines changed: 30 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -781,6 +781,36 @@ year the plan claims. `verified: false` warns, exactly like `programs.json`.
781
781
782
782
The selection modal lives in `src/components/OptionGroupModal.tsx`. Two earlier notes in this file and in `REVIEW.md` said it had been inlined into `TimelineVisualization.tsx` — it was, and then extracted again; grepping only `TimelineVisualization.tsx` for `kind` therefore suggests `minCredits` is unimplemented when it is not.
783
783
784
+
**A picked option is drawn where the box was, not where the data files it.** One
785
+
course code can be offered by several boxes, and the boxes need not sit in the
786
+
same study year. CTMAT offers SF1677/SF1678/SF1691 as the year-2 *villkorligt
787
+
valfria* group **and** among the year-3 elective boxes, because a student picks
788
+
one of them in year 2 and may take another as a free elective in year 3. The data
789
+
file carries one entry per code, stamped `year: 2`, so resolving a pick straight
790
+
from that entry drew Komplex analys in year 2 however you got there — the box the
791
+
user clicked was not an input to the placement at all.
792
+
793
+
A picked option is therefore re-stamped to the year of the group it was picked
794
+
from, keeping its own period layout. Keeping the layout is not a compromise: the
795
+
group bar is only an *envelope* (its shape is the per-period maximum of its
796
+
options), so an option whose shape differs from the box has always drawn its own
797
+
— CTMAT's DD1351 picked in the "P2" box spans P1+P2. Only the year was ever
798
+
wrong. Measured over all eight programmes, the year mismatch is CTMAT-only:
799
+
exactly those three courses, all five cohorts, both spring boxes.
800
+
801
+
Selections are **mutually exclusive across groups** — a course is taken once, so
802
+
picking it in one box releases it from any other. Without that, "the box that was
803
+
clicked" has no single answer. This also bites the same-year case, which is far
804
+
more common (21 codes across CTFYS and CTMAT sit in two or three boxes of the
805
+
same year): picking MH1023 in the P3 box and then the P4 box now leaves the P3
806
+
box an unfilled placeholder instead of quietly holding both.
807
+
808
+
The trap when changing any of this: the bar-drawing loop has a defensive
809
+
`coursesInOptionGroups.has(code)` guard, and that set must keep meaning "an option
810
+
somewhere, picked nowhere". Widening it to all option codes makes picked courses
811
+
render their connector and exam markers with **no bars** — and neither `tsc` nor
812
+
`eslint` sees it, because nothing about the types changes.
813
+
784
814
**Chart height must stay a pure function of the data.**`TimelineVisualization`
785
815
used to seed its height from `svgRef.current.clientHeight` — the height its own
786
816
previous render had written onto that node — and then only ever grew it
0 commit comments