Reports in _audit/:
audit_FRONTEND_COVERAGE.md — SA-1 (Explore): 9 HTML files, 0 orphan handlers (clean)
audit_API_GAP.md — SA-2 (Explore): 356 backend routes vs 54 frontend paths
23 missing routes / 39 call sites
audit_DB_INTEGRITY.md — SA-3 (general-purpose): 8 SQL probes, FKs/NULLs clean,
48 dup-OIB clusters, 518 low-cov klubovi
audit_CONSOLIDATED.md — top 10 critical with owner matrix (cc1/cc4/cc5/cc6)
Headlines:
Frontend: clean (post-R3 refactors landed)
API gap: CRM module systemic — 16 of 23 missing routes need /crm prefix in crm.html
6 missing routes are trailing-slash bugs in crm.html
DB: 48 OIB dup clusters in klubovi (~100 rows) need merge+unique-index
518/2244 klubovi (23%) <33% coverage → enrichment_worker target list
14 scoreboard-string klubovi rows (RK ... HRL Zapad od X) → DELETE
~30 backup tables (~97k rows) cluttering pgz_sport schema
Owner allocation:
cc1 → #6 backup-table archival, #8 verify, #9 sportas trailing-slash
cc4 → #1 OIB dedup script, #4 scoreboard DELETE, #10 schema CHECKs
cc5 → #2 /crm prefix sweep on crm.html, #3 trailing-slash sweep, #7 notif endpoint
cc6 → #5 enrichment_worker batch on filled<4 klubovi
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5.2 KiB
CC1 Consolidated Audit — 3 subagents
Generated: 2026-05-05T08:30:00Z Source reports:
_audit/audit_FRONTEND_COVERAGE.md(SA-1, 9 files scanned, 0 issues)_audit/audit_API_GAP.md(SA-2, 23 missing routes / 39 call sites)_audit/audit_DB_INTEGRITY.md(SA-3, 48 dup-OIB clusters, 518 low-coverage klubovi)
Executive summary
| Area | Verdict | Headline finding |
|---|---|---|
| Frontend coverage | CLEAN | 200+ onclick handlers, 9 forms, 8 modals, 28 tabs all wired correctly. No orphans. |
| API gap | NEEDS WORK | 23 unique missing routes (39 call sites). Two systemic patterns: trailing slashes (6) and missing /crm prefix (16). |
| DB integrity | NEEDS WORK | FKs/NULLs/audit-chain clean. 48 duplicate-OIB clusters in klubovi (~100 rows). 518/2244 klubovi (23%) have <33% coverage. |
TOP 10 critical (sorted by user-impact + fix-ease)
1. Klubovi 48 duplicate-OIB clusters (DB)
Impact: confuses joins, breaks unique business identity. Fix: run a dedup_klubovi_by_oib.py --dry-run then merge children (clanovi.klub_id, klub_sezona.klub_id, hns_klubovi_natjecanje.klub_id) onto the row with highest coverage and DELETE the duplicates. Then CREATE UNIQUE INDEX CONCURRENTLY klubovi_oib_unique_valid ON klubovi(oib) WHERE oib ~ '^[0-9]{11}$'. — owner: cc4 (DB)
2. CRM frontend missing /crm prefix on 16 endpoints (API)
Impact: crm.html buttons silently fail. Fix: in static/crm.html, change api('/clanarine/...') → api('/crm/clanarine/...') (and lijecnicki, forms, notifications, email-templates, zzjz). — owner: cc5 (CRM)
3. CRM forms 5 trailing-slash 404s (API)
Impact: form submissions fail. Fix: in crm.html L1039/1087/1126/1135/1144 strip trailing / from /forms/submissions/${sid} and /forms/${code}. — owner: cc5 (CRM)
4. 14 scoreboard-string klubovi rows (DB)
Impact: garbage in klubovi.naziv (e.g. RK ... N. u II HRL Zapad od X strings). Fix: DELETE FROM pgz_sport.klubovi WHERE naziv ~ '\d+\. u (I{1,3}|IV) HRL .* od \d+' (verify COUNT first). — owner: cc4 (DB)
5. 518 klubovi <33% coverage (DB)
Impact: worst panel UX, low-info entities. Fix: python3 scripts/enrichment_worker.py --filter "filled<4" --limit 100 --concurrency 4 (existing CC6 module). — owner: cc6 (enrich)
6. ~30 backup tables in pgz_sport schema (DB hygiene)
Impact: ~97k rows of stale data, accidental queries against snapshots. Fix: pg_dump --schema-only snapshot then DROP TABLE each *_backup_*/*_premerge_*/*_pre_*/*_dedup_*. Move to pgz_sport_archive schema if cold storage preferred. — owner: cc1/dba
7. /api/notifications/{nid}/read trailing slash (API)
Impact: mark-as-read buttons fail. Fix: crm.html:L1652 POST URL — strip trailing /, full path /crm/notifications/{nid}/read. — owner: cc5 (CRM)
8. 3 [VERIFY]/[UNRESOLVED] klubovi (DB)
Impact: placeholder names visible in UI. Fix: ids 2619, 2630, 4426 already flagged metadata->>'manual_review'='true'. Surface them in /audit UI for triage; or hard-link via Sportilus / sport-pgz manual lookup. — owner: cc1/cc6
9. /api/sportas/{id}/profil — frontend trailing slash (API)
Impact: sport2.html openSportas may 404 in some code paths. Fix: verify static/sport2.html doesn't construct URL with extra /; backend route is /api/sportas/{id}/profil (no trailing slash). — owner: cc1
10. ALTER TABLE constraints to prevent regression (DB)
Impact: prevents future garbage. Fix: add CHECK (naziv = btrim(regexp_replace(naziv, '\s+', ' ', 'g'))) on klubovi/clanovi naziv columns; add unique index on klubovi.oib; document sys_audit retention (7d → 30d?). — owner: cc4
Owner allocation matrix
| CC | Tasks |
|---|---|
| cc1 (orchestrator) | #6 backup-table cleanup, #8/9 verify, #10 schema constraints PR review |
| cc4 (DB/ERP) | #1 OIB dedup, #4 scoreboard-string DELETE, #10 DDL |
| cc5 (CRM) | #2 /crm prefix sweep on crm.html, #3 trailing-slash sweep, #7 notifications |
| cc6 (enrichment) | #5 enrichment_worker batch, possibly co-own #8 |
Reports verbatim
- Read full SA-1 detail:
_audit/audit_FRONTEND_COVERAGE.md - Read full SA-2 detail:
_audit/audit_API_GAP.md(each missing path with file:line + suggested fix) - Read full SA-3 detail:
_audit/audit_DB_INTEGRITY.md(each query + result + fix SQL)
Methodology
- SA-1 walked every
<button>,<form>,onclick=, modal id, tab pattern across 9 HTML files. 0 orphans found — confirms the post-Round-3+ refactors landed cleanly. - SA-2 diff'd
openapi.json(356 routes) against grep offetch|api|apiAuth|apiPost(...)calls in static/. Normalised paths to FastAPI templates before matching. - SA-3 ran 8 read-only SQL probes (counts, NULLs, FKs, dup OIBs, placeholders, low-coverage, junk imports, audit health) — no DB writes performed.
What's already healthy (don't refactor)
- ✅ Audit-chain (sys_audit row_hash + chain_idx) intact for all 100+ entries
- ✅ FK integrity: no orphan klub_id / savez_id / user_id
- ✅ Frontend onclick handlers all defined (post-R3 cleanup)
- ✅ Mreža 3D graph centering on PGŽ savez (R6 verified)
- ✅ JOSIP ZEC test case 257/182/15 still passing (verified earlier)