Skip to content

refactor(app): decompose SpecTabs into feature folder#8564

Merged
MarkusNeusinger merged 8 commits into
mainfrom
refactor/frontend-spectabs-split
Jun 10, 2026
Merged

refactor(app): decompose SpecTabs into feature folder#8564
MarkusNeusinger merged 8 commits into
mainfrom
refactor/frontend-spectabs-split

Conversation

@MarkusNeusinger

Copy link
Copy Markdown
Owner

Summary

Part 9 of the frontend modernization roadmap. Pure decomposition of the 961-line SpecTabs.tsx into sections/spec-detail/SpecTabs/ — no behavior change, import path (and SpecPage's lazy usage) unchanged.

  • index.tsx (420): tab orchestration — tab/tag-count state, fetch, tag chips, handleTagClick
  • CodeTab.tsx (88): code display + copy-to-clipboard (owns copied state; tracking + aria preserved verbatim)
  • SpecTab.tsx (89), ImplTab.tsx (139), QualityTab.tsx (229 — expansion state stays lifted in the parent, as before)
  • md.tsx: presentational markdown components (TabPanel, MdHeading, MdListItem) — components-only so react-refresh stays warning-free
  • utils.tsx: pure helpers (parseInlineCode, formatDate, tag param maps) + the module-level tag-count cache behind getter/setter (lifetime semantics preserved)
  • Existing SpecTabs.test.tsx moved unchanged (git rename, 22 tests); +4 per-tab test files

Tests: 552 → 572 (+20).

Verification

yarn lint ✓ (no new warnings) · yarn fm:check ✓ · yarn type-check ✓ · yarn test 572/572 ✓ · yarn build

🤖 Generated with Claude Code

- Split the 961-line SpecTabs.tsx monolith into src/sections/spec-detail/SpecTabs/
  with index.tsx (tabs orchestration, tag-count state, tag chip rendering),
  CodeTab.tsx, SpecTab.tsx, ImplTab.tsx, QualityTab.tsx, and utils.tsx
- utils.tsx keeps the module-level tag-count cache (via getter/setter to preserve
  its once-per-session lifetime), Md helpers, parseInlineCode, TabPanel,
  formatDate, and the tag→URL-param maps
- QualityTab expansion state stays lifted in index.tsx (as before) and is passed
  down as expandedCategories/onToggleCategory props; copy state moved with the
  copy button into CodeTab
- No behavior change: all trackEvent calls, aria attributes, and interactions
  preserved verbatim; existing SpecTabs.test.tsx moved into the folder unchanged
- Add focused per-tab tests for the now prop-driven surfaces (QualityTab
  expansion contract, CodeTab copy/tracking, ImplTab date fallback, SpecTab
  inline-code rendering): 60→64 test files, 552→572 tests

Part 9 of the frontend modernization roadmap.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 10, 2026 01:21
@codecov

codecov Bot commented Jun 10, 2026

Copy link
Copy Markdown

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors the Spec detail UI by decomposing the previously large SpecTabs.tsx component into a dedicated feature folder (app/src/sections/spec-detail/SpecTabs/) while keeping the public import surface (src/sections/spec-detail/SpecTabs) intact for the rest of the app.

Changes:

  • Splits SpecTabs into smaller tab-focused components (CodeTab, SpecTab, ImplTab, QualityTab) plus shared presentation/helpers (md.tsx, utils.tsx).
  • Moves/expands frontend tests to cover the decomposed components and keeps the integration-style SpecTabs.test.tsx in the new location.
  • Removes the old monolithic app/src/sections/spec-detail/SpecTabs.tsx.

Reviewed changes

Copilot reviewed 12 out of 13 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
app/src/sections/spec-detail/SpecTabs/index.tsx New SpecTabs orchestrator (tab state, tag rendering, tag count fetch/cache).
app/src/sections/spec-detail/SpecTabs/CodeTab.tsx Extracted code display + clipboard copy behavior.
app/src/sections/spec-detail/SpecTabs/SpecTab.tsx Extracted specification content rendering.
app/src/sections/spec-detail/SpecTabs/ImplTab.tsx Extracted implementation review content + metadata line.
app/src/sections/spec-detail/SpecTabs/QualityTab.tsx Extracted quality score + criteria breakdown UI.
app/src/sections/spec-detail/SpecTabs/md.tsx Shared presentational components (TabPanel, headings, list items).
app/src/sections/spec-detail/SpecTabs/utils.tsx Shared helpers + module-level tag-count cache getter/setter.
app/src/sections/spec-detail/SpecTabs/SpecTabs.test.tsx Moved SpecTabs tests to new folder location.
app/src/sections/spec-detail/SpecTabs/CodeTab.test.tsx Added unit tests for CodeTab.
app/src/sections/spec-detail/SpecTabs/SpecTab.test.tsx Added unit tests for SpecTab.
app/src/sections/spec-detail/SpecTabs/ImplTab.test.tsx Added unit tests for ImplTab.
app/src/sections/spec-detail/SpecTabs/QualityTab.test.tsx Added unit tests for QualityTab.
app/src/sections/spec-detail/SpecTabs.tsx Deleted monolithic implementation (replaced by feature folder).

Comment thread app/src/sections/spec-detail/SpecTabs/QualityTab.tsx
)}

{/* No data message */}
{!qualityScore && (!criteriaChecklist || Object.keys(criteriaChecklist).length === 0) && (

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied — the no-data guard checks qualityScore === null now.

Comment thread app/src/sections/spec-detail/SpecTabs/index.tsx Outdated
export function TabPanel({ children, value, index }: TabPanelProps) {
const isOpen = value === index;
return (
<Collapse in={isOpen}>

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skipping intentionally: always-mounted Collapse children is the original SpecTabs behavior moved verbatim — CodeTab's copied state lifetime and the lazy CodeHighlighter prefetch both rely on it. Changing mount semantics is a behavior change out of scope for this decomposition PR.

Comment on lines +77 to +87
<Box
onClick={() => items.length > 0 && onToggleCategory(category)}
sx={{
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
mb: 0.5,
cursor: items.length > 0 ? 'pointer' : 'default',
'&:hover': items.length > 0 ? { opacity: 0.8 } : {},
}}
>

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied — header is a ButtonBase with aria-expanded; item-less categories are disabled. (Pre-existing issue, fixed here as a separate labeled commit.)

MarkusNeusinger and others added 2 commits June 10, 2026 03:52
… criteria headers

Copilot review findings on the SpecTabs decomposition (pre-existing behavior
moved verbatim, fixed in a separate commit to keep the decomposition pure):
- qualityScore truthiness misclassified a legitimate score of 0 as missing
  (N/A display, no-data guard, Quality tab label) — explicit null checks now
- QualityTab category headers were clickable plain divs; now MUI ButtonBase
  with aria-expanded and disabled state for item-less categories

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 10, 2026 02:12
@MarkusNeusinger MarkusNeusinger enabled auto-merge (squash) June 10, 2026 02:12

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 14 changed files in this pull request and generated 1 comment.

overviewMode = false,
highlightedTags = [],
}: SpecTabsProps) {
// In overview mode, start with Spec tab open; in detail mode, all collapsed
Copilot AI review requested due to automatic review settings June 10, 2026 02:26
@MarkusNeusinger MarkusNeusinger review requested due to automatic review settings June 10, 2026 02:26
Copilot AI review requested due to automatic review settings June 10, 2026 02:28
@MarkusNeusinger MarkusNeusinger review requested due to automatic review settings June 10, 2026 02:28
@MarkusNeusinger MarkusNeusinger merged commit c145a6b into main Jun 10, 2026
7 checks passed
@MarkusNeusinger MarkusNeusinger deleted the refactor/frontend-spectabs-split branch June 10, 2026 02:40
MarkusNeusinger added a commit that referenced this pull request Jun 10, 2026
…tion (#8596)

## Summary

Part 11 (final) of the frontend modernization roadmap.

- **`app/ARCHITECTURE.md`**: directory layout
(routes/layouts/pages/sections/components/hooks/lib/theme), conventions
(`src/` alias imports, `paths.*` URL registry, `lib/api` client, theme
tokens, feature folders), data flow, testing pattern, quality gates, and
how-to-add recipes for pages/sections/hooks/endpoints
- **`agentic/docs/project-guide.md`**: frontend section now lists the
full gate (`lint`, `fm:check`, `type-check` incl. tests, `test`),
mentions the dev-time checker overlay, and links the new architecture
doc

With this, the roadmap is complete: tooling baseline (#8519), src/
aliases (#8520), theme split (#8525), global-config (#8529), API client
(#8531), routes registry (#8546), structure split (#8547), FilterBar
(#8559), SpecTabs (#8564), MapPage hook (#8581).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants