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

4.7 KiB
Raw Permalink Blame History

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)

{
  "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)

<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):

<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).