CC1: 3-subagent deep audit — Frontend / API gap / DB integrity
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>
This commit is contained in:
@@ -0,0 +1,183 @@
|
||||
# SA-2 API Gap Analysis
|
||||
|
||||
**Generated:** 2026-05-05T06:25:39.772966Z
|
||||
**Backend routes:** 356
|
||||
**Frontend unique paths:** 54
|
||||
**Missing or misconfigured (frontend calls without correct backend):** 23
|
||||
|
||||
## MISSING ROUTES
|
||||
|
||||
### Routes with Trailing Slashes (6 issues)
|
||||
|
||||
#### `GET /api/forms/`
|
||||
- Called from: `static/crm.html:L957`
|
||||
- Actual call: `api('/forms/' + code)`
|
||||
- Method: GET
|
||||
- Backend equivalent: `/api/crm/forms/{code_or_id}`
|
||||
- Fix: Remove trailing slash, add `/crm` prefix. Frontend should call `/crm/forms/{code}` (API base is `/sport/api/crm`)
|
||||
|
||||
#### `GET|POST /api/forms/submissions/`
|
||||
- Called from: `static/crm.html:L1039`, `static/crm.html:L1087`, `static/crm.html:L1126`, `static/crm.html:L1135`, `static/crm.html:L1144`
|
||||
- Method: GET/POST (mixed)
|
||||
- Backend equivalent: `/api/crm/forms/submissions/{sid}`
|
||||
- Fix: Remove trailing slash when accessing specific submission by ID
|
||||
|
||||
#### `POST /api/notifications/`
|
||||
- Called from: `static/crm.html:L1652`
|
||||
- Method: POST
|
||||
- Backend equivalent: `/api/crm/notifications/{nid}/read`
|
||||
- Fix: Remove trailing slash, use full path `/crm/notifications/{nid}/read`
|
||||
|
||||
#### `GET /api/sportas/`
|
||||
- Called from: `static/sport2.html:L1582`, `static/sport2_new.html:L907`
|
||||
- Method: GET
|
||||
- Backend equivalent: `/api/sportas/{clan_id}/profil`
|
||||
- Fix: Remove trailing slash, include full path `/sportas/{clan_id}/profil`
|
||||
|
||||
#### `POST /api/v2/enrich/`
|
||||
- Called from: `static/sport2.html:L376`
|
||||
- Actual call: `await apiPost('/v2/enrich/'+kind+'/'+id)`
|
||||
- Method: POST
|
||||
- Backend equivalent: `/api/v2/enrich/{kind}/{eid}/apply`
|
||||
- Fix: Append `/apply` to complete the route (e.g., `/v2/enrich/klub/{eid}/apply`)
|
||||
|
||||
#### `POST /api/v2/forensic/findings/`
|
||||
- Called from: `static/sport2.html:L2873`
|
||||
- Actual call: `await apiPost('/v2/forensic/findings/'+findingId+'/enrich')`
|
||||
- Method: POST
|
||||
- Backend equivalent: `/api/v2/forensic/findings/{finding_id}/enrich`
|
||||
- Fix: Parameter name in backend is `finding_id`, ensure frontend passes correct ID
|
||||
|
||||
### Routes Missing /crm Prefix (16 issues)
|
||||
|
||||
#### `GET|POST /api/clanarine/`
|
||||
- Called from: `static/crm.html:L503`, `static/crm.html:L571`
|
||||
- Method: GET/POST (mixed)
|
||||
- Correct path: `/api/crm/clanarine` (no trailing slash)
|
||||
- Fix: Add `/crm` to path; frontend base is `/sport/api/crm` so call `/clanarine` instead of `/clanarine/`
|
||||
|
||||
#### `POST /api/clanarine/bulk/notify`
|
||||
- Called from: `static/crm.html:L417`
|
||||
- Method: POST
|
||||
- Correct path: `/api/crm/clanarine/bulk/notify`
|
||||
- Fix: Add `/crm` prefix; frontend base is `/sport/api/crm` so call `/clanarine/bulk/notify`
|
||||
|
||||
#### `POST /api/clanarine/bulk/uplatnice`
|
||||
- Called from: `static/crm.html:L456`
|
||||
- Method: POST
|
||||
- Correct path: `/api/crm/clanarine/bulk/uplatnice`
|
||||
- Fix: Add `/crm` prefix
|
||||
|
||||
#### `POST /api/clanarine/notify-bulk`
|
||||
- Called from: `static/crm.html:L631`
|
||||
- Method: POST
|
||||
- Correct path: `/api/crm/clanarine/notify-bulk`
|
||||
- Fix: Add `/crm` prefix
|
||||
|
||||
#### `GET|POST /api/email-templates`
|
||||
- Called from: `static/crm.html:L1675`, `static/crm.html:L1824`
|
||||
- Method: GET/POST (mixed)
|
||||
- Correct path: `/api/crm/email-templates`
|
||||
- Fix: Add `/crm` prefix
|
||||
|
||||
#### `GET /api/forms`
|
||||
- Called from: `static/crm.html:L900`, `static/crm.html:L1846`
|
||||
- Method: GET
|
||||
- Correct path: `/api/crm/forms`
|
||||
- Fix: Add `/crm` prefix
|
||||
|
||||
#### `GET|POST /api/forms/submissions`
|
||||
- Called from: `static/crm.html:L901`, `static/crm.html:L1035`, `static/crm.html:L1053`
|
||||
- Method: GET/POST (mixed)
|
||||
- Correct path: `/api/crm/forms/submissions`
|
||||
- Fix: Add `/crm` prefix
|
||||
|
||||
#### `GET /api/klubovi/`
|
||||
- Called from: `static/app.html:L508`, `static/sport2.html:L1294`, `static/sport2_new.html:L702`
|
||||
- Method: GET
|
||||
- Correct path: `/api/klubovi` (no trailing slash)
|
||||
- Fix: Remove trailing slash (frontend base is `/sport/api` so path becomes `/sport/api/klubovi` → `/api/klubovi` after nginx rewrite)
|
||||
|
||||
#### `GET|POST /api/lijecnicki/`
|
||||
- Called from: `static/crm.html:L794`, `static/crm.html:L808`
|
||||
- Method: GET/POST (mixed)
|
||||
- Correct path: `/api/crm/lijecnicki` (no trailing slash)
|
||||
- Fix: Add `/crm` prefix, remove trailing slash
|
||||
|
||||
#### `POST /api/lijecnicki/notify-scan`
|
||||
- Called from: `static/crm.html:L1644`
|
||||
- Method: POST
|
||||
- Correct path: `/api/crm/lijecnicki/notify-scan`
|
||||
- Fix: Add `/crm` prefix
|
||||
|
||||
#### `GET /api/notifications`
|
||||
- Called from: `static/crm.html:L1591`, `static/crm.html:L1848`
|
||||
- Method: GET
|
||||
- Correct path: `/api/crm/notifications`
|
||||
- Fix: Add `/crm` prefix
|
||||
|
||||
#### `POST /api/notifications/mark-all-read`
|
||||
- Called from: `static/crm.html:L1661`
|
||||
- Method: POST
|
||||
- Correct path: `/api/crm/notifications/mark-all-read`
|
||||
- Fix: Add `/crm` prefix
|
||||
|
||||
#### `GET /api/savezi/`
|
||||
- Called from: `static/app.html:L488`, `static/sport2.html:L1146`, `static/sport2_new.html:L558`
|
||||
- Method: GET
|
||||
- Correct path: `/api/savezi` (no trailing slash)
|
||||
- Fix: Remove trailing slash (frontend base is `/sport/api` so path becomes `/sport/api/savezi` → `/api/savezi` after nginx rewrite)
|
||||
|
||||
#### `GET /api/stats`
|
||||
- Called from: `static/crm.html:L1517`
|
||||
- Method: GET
|
||||
- Correct path: `/api/crm/stats`
|
||||
- Fix: Add `/crm` prefix
|
||||
|
||||
#### `GET /api/zzjz/info`
|
||||
- Called from: `static/crm.html:L721`
|
||||
- Method: GET
|
||||
- Correct path: `/api/crm/zzjz/info`
|
||||
- Fix: Add `/crm` prefix
|
||||
|
||||
#### `GET /api/zzjz/termini`
|
||||
- Called from: `static/crm.html:L722`
|
||||
- Method: GET
|
||||
- Correct path: `/api/crm/zzjz/termini`
|
||||
- Fix: Add `/crm` prefix
|
||||
|
||||
### Parameter Mismatch (1 issue)
|
||||
|
||||
#### `POST /api/crm/notifications/{nid}/read`
|
||||
- Called from: `static/app.html:L1310`
|
||||
- Issue: Frontend passes `{n.id}` but backend expects `{nid}`
|
||||
- Fix: Update template variable in frontend to match backend parameter name, or update backend to accept `id` instead of `nid`
|
||||
|
||||
## SUMMARY TABLE
|
||||
|
||||
| Category | Count |
|
||||
|---|---:|
|
||||
| Total unique frontend paths checked | 54 |
|
||||
| Successfully matched to backend | 31 |
|
||||
| Missing routes with issues | 23 |
|
||||
| - Trailing slash issues | 6 |
|
||||
| - Missing /crm prefix | 16 |
|
||||
| - Parameter mismatches | 1 |
|
||||
| **Total call locations with problems** | **39** |
|
||||
|
||||
## ROOT CAUSE ANALYSIS
|
||||
|
||||
1. **Trailing slashes:** Frontend code constructs paths dynamically using template variables (e.g., `/api/forms/` + code), but leaves trailing slash in base path
|
||||
2. **Missing /crm prefix:** CRM module endpoints require `/crm/` prefix in API path, but some frontend files are calling the base `/api/` version instead of going through the CRM submodule
|
||||
3. **Parameter name mismatch:** Template variable names in frontend don't match backend parameter names (e.g., `{n.id}` vs `{nid}`)
|
||||
|
||||
## RECOMMENDATIONS
|
||||
|
||||
1. Audit all `api()`, `apiAuth()`, and `apiPost()` calls in frontend to ensure correct base paths and prefixes
|
||||
2. Review nginx rewrite rules to confirm `/sport/api/crm/*` → `/api/crm/*` mapping
|
||||
3. Add linting rule or static analysis to catch trailing slashes in API calls
|
||||
4. Document API path conventions for each HTML file (which use `/api`, `/sport/api`, `/sport/api/crm`, etc.)
|
||||
5. Consider normalizing frontend API call helpers to automatically handle path prefixes consistently
|
||||
|
||||
---
|
||||
**Generated by SA-2 API Gap Analysis Agent**
|
||||
Reference in New Issue
Block a user