Problem
src/components/features/ReconstructedResume.tsx is 1489 lines — 7× the ~200 LOC guidance in CLAUDE.md, and the single largest feature component in the repo.
CLAUDE.md names it as known debt:
⚠️ Known debt — do not imitate: ReconstructedResume.tsx (1489), SectionRewrite.tsx (607), ModelSelector.tsx (556), ReconstructedRole.tsx (490) all violate this. If you are editing one, prefer extracting your change into a new sibling over growing the file further.
fallow reports three functions in this one file over the guidance:
| Function |
LOC |
ReconstructedResume |
370 |
ExperienceSection |
320 |
ProjectsSection |
143 |
with AchievementsSection alongside them. Four peer section renderers are co-located in one module, and the outer component threads props to all of them.
Why now, and why not in #858
#858 grew this file from 1356 → 1489 (+133) while adding parsed-entry deletion. It did extract a sibling (src/lib/edit/entry-remove.ts), which is the right instinct — the extraction just is not where the mass is.
Splitting the sections inside #858 was explicitly declined: that diff is already 1846 insertions, and moving four section renderers would have buried the index-remap change — the part that actually needed careful review. Filed separately instead, per the review thread on #858.
This is a refactor: no behaviour change, no user-visible difference.
Reuse analysis
Capability: render one section of the reconstructed résumé.
Existing surfaces found:
Decision: extend the existing one-module-per-section convention. No new abstraction, no new design-system piece, no new panel — this moves code that already exists into the file layout its two siblings already use.
Implementation sketch
Extract each section into its own module under src/components/features/, mirroring ReconstructedRole.tsx:
ExperienceSection (320 LOC) — the largest win, and the one whose extraction most clarifies the parent.
ProjectsSection (143 LOC).
AchievementsSection.
Each takes the props it already receives today; the parent keeps the shared state and the buildEntryGroups call. Do them as separate commits (or separate PRs) so each diff is readable as a pure move — a move plus an edit in one diff is exactly what makes this kind of refactor expensive to review.
Update the CLAUDE.md "Known debt" line with the resulting LOC when done.
Acceptance criteria
Not in scope
SectionRewrite.tsx (607), ModelSelector.tsx (556), ReconstructedRole.tsx (490) — same debt class, separate issues.
- Any change to what the sections render or how the edit model works.
Problem
src/components/features/ReconstructedResume.tsxis 1489 lines — 7× the ~200 LOC guidance inCLAUDE.md, and the single largest feature component in the repo.CLAUDE.mdnames it as known debt:fallowreports three functions in this one file over the guidance:ReconstructedResumeExperienceSectionProjectsSectionwith
AchievementsSectionalongside them. Four peer section renderers are co-located in one module, and the outer component threads props to all of them.Why now, and why not in #858
#858 grew this file from 1356 → 1489 (+133) while adding parsed-entry deletion. It did extract a sibling (
src/lib/edit/entry-remove.ts), which is the right instinct — the extraction just is not where the mass is.Splitting the sections inside #858 was explicitly declined: that diff is already 1846 insertions, and moving four section renderers would have buried the index-remap change — the part that actually needed careful review. Filed separately instead, per the review thread on #858.
This is a
refactor: no behaviour change, no user-visible difference.Reuse analysis
Capability: render one section of the reconstructed résumé.
Existing surfaces found:
ReconstructedRole.tsx(490 LOC) andReconstructedEducationSkills.tsx— sections that already live in their own modules. The split target is the shape these two already have; this issue makes the remaining sections match their siblings.src/lib/edit/entry-remove.ts— the shared delete definition all sections route through, already extracted by feat: [edit] A parsed entry cannot be deleted from the reconstructed résumé — only user-ADDED ones (achievement, role, education, project) (#856) #858.Decision: extend the existing one-module-per-section convention. No new abstraction, no new design-system piece, no new panel — this moves code that already exists into the file layout its two siblings already use.
Implementation sketch
Extract each section into its own module under
src/components/features/, mirroringReconstructedRole.tsx:ExperienceSection(320 LOC) — the largest win, and the one whose extraction most clarifies the parent.ProjectsSection(143 LOC).AchievementsSection.Each takes the props it already receives today; the parent keeps the shared state and the
buildEntryGroupscall. Do them as separate commits (or separate PRs) so each diff is readable as a pure move — a move plus an edit in one diff is exactly what makes this kind of refactor expensive to review.Update the
CLAUDE.md"Known debt" line with the resulting LOC when done.Acceptance criteria
ExperienceSection,ProjectsSectionandAchievementsSectioneach live in their own module.ReconstructedResume.tsxis materially under its current 1489 LOC, and theReconstructedResumefunction is under the ~200 LOC guidance.corpus.test.ts,corpus-roundtrip.test.ts).fallowno longer reports these three functions over the LOC guidance.CLAUDE.md's "Known debt" LOC figures updated to the post-split reality.npm run verifygreen.Not in scope
SectionRewrite.tsx(607),ModelSelector.tsx(556),ReconstructedRole.tsx(490) — same debt class, separate issues.