8.8 KiB
8.8 KiB
Patient Pathway Graph Stability + Unified Timeline Plan
Scope
Refactor pathway graph + timeline cards so career and education are rendered from one canonical dataset, hover behavior is shared and stable, and sidebar tags are derived from canonical skills frequency.
Root-Cause Findings
- Hover jiggle source:
CareerConstellationre-creates the full SVG and force simulation wheneverhighlightedNodeIdchanges because the main D3 effect depends on[dimensions, highlightedNodeId, pinnedNodeId](src/components/CareerConstellation.tsx). - Date mismatch source: duplicated timeline/date models across:
consultations(dateanddurationstrings) insrc/data/consultations.tsconstellationNodes(startYear/endYear) insrc/data/constellation.ts- education card details built separately from
documentsinsrc/components/EducationSubsection.tsx
- Experience/education split source:
DashboardLayoutrendersWorkExperienceSubsectionandEducationSubsectionas separate blocks (src/components/DashboardLayout.tsx), so hover wiring and pill treatment are inconsistent by design. - Sidebar tags source mismatch: tags are static in
src/data/tags.tsand consumed directly insrc/components/Sidebar.tsx, not derived from actual timeline entities.
Target Canonical Model
Define a single timeline entity type in src/types/pmr.ts and canonical data module in src/data/timeline.ts.
Required per-entry fields:
id: stringkind: 'career' | 'education'title: string(full card title)graphLabel: string(short node label)organization: stringorgColor: stringdateRange: { start: string; end: string | null; display: string; startYear: number; endYear: number | null }description: stringdetails: string[](card bullets)skills: string[](skill IDs for graph links + aggregation)
Derived selectors/utilities in src/data/timeline.ts:
timelineEntities(canonical array, sorted reverse-chronological)buildConstellationData()=> role nodes + links from canonical entities + skills cataloggetTopTimelineSkills(limit)=> ordered skills by descending frequency for sidebar tags
File-Level Implementation Plan
- Add canonical types/data and migrate existing records.
- Files:
src/types/pmr.ts, newsrc/data/timeline.ts, optionally thin compatibility exports fromsrc/data/consultations.ts/src/data/constellation.ts. - Action: move career + education entries into
timelineEntities; stop hand-maintained duplicate date fields.
- Refactor graph data construction to consume canonical entities only.
- Files:
src/data/constellation.ts(or replace with derived module),src/components/CareerConstellation.tsx. - Action: remove hard-coded role node years/labels from graph source and generate from canonical date ranges.
- Stabilize hover interaction and remove graph-wide re-init on hover.
- File:
src/components/CareerConstellation.tsx. - Action:
- Split graph init/layout effect from highlight-only effect.
- Keep simulation/SVG creation dependent on dimensions/data only.
- Apply highlight updates imperatively via ref without rebuilding nodes/forces.
- Keep
onNodeHovercontract for role nodes; ensure null reset on leave/touch clear.
- Unify timeline card rendering (career + education in one flow).
- Files: replace
src/components/WorkExperienceSubsection.tsxandsrc/components/EducationSubsection.tsxusage with a unified list component (newsrc/components/TimelineInterventionsSubsection.tsxor equivalent), updatesrc/components/DashboardLayout.tsx. - Action:
- Remove standalone work-experience subheader and old role pill treatment.
- Render both kinds in one chronological list.
- Career cards:
Career Interventionpill. - Education cards: right-aligned card layout +
Education Interventionpill inside each card. - Remove separate education block under work experience.
- Unify graph/card highlight source of truth.
- Files:
src/components/DashboardLayout.tsx, unified timeline component,src/components/CareerConstellation.tsx. - Action:
- Replace split
highlightedNodeId/highlightedRoleIdwith one active timeline entry ID for role-type entities. - Hovering graph role node highlights matching card; hovering matching card highlights graph node.
- Keep click behavior opening detail panel by entity kind.
- Replace split
- Feed sidebar tags from canonical skill aggregation.
- Files:
src/components/Sidebar.tsx,src/data/tags.ts(remove static dependency or convert to fallback only),src/data/timeline.ts. - Action:
- Compute top N frequent skills from
timelineEntities.skills. - Map aggregated skills to existing
Tagshape with deterministic color-variant mapping.
- Compute top N frequent skills from
- Regression sweep + quality gates.
- Files:
src/components/CommandPalette.tsx,src/lib/search.tsonly if section IDs/labels or timeline references need consistency updates. - Action: ensure route/anchor labels still work after removing separate education section.
Build/Verification Checklist
- Hovering graph node and corresponding card produce identical highlight result.
- Hover no longer causes graph jitter/repositioning.
- Graph timeline date ranges and card date ranges match for every entry.
- Canonical timeline dataset is the only source for career + education cards and graph role nodes/links.
- Sidebar tags are generated from canonical skill frequencies (descending).
- Career entries show
Career Intervention; education entries are right-aligned withEducation Intervention. - Separate education section below experience is removed.
npm run lintnpm run typechecknpm run build
Runtime Task Mapping
task-1771244841-616d: canonical model/data unificationtask-1771244841-cb07: graph stability + shared hover lifecycletask-1771244841-2f8e: unified career/education timeline presentationtask-1771244841-9748: sidebar tag aggregation + quality gates
Progress Updates
- 2026-02-16: Completed
task-1771244841-616d.- Added canonical timeline schema (
TimelineEntity,TimelineEntityDateRange,TimelineEntityKind) insrc/types/pmr.ts. - Added
src/data/timeline.tsas source-of-truth for timeline entities, includingtimelineEntities,timelineConsultations,buildConstellationData(), andgetTopTimelineSkills(). - Replaced static duplicated
consultationsandconstellationdatasets with compatibility exports derived from canonical timeline data. - Validation run:
npm run lint,npm run typecheck,npm run buildall passed (warnings only).
- Added canonical timeline schema (
- 2026-02-16: Completed
task-1771244841-cb07.- Refactored
src/components/CareerConstellation.tsxso the D3 initialization/simulation effect depends only ondimensionsrather than hover/pin state. - Added ref-backed highlight target tracking (
highlightedNodeIdRef,pinnedNodeIdRef) so hover and pin changes update styling without tearing down/recreating the SVG simulation. - Updated pointer/touch handlers and render tick highlight fallback to read from refs, preserving graph-card hover sync while eliminating hover-driven graph reinitialization jitter.
- Validation run:
npm run lint,npm run typecheck,npm run buildall passed (same pre-existing warnings only).
- Refactored
- 2026-02-16: Completed
task-1771244841-2f8e.- Added
src/components/TimelineInterventionsSubsection.tsxto render career + education entries in one canonical timeline flow sourced fromtimelineEntities. - Replaced separate
WorkExperienceSubsection+EducationSubsectionblocks insrc/components/DashboardLayout.tsxwith unified timeline rendering; removed standalone education section beneath work experience. - Removed legacy chronology "Role/Education" badge pills around the split sections, and added per-card intervention pills:
- Career cards show
Career Intervention. - Education cards show
Education Intervention.
- Career cards show
- Added right-aligned treatment for education cards in
src/index.cssvia.timeline-intervention-item--education. - Preserved graph/card hover parity by keeping existing
onNodeHighlight+highlightedRoleIdwiring across unified cards. - Validation run:
npm run lint,npm run typecheck,npm run buildall passed (same pre-existing warnings only).
- Added
- 2026-02-16: Completed
task-1771244841-9748.- Replaced static sidebar tags in
src/data/tags.tswith canonical aggregation viagetTopTimelineSkills(), preserving deterministic ordering (most frequent skills first) and mapping to existing tag color variants. - Kept sidebar rendering path unchanged in
src/components/Sidebar.tsxso tags now automatically follow canonical timeline skill frequencies. - Validation run:
npm run lint,npm run typecheck,npm run build,npm audit --omit=devpassed (eslintretains the same 2 pre-existing react-refresh warnings). - Repository check confirmed no automated test/spec files are currently present under
src/.
- Replaced static sidebar tags in