Skip to content

Refactor duplicated web page scaffolding before adding more analytics pages #44

Description

@Mattsface

Goal

Reduce the repeated web-layer scaffolding that has accumulated across the team analytics pages before adding another major visualization page.

The intent is to remove mechanical duplication while keeping baseball-specific analytics explicit and readable.

Why

The same page lifecycle is now repeated across Hits, Batting Strikeouts, Runs, Baserunners, Pitching, Run Differential, Comparison, and related views:

parse team / season / window
→ load available team-seasons
→ build selector context
→ handle empty database
→ resolve selected team
→ handle missing team
→ resolve selected season
→ handle missing season
→ rebuild navigation
→ load persisted records
→ run metric-specific analytics
→ build chart
→ build summary cards
→ render template

The chart builders also repeat a large amount of common Plotly setup, including raw-game traces, rolling-average traces, reference lines, axis configuration, ticks, margins, legends, and annotations.

Several Pydantic analytics models additionally repeat identical consistency validators such as:

  • prior-window fields must either both be present or both be absent
  • summary game count must match point count

This was manageable when the app had only a few pages. With 6–7 similar pages and Player analytics planned, continuing to copy the same scaffolding will make changes harder to review and easier to apply inconsistently.

Scope

Routes

Extract small shared helpers for genuinely mechanical behavior such as:

  • loading available team-seasons
  • resolving team / season selections
  • common base template context
  • empty and not-found handling
  • navigation/query-parameter preservation

Keep route-specific analytics, missing-data behavior, league gating, and explanatory copy explicit.

Do not turn every metric into a configuration-driven generic route.

Charts

Identify the common structure used by standard per-game count charts and extract focused helpers for things such as:

  • raw observation trace
  • rolling-average trace
  • season / MLB reference lines
  • standard x-axis ticks
  • shared Plotly layout and legend configuration

Keep genuinely different charts separate. In particular, normalized comparison, run differential, and pitching/rate-specific behavior should not be forced into an abstraction that obscures their semantics.

Schemas / validators

Consolidate identical validation logic with small reusable helpers or narrowly-scoped base behavior where it improves readability.

Do not collapse Hits, Strikeouts, Runs, Baserunners, Pitching, etc. into one generic analytics model. Their baseball semantics should remain explicit.

Design constraints

  • Prefer small helper functions over a generic metric framework
  • Preserve thin routes
  • Preserve pure analytics modules
  • Preserve DB-only browser requests
  • Preserve server-rendered FastAPI/Jinja
  • Preserve local Plotly rendering
  • Preserve current URLs and shareable query parameters
  • Preserve all current empty, missing-data, coverage, and 409 re-import behavior
  • Do not change statistical formulas or interpretation
  • Do not change persistence or ingestion behavior as part of this issue unless a tiny supporting refactor is unavoidable

Testing

Existing behavior must remain unchanged.

Cover at minimum:

  • Hits route regression
  • Strikeouts route regression
  • Runs route regression
  • Baserunners route regression
  • Pitching route regression
  • Run Differential route regression
  • Comparison route regression
  • empty database behavior
  • missing team / season behavior
  • missing-data re-import states
  • COMPLETE league-coverage gating
  • query-parameter preservation
  • chart trace names and reference lines
  • /health
  • zero MLB API calls during browser rendering

Completion

  • Common web-page plumbing is shared rather than copied across each metric route
  • Standard count charts reuse a small, readable common chart foundation
  • Repeated consistency validation is consolidated where appropriate
  • Baseball-specific analytics remain explicit
  • No generic metric framework or premature frontend architecture is introduced
  • Existing tests remain green and behavior is unchanged
  • Adding another straightforward team metric no longer requires copying an entire route and Plotly layout block

Context

This addresses duplication called out during the review of #38 and observed again as later analytics pages were added. PR #42 already consolidated duplicated batting/pitching upsert and game-log helper logic; this issue intentionally focuses on the remaining web-layer and analytics-schema duplication.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions