Skip to content

Complete React migration with analysis tools and faster backend views - #129

Merged
gmalbert merged 3 commits into
mainfrom
codex/react-parity-enhancements
Oct 5, 2026
Merged

gmalbert merged 3 commits into
mainfrom
codex/react-parity-enhancements

Conversation

@gmalbert

@gmalbert gmalbert commented Oct 4, 2026 •

Copy link
Copy Markdown
Owner

The React migration needs the remaining native presentation work, faster raw-data responses, and the requested analysis tools. This PR completes that integration and makes driver comparison understandable: choosing George Russell, Kimi Antonelli and Esteban Ocon now shows their actual tire metrics and a chart containing those same three drivers, with the Grand Prix and year identified.

Resulting behavior

  • Native React renders the reference presentation protocol for the seven application sections, including original fields, number/date formatting, model panels, charts, filters, grid operations and CSV downloads. Years have no thousands separator, numbers use the same font as words, and the React favicon is included.
  • All 17 requested enhancements are integrated: contrast/focus/target sizes, compact responsive layout, visible table tools, loading/retry feedback and stale cancellation; named local views, safe share links, keyboard command palette, semantic HTML tables, driver comparisons and context/model-provenance exports; bounded caches, artifact invalidation, request diagnostics, separate research processes and body limits; responsive footer assets, enforced build budgets and production HTTP caching.
  • Driver comparisons are offered only for tables with useful metrics. Already summarized tire tables show their recorded degradation, compound, stint and lap values without a redundant “Sample rows: 1” column. Repeated race records retain descriptive means, known-record DNF rates and a Records included count. The race chart follows the selection; clearing or closing comparison restores the full field. Annual summaries retain the source Races count.
  • Named/shared/exported settings exclude uploads, ledgers, betting inputs, passwords and tokens. The obsolete hosted research warning is removed.
  • Precomputed prediction discovery includes position_group and track_weighted, matching the supported estimator choices.

Backend performance and hosting

Numeric table normalization now operates on columns, the view endpoint skips redundant framework conversion of normalized JSON, and gzip uses level 5. The recorded October 1 local benchmark reduced median raw-table response-header wait from 8.15 s to 1.98 s and completion time from 8.62 s to 2.53 s. All 4,629 rows × 561 columns and the complete table checksum matched. The compression tradeoff increased that measured transfer by approximately 5.3%. These are historical local measurements with warmed servers, not WAN or capacity guarantees.

Client/server response reuse is bounded and short-lived; eligible artifact changes invalidate source, presentation and response caches. Requests carry IDs and timing headers, with a bounded diagnostic history that excludes bodies, queries and credentials. Research jobs use an explicit queue and separate spawned process, bounded inputs/results and source revision checks.

The bundled DNF diagnostic snapshot is refreshed for the latest main analysis dataset (4,651 probabilities). It is generated offline by the existing reference logistic-regression algorithm; the runtime keeps validating its dataset checksum and does not retrain it on page loads. Refresh this snapshot when publishing a changed analysis dataset.

Footer WebP variants reduce the image from 1,127,638 bytes to 4,938/15,096 bytes. The production build enforces a 500,000-byte initial JavaScript gzip budget; this build uses 231,146 bytes. Nginx compresses text, caches hashed assets immutably, revalidates HTML and gives API responses no-store. CI runs the build-budget and actual container HTTP-header checks.

Behavior changes and operating limits

  • Public React betting exposes Value & stake only. Upload-based Field simulation, Paper replay and Calibration UI workflows and their compatibility HTTP endpoints are removed. The offline research functions and their calculation tests remain. This narrows public exposure relative to the original parity snapshot.
  • Requests default to 1 MiB, bounded before JSON parsing and by Nginx. Change both backend and proxy limits together if a different policy is needed.
  • start-local.ps1 enables token-free research/diagnostics only for direct trusted loopback requests with local Host/Origin checks and no forwarded-header trust. Hosted mode and Docker keep this off and require administrator credentials. Calculations start only after Queue calculation.
  • The local job queue requires one API worker, loses state on restart, and permits cancellation only while queued. Multiple workers need an external shared queue/store. Cache revisions use paths, sizes and mtimes; publish changed artifacts atomically.
  • Lazy Plotly/Vega chunks remain large and the build retains their nonfatal warnings. No production deployment or merge is performed by this PR.

Validation

Check Result
Backend pytest 125 passed, 90.50% coverage
Backend Ruff / strict mypy Passed
Python compilation All 22 application sources passed
Frontend Vitest 98 passed
ESLint / TypeScript Passed
Production build / budget Passed; 231,146 / 500,000 initial gzip bytes
Production dependency audit 0 vulnerabilities
Main-app Playwright regression 16 flows passed, 0 unexpected errors
Live tire-comparison Playwright 4 checks passed, 0 unexpected errors; real metric values, matching selected chart, restoration, annual counts and mobile layout

The local/hosted research acceptance reports and Nginx header/production-browser evidence are also included. Research lifecycle browser checks use controlled fixtures and do not train real models. Pytest uses a fresh workspace temporary directory on Windows to avoid the locked shared pytest directory.

Review guide and evidence

Benchmark captures retain timing/byte/count values. Repeated inline image URLs are represented by media type, original character count and SHA-256; recomputing the summary after compaction produced a byte-for-byte identical result. Earlier visual snapshots and proposals are historical evidence; the current enhancement guide and acceptance reports describe the final behavior.

Three selected drivers with real tire metrics and matching chart

CI regression correction

The backend parity test now derives its expected row count from the current source dataset and compares every year/Grand Prix/driver entry. This fixes the failure caused by the dataset growing from 4,629 to 4,651 rows without weakening the displayed-column or seven-model-panel checks. The corrected full backend suite passes all 125 tests with 90.50% coverage; Ruff and strict mypy pass.

Greg Albert added 3 commits October 4, 2026 00:16
## Implementation

- Add a request-isolated FastAPI presentation protocol and checked-in offline
  exports of the original Python views, chart helpers and DNF diagnostics.
  Runtime page rendering does not import or start Streamlit.
- Render all seven application sections and their nested panels in React,
  preserving the original calculations, six model selections, visible fields,
  table column order (including duplicates), formatting and chart behavior.
- Match typography, branding, spacing, sidebar filters, responsive navigation,
  themes, metrics, uploads and downloads. Add the native data grid controls for
  search, sorting, column visibility, selection, copying and fullscreen views.
- Preserve model metadata and feature order, isolate request state, return
  private cached copies and serialize Matplotlib rendering. Keep research
  training disabled and experiments explicitly triggered by their controls.
- Repair the shared temporal-leakage audit callable and reproduce the narrow
  Glide header bounds fix during dependency installation.
- Include parity tests, reproducible comparison scripts, final screenshots,
  comparison reports and updated implementation/handoff documentation.

## Validation

- Python compilation passed for 23 files; backend lint and strict typing passed.
- Backend: 59 tests passed, with 87.36% coverage.
- Frontend: 57 tests passed, with 73.74% line coverage; lint, type checking and
  the production build passed. Production dependency audit found no issues.
- Original Streamlit comparisons: 77 table/model cases and four filtered-data
  cases passed. Both live CSV comparisons matched the reference fields/values.
- All 24 desktop, tablet and mobile visual comparisons passed the existing
  tolerances. Playwright interaction, experiment and capture reports recorded
  zero browser errors.
- Staged changes passed the whitespace check before committing.

## Evidence scope

Validation was performed locally against the running Streamlit, React and
FastAPI applications. The visual checks retain the original tolerances and
reference color-contrast findings; the mobile Raw Data capture leaves its
expensive display checkbox unchecked. These results do not establish a
production deployment or current GitHub PR/CI status.

Existing workflow, pre-commit configuration and prediction-generator edits,
along with older visual runs and transient inspection output, are excluded
from this commit.
## User-facing changes

- Finish native React rendering of the Streamlit presentation, preserving original fields, formatting, table operations, charts, filters, exports and model panels.
- Add named local views, safe share links, keyboard section search, semantic tables, context/provenance export and explicit research job controls.
- Compare actual tire strategy metrics for up to four selected drivers and filter the adjacent chart to the same selection. Identify race/year and retain real annual race counts.
- Improve focus, contrast, target sizes, compact spacing, table tools, loading/retry feedback and cancellation. Keep years ungrouped, use matching numeric/text fonts, add the favicon and remove the obsolete hosted-mode warning.

## Backend and deployment

- Normalize raw numeric table columns efficiently, avoid redundant FastAPI conversion and use gzip level 5. Recorded local header wait fell from 8.15 s to 1.98 s with unchanged raw table checksums.
- Add bounded response reuse, request deduplication, artifact invalidation, request IDs/timing and bounded diagnostics.
- Run explicit administrator research in a separate process. Trusted loopback mode removes the local token requirement; hosted authentication remains enabled by default.
- Enforce a 1 MiB aggregate body limit before JSON parsing and in Nginx. Public React betting exposes Value & stake; upload-based simulation/replay/calibration endpoints are removed, while offline functions remain.
- Generate responsive footer assets and enforce an initial JavaScript budget plus production caching checks in CI. Include position_group and track_weighted in precomputed prediction model discovery.

## Documentation and verification

- Include performance reports, enhancement proposals, full implementation snapshots, screenshots and reproducible acceptance scripts.
- Refresh the bundled offline DNF diagnostic probabilities for the current main dataset; retain the original logistic-regression diagnostic algorithm and source checksum validation.
- Compact repeated inline image URLs in benchmark evidence while retaining their hashes, original lengths and unchanged measurements.
- Backend: 125 tests pass, 90.50% coverage, Ruff and strict mypy pass.
- Frontend: 98 tests pass; lint, type check, production build and production dependency audit pass. Initial JavaScript is 231,146 gzip bytes, below the 500,000-byte budget.
- All 22 Python application sources compile. The 16 main Playwright flows and four tire-comparison checks report zero unexpected errors.
## Problem

The backend CI job expected a historical 4,629-row dataset. The current main dataset contains 4,651 race entries, so the presentation integration test failed despite returning the complete current data.

## Fix

- Derive the expected default-filter row count from the current joined source table instead of freezing a historical dataset size.
- Require a nonempty source and compare the complete multiset of year, Grand Prix and driver identities. This catches missing, duplicated or substituted race entries even when counts match.
- Preserve the 34 displayed-column contract, repeated positionsGained check and all seven model-panel assertions. Application rendering and dataset contents are unchanged.

## Validation

- Full backend suite: 125 passed, 90.50% application coverage.
- Ruff and strict mypy passed.
- Confirmed the only failed PR job was the obsolete fixed-row-count assertion; the other existing checks passed.
@gmalbert
gmalbert merged commit fded412 into main Oct 5, 2026
9 checks 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