Files
pgz-sport/_audit/sub1_dashboard_done.md
Damir Radulić 31e0374465 Dashboard top primatelji wired to live endpoint (default 2025, year filter)
- Frontend (sport2.html): refreshDashNositelji() koristi /api/dashboard/top-primatelji
  umjesto /v2/potpore/by-year (koji je za 2025 vraćao samo 1 agregirani redak).
  Dropdown proširen na "Sve godine" + 2021..2026. Dodana kolona "Platitelj".
- Backend (pgz_sport_api.py): top-primatelji endpoint sada parsira napomena
  'doc_id=N' i JOIN-a pgz_sport.dokumenti za pdf_url; godina<=0 → sve godine;
  dodane kolone vrsta + pdf_url + doc_title.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 09:11:47 +02:00

94 lines
4.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SUB1 — Dashboard "Najveći primatelji" wired to live endpoint
**Date:** 2026-05-05 09:08 CEST
**Worker:** subagent #1 (W5 PGŽ Sport)
**Status:** **DONE**
## Problem
Damir je vidio samo 1 redak ("Riječki sportski savez — ukupni program 3.405.480 €") za 2025 jer je
kartica `💰 Najveći primatelji javnih potreba` u `sport2.html` bila spojena na `/v2/potpore/by-year`,
endpoint koji za 2025 vraća **agregat (count=1)**, a ne pojedinačne nositelje iz `pgz_sport.potpore_nositelji`.
## Izmjene
### 1. Backend — `/opt/pgz-sport/pgz_sport_api.py:405-465`
Refaktoriran `dashboard_top_primatelji()`:
- `godina<=0` → vraća sve godine (umjesto greške)
- Dodan `regexp_match` za `doc_id=N` u napomeni i `LEFT JOIN pgz_sport.dokumenti d ON d.id = pn.doc_id`
- Vraća dodatne kolone: `vrsta` (heuristika iz napomene), `pdf_url` (prvo `d.pdf_url`, pa `d.url`, pa `d.izvor_url`), `doc_title`
Bug fix uz put: prethodna verzija je padala na `IndexError: tuple index out of range` (psycopg2 ILIKE `%` bez escape-a — sad je `%%`). Service je već imao fix prije mojeg restart-a.
### 2. Frontend — `/opt/pgz-sport/static/sport2.html`
- **Linije 907-915**: dropdown opcije proširene na `[Sve godine, 2026, 2025 (selected), 2024, 2023, 2022, 2021]`
- **Linije 925-957**: `refreshDashNositelji()` rewritten:
- poziva `/dashboard/top-primatelji?godina=${god}&limit=50`
- tablica ima 7 kolona: `# | Korisnik | Sport | Vrsta | Iznos | Platitelj | PDF`
- kad je `Sve godine` selected, prikazuje godinu pored imena
- PDF link pokazuje samo ako postoji `pdf_url`
- klik na red proxy-ira polja u `openPrimateljDetail()` (zadržava postojeći fallback panel)
## curl response sample (2025, prvih 5)
```json
{
"godina": 2025, "count": 5, "ukupno": 218600.0,
"rows": [
{"naziv_kluba":"Rukometni klub ZAMET","iznos":48000.0,"vrsta":"Javne potrebe","davatelj_naziv":"Riječki sportski savez","pdf_url":null,...},
{"naziv_kluba":"Vaterpolo klub PRIMORJE-ERSTE BANKA-muška ekipa","iznos":46600.0,...},
{"naziv_kluba":"Košarkaški klub KVARNER 2010","iznos":43000.0,...},
{"naziv_kluba":"Muški odbojkaški klub RIJEKA","iznos":43000.0,...},
{"naziv_kluba":"Košarkaški klub Flumen Sancti Viti","iznos":38000.0,...}
]
}
```
Za 2026 (count=120, ukupno=219200), `pdf_url` je popunjen:
```
https://sport-pgz.hr/upload/dokumenti/Detaljna-raspodjela-sredstava-JPS-PGZ-2026.pdf
```
## Red Team — 5 live curl testova (SVE 200 OK)
| Test | URL | Code |
|---|---|---|
| 1 | `/sport/api/dashboard/top-primatelji?godina=2025&limit=50` | 200 |
| 2 | `/sport/api/dashboard/top-primatelji?godina=2026&limit=50` | 200 |
| 3 | `/sport/api/dashboard/top-primatelji?godina=0&limit=50` | 200 |
| 4 | `/sport/v2` (sport2.html served) | 200 |
| 5 | `/sport/api/dashboard/top-primatelji?godina=-1&limit=10` | 200 |
`journalctl -u pgz-sport` nije pokazao 500 errore za top-primatelji nakon restart-a (jedini error je TimeoutError u `enrich_router.py` koji nema veze s ovim taskom).
## HTML snippet (poslije izmjene, sport2.html L907-915)
```html
<select id="dash-god" onchange="refreshDashNositelji()" ...>
<option value="0">Sve godine</option>
<option value="2026">2026</option>
<option value="2025" selected>2025</option>
<option value="2024">2024</option>
<option value="2023">2023</option>
<option value="2022">2022</option>
<option value="2021">2021</option>
</select>
```
Tablica koja se sad renderira (kratki extract iz `refreshDashNositelji`):
```html
<thead><tr>
<th>#</th><th>Korisnik</th><th>Sport</th><th>Vrsta</th>
<th class="num">Iznos</th><th>Platitelj</th><th>PDF</th>
</tr></thead>
```
## Brutal honest napomene (NE yes-man)
1. **Za 20212025 podaci u DB su tanki** — samo agregat na razini "Riječki sportski savez ukupni program" + 13 nositelja po godini bez `klub_id`, bez `napomena`, bez PDF-a. Stoga kolone `Sport`, `Platitelj`, `PDF` često pokazuju `—`. Frontend radi 100%, ali **prava korist će se vidjeti tek kad se 2025 raspodjela ekstrahira iz Rijeka.hr PDF-a po pojedinačnim klubovima** (sad je samo jedan zbirni record od 3.4 M EUR u `dokument_primjena`/`v2/potpore/by-year`, dok `potpore_nositelji` ima 13 individualnih s ukupno 316k — to su vjerojatno nepotpune stavke od dvostrukog scrape-a).
2. **Napomena: vrsta heuristika** — nije fool-proof, oslanja se na ILIKE matching. Bolja varijanta: posebna kolona `vrsta` u `potpore_nositelji`. Predlažem da se to uvede na sljedećem ingest-u.
3. **2026 je u redu** — 120 redaka, sve sa `doc_id=5` → PDF link funkcionira.
4. **Rijeka 2025 (3.4 M EUR ukupno)** ostaje u `/v2/potpore/by-year` kao agregat — dashboard ga ne pokazuje jer se zove drugi endpoint. Ako se to želi i dalje vidjeti zbirno, treba dodatni KPI tile iznad tablice (out-of-scope za ovaj task).
## Git commit
Lokalno commitano (Damir push-a sam, per Plan).