3e5b98a935
Sub1 (commit eb1b49f): 4 v2 listing/discovery endpoints + SQL fix
Sub2: CRM 4 modula PASS (M7 članarine, M8 liječnički, M9 obrasci, dokumenti partial)
Sub3: ERP 4 modula GREEN — racuni/putni/placanja/xlsx, E2E demo flow (7 steps) PASS
Critical fix this commit:
- erp/audit_helper.py (centralni helper za audit_log writer)
- routers/clanarine_router.py: audit hook na POST /clanarine
- routers/lijecnicki_router.py: audit hook na POST /lijecnicki
- routers/obrasci_router.py: audit hook na POST /submissions + /submit
Verify: prije 0 / poslije 1 audit entry za POST /api/crm/clanarine
"33|create|api|clan=4946 klub=2320 300.0€"
Outstanding (next round):
- /api/v2/dokumenti plain route shadowing with RAG
- /api/v2/dokumenti/upload missing
- SQL alias bug u pgz_sport_v2_router.py:3099
Reports:
_audit/audit_CC4_FINAL.md (konsolidirani)
_audit/audit_CRM_VERIFIED.md
_audit/audit_ERP_VERIFIED.md
_audit/audit_ENDPOINTS_ADDED.md
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
74 lines
3.9 KiB
Markdown
74 lines
3.9 KiB
Markdown
# 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 + kategorizirani fix | `eb1b49f` | pgz_sport_v2_router.py |
|
|
|
|
Pushed to `gitea/master` (4fc8327..eb1b49f).
|
|
|
|
## Backups
|
|
|
|
- `/opt/pgz-sport/_backups/r3_cc4/pgz_sport_v2_router.py.bak.1777962063`
|