UI Audit Report — SoccerPredictAI¶
Date: 2026-04-28
Auditor: GitHub Copilot (Claude Opus 4.7) — /skill-ml-system-audit full (audit 09/12)
Scope: Streamlit UI — structure, API integration, error handling
Baseline: docs/validation/20260424/09_ui_audit.md
Delta vs baseline¶
src/ui/app/main.py, src/ui/app/api_client.py, and src/ui/app/pages/ unchanged since 2026-04-26 (only src/ui/app/api_client.py is in the modified set, but no edits since the previous audit run). Baseline findings remain in force.
Confirmed structure¶
- Single page:
main.py(Livescores).pages/directory is empty. APIClientexposes onlyget_livescores(year, month)andget_health()(latter unused in UI). No client methods for any/predict/*endpoint.- Retry policy:
total=2,backoff_factor=0.3,status_forcelist=[500, 502, 503, 504]. - Caching:
@st.cache_resourcefor client singleton,@st.cache_data(ttl=30)for livescores data — correct split. - Status labels: 8 codes with emoji; codes 4 and 5 mapped to "Unknown" (semantics unclear).
Risk register (re-confirmed)¶
| ID | Severity | Description | Status |
|---|---|---|---|
| UI-01 | P0 | pages/ empty — no prediction UI, no model-info page |
Open |
| UI-02 | P1 | APIClient lacks methods for /predict/* endpoints |
Open |
| UI-03 | P2 | Auth token sent as query param ?token=... (leaks to URL/logs) |
Open |
| UI-04 | P2 | get_health() exists but unused — no health indicator in UI |
Open |
| UI-05 | P3 | Status codes 4, 5 mapped to "Unknown" without documentation | Open |
Summary¶
| Aspect | Status |
|---|---|
| Livescores page (filters, refresh, error handling, empty state) | ✅ |
| API retry / timeout policy | ✅ |
| Streamlit caching split | ✅ |
| Prediction surfacing in UI | ❌ (UI-01, UI-02) |
| Auth via header only | ❌ (UI-03) |
Recommendation: The product-level value of the system (predictions) is currently invisible to end users via the UI. Address UI-01 + UI-02 together (extend APIClient, add a Prediction page using GET /predict/{match_id} and POST /predict/async/).
See baseline §1–§3 for code-level detail.