Skip to content

Organize Team analytics navigation - #54

Merged
Mattsface merged 2 commits into
mainfrom
issue-30-ui-architecture
Sep 25, 2026
Merged

Mattsface merged 2 commits into
mainfrom
issue-30-ui-architecture

Conversation

@Mattsface

Copy link
Copy Markdown
Member

Summary

Implements the first focused UI-architecture slice of #30.

  • separates primary/domain navigation from Team metric navigation
  • groups Team analytics under Offense, Pitching, and Results
  • keeps all existing Team URLs canonical and unchanged
  • preserves team_id, season, and window across navigation
  • keeps Players hidden until a real Player destination exists
  • adds a Team-specific template layer without introducing a generic analytics framework
  • adds a skip link and clearer navigation semantics
  • documents the adopted UI information architecture
  • strengthens navigation tests around semantic landmarks, active state, query preservation, and recovery states

Navigation

Offense

  • Hits
  • Batting Strikeouts
  • Runs Scored
  • Baserunners
  • Hits vs Batting Strikeouts

Pitching

  • Pitching Trends
  • Hits Allowed

Results

  • Run Differential

Compatibility

No route migration is included.

Existing URLs remain:

/
/strikeouts
/runs
/baserunners
/pitching
/hits-allowed
/run-differential
/comparison

Existing selector behavior, error states, completeness semantics, and DB-only browser rendering are preserved.

Scope intentionally excluded

  • Player UI
  • /teams/* URL migration
  • selector refactors
  • analytics changes
  • chart changes
  • persistence or ingestion changes
  • generic frontend/navigation frameworks

Closes part of #30.

@Mattsface

Copy link
Copy Markdown
Member Author

@claude please review

@claude

claude Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

Claude finished @Mattsface's task in 5m 49s —— View job


Review

  • Gather context (AGENTS.md, diff, changed files)
  • Understand request (code review requested)
  • Review navigation/template changes
  • Review CSS changes
  • Review test changes
  • Check CI status (could not run tests/lint locally — see note below)
  • Post final review

This is a clean, well-scoped slice of #30. It sticks to the stated boundaries (no route migration, no analytics/chart changes, Player nav left out until there's a real destination), and the architecture fits AGENTS.md: navigation.py stays a plain typed builder, presentation logic stays in app/web/templates, and no generic "framework" was introduced for a two-group taxonomy.

Strengths

  • app/web/navigation.py:41 adds group: Literal["Offense", "Pitching", "Results"] to NavLink instead of a bare str — keeps the domain typed per the type-safety rules, and a typo in a group name would be a type error, not a silent no-op in the template.
  • team_base.html cleanly separates the entity-neutral shell (base.html) from the Team-specific scaffold, which sets up a Player shell later without copying Team assumptions — matches the "small focused modules" guidance.
  • build_nav_links (app/web/navigation.py:44) always returns all 8 links regardless of team_id/season, so team_base.html's nav_links[0].href (used for the "Teams" primary-nav link) can never index into an empty list — checked both the "empty"/"not_found" and schema-missing paths in routes.py:1040-1168, and only error.html (which uses default base.html, no Team context) skips the Team nav entirely.
  • Test coverage is a real strength here: tests/test_web_page_scaffolding.py's new NavigationParser (an HTMLParser subclass) replaces a regex-based nav scraper and asserts on landmark labels, aria-current semantics, group headings, skip-link target, and main id — a meaningfully stronger contract than counting substring matches. The new test_reimport_states_keep_team_navigation case also protects the 409 conflict path, which is easy to regress silently.
  • Relabeling ("Runs" → "Runs Scored", "Comparison" → "Hits vs Batting Strikeouts") is consistently propagated through navigation.py, all dependent templates, and every test that asserted on the old label text — nothing was left referencing the stale strings (confirmed via grep).
  • docs/ui-information-architecture.md documents the actual design decision (why Comparison is grouped under Offense, why Players stays hidden, the shell/team_base split) rather than restating the visible markup — in the spirit of the "why over what" documentation guidance.

Minor observations (non-blocking)

  • _team_navigation.html:3 hardcodes the group order/list ("Offense", "Pitching", "Results") separately from the Literal in navigation.py:41. Small duplication, but if a fourth group is ever added, both places need updating in lockstep — worth a one-line comment noting the coupling, or leave as-is since three static groups is unlikely to churn (AGENTS.md's "small amount of obvious duplication over premature abstraction" guidance applies fine here).
  • The aria-current="location" value on the "Teams" primary-nav link (team_base.html:5) is a valid ARIA 1.1 token but less common than page/true; worth a quick screen-reader spot check since it's new to this codebase, but the semantics (a link to the current section, not the current document) are correctly chosen over aria-current="page".
  • _team_navigation.html and team_base.html are new small template files rather than one file — consistent with "module ownership" guidance (nav markup owns navigation, the scaffold owns layout), not a concern.

Not verified

I was not able to run poetry run pytest, ruff check, or ruff format --check in this sandbox (the tool approval for poetry run … was declined). CI's Test workflow run (36147456910) reports success for this branch, which covers the test-suite requirement; formatting/linting should still be double-checked with poetry run ruff check . and poetry run ruff format --check . before merge if those aren't part of that same CI job.

No functional or architectural issues found. Nice, disciplined slice.

@Mattsface
Mattsface merged commit 9ecd377 into main Sep 25, 2026
1 check passed
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.

1 participant