# CC4 Sub1 — FastAPI Endpoint Coverage Extension **Author:** cc4-sub1@rinet.one (Damir Radulić — dradulic@outlook.com / damir@rinet.one) **Date:** 2026-05-05 **Source audit:** `/opt/pgz-sport/_audit/audit_20260505_023639/errors.json` (57 errors / 80 pages) ## Audit-driven scope reduction The CC1 audit listed 57 errors. Filtering for genuine API gaps (`http_4xx_5xx` + console 404/405 referencing `/api/`): | Class | Count | Verdict | |---|---:|---| | `THREE.WebGLRenderer` console errors on `an_mreza` | 21 | Headless Chromium GPU sandbox issue, NOT API. Skipped. | | Three.js deprecation warnings | 16 | Frontend asset issue, NOT API. Skipped. | | `/static/uploads/avatars/99-68860ddb.png` 404 | 4 | Missing file, not endpoint. Avatar mount works (`/uploads/avatars/`). Frontend has stale hash. Skipped. | | `/static/erp.html` 502 | 1 | Tested live: returns 200. Transient 502 in audit — public path issue (`/sport/static/erp.html` returns 404 publicly because nginx maps `/static` differently). Not a Python-API gap. Skipped. | | `/sport/api/v2/img-proxy?u=...` 404 | 3 | Tested live (anon + auth) → 200. Already deployed (`routers/img_proxy_router.py`, mounted line 1431). Skipped. | After eliminating non-API noise, an **extended frontend-fetch sweep** (grep all `fetch(...)` calls in `/opt/pgz-sport/static/*.html`, then probe each with anon + JWT) surfaced these real API gaps: | Status | Path | Method | Notes | |---|---|---|---| | 404 | `/api/v2/klubovi` | GET | v2 alias missing; only legacy `/api/klubovi` existed | | 404 | `/api/v2/savezi` | GET | v2 alias missing; only legacy `/api/savezi` existed | | 404 | `/api/v2/sport` and `/api/v2/sport/` | GET | namespace index missing | | 500 | `/api/v2/kategorizirani/list` | GET | SQL bug: column alias used in WHERE clause | ## Endpoints added / fixed All changes in `/opt/pgz-sport/pgz_sport_v2_router.py` (no new router file — domain already existed). | Method | Path | File | Lines added | Auth | Audit log | |---|---|---|---:|---|---| | GET | `/api/v2/klubovi` | pgz_sport_v2_router.py | ~25 | optional (read-only) | n/a (read) | | GET | `/api/v2/savezi` | pgz_sport_v2_router.py | ~22 | optional (read-only) | n/a (read) | | GET | `/api/v2/sport` | pgz_sport_v2_router.py | ~12 | optional (read-only) | n/a (discovery) | | GET | `/api/v2/sport/` | pgz_sport_v2_router.py | (alias) | optional | n/a | | FIX | `/api/v2/kategorizirani/list` | pgz_sport_v2_router.py | -1/+1 | optional | n/a (read) | State-changing endpoints: **none added** (all gaps were read-only listings/aliases). No audit_log entries needed. ## Status matrix (smoke test, post-deploy) | Endpoint | anon | auth (JWT) | public via nginx | |---|---:|---:|---:| | `/api/v2/klubovi` | 200 | 200 | 200 | | `/api/v2/klubovi?q=` | 200 | 200 | — | | `/api/v2/savezi` | 200 | 200 | 200 | | `/api/v2/sport` | 200 | 200 | — | | `/api/v2/sport/` | 200 | 200 | — | | `/api/v2/kategorizirani/list` | 200 | 200 | — | All read-only — middleware allows anonymous GETs on `/api/v2/*` listings. ## Skipped (not API gaps) - `/static/uploads/avatars/99-68860ddb.png` — file missing on disk. Real avatar exists with hash `99-3a8466b0.png`. Frontend or DB has stale URL. Out of scope (data, not API). - `/static/erp.html` 502 — public infrastructure (nginx upstream) hiccup; locally returns 200. - `/sport/api/v2/img-proxy?u=...` — already implemented in `routers/img_proxy_router.py`, returns 200 with placeholder PNG when origin 404s. - THREE.WebGLRenderer console errors — headless Chrome GPU issue, not solvable on the API. - Three.js deprecation warnings — frontend asset upgrade, separate ticket. - Google Analytics / external CDN URLs — none seen in this audit. ## Per-domain commit | Domain | Commit | Files | |---|---|---| | v2 listings + sport namespace | _(pending git commit at end of run)_ | pgz_sport_v2_router.py | ## Backups - `/opt/pgz-sport/_backups/r3_cc4/pgz_sport_v2_router.py.bak.1777962063`