Files
pgz-sport/_audit/sub5_klubovi.md
damir 8e136351f9 CRISIS FIX: login flow + mobile responsive + token expiry handling
ROOT CAUSE ISOLATED:
Backend POST /api/auth/login, GET/PUT /api/auth/me, POST avatar, POST /logout
all return 200 OK (verified curl). Damirov problem is browser-side:
stale localStorage tokens that don't match current backend → 401 cascade
→ avatar upload appears as 'failed: 401' → profile changes 'lost'.

FIXES:
1. apiAuth() in app.html now:
   - Pre-checks JWT exp claim before request
   - On 401 response: clears localStorage (pgz_access/refresh/user) +
     redirects to /login?reason=unauthorized
   - On JWT expired: redirects to /login?reason=expired

2. login.html displays toast for ?reason=expired/unauthorized

3. Mobile responsive CSS (max-width: 768px):
   - app.html: hamburger menu, sidebar slide-in, full-width drill-down panel
   - sport2.html: KPI grid 2-col, klubovi 1-col, tables horizontal scroll
   - Both: viewport meta + media queries + touch-friendly buttons

4. Mobile menu toggle button + backdrop overlay added

VERIFIED E2E (curl):
- POST /auth/login → 200 + JWT
- GET /auth/me → 200 + telefon persisted
- PUT /auth/me → 200, DB row updated
- POST /auth/me/avatar → 200, file saved + avatar_url returned
- POST /auth/logout → 200, token revoked (next /me returns 401)
2026-05-05 09:14:46 +02:00

11 KiB
Raw Permalink Blame History

SUB5 — Klubovi data quality (PGŽ Sport)

Run date: 2026-05-05 Operator: W5 (CC subagent #5) Scope: 5a adresa-as-naziv, 5b KUD verify, 5c RSS cross-check DB: rinet_v3.pgz_sport.klubovi (2244 rows) Detail JSON: /opt/pgz-sport/_audit/sub5_klubovi/sub5_run.json

TL;DR

  • 5a: Brief navodi "27 klubova", actual count je 13 (čisti garbage naziv = address/URL/email/heading). Flagani u napomena, postavljeni aktivan=false. Naziv NIJE mijenjan (confidence < 0.9 — bolje fail-safe nego pogrešno preimenovati).
  • 5b: MAJOR FINDING — sva 49 redova s sport='kulturno-umjetnicko' su LOVAČKA DRUŠTVA, ne KUD-ovi. Wholesale misclassification. Reclassified to sport='lovstvo'.
  • 5c: PARTIAL-BLOCKED. rss-rijeka.hr i zssr-pgz.hr ne resolve-aju. sport-pgz.hr/clanice-zajednice lista samo PGŽ-saveze, NE individualne klubove. NSPGZ.hr glasniks su PDF (potreban OCR). Cross-check klubova not feasible autonomno.

5a — Adresa-as-naziv klubovi (13 redova)

Action: Naziv NIJE preimenovan ni za jedan red (confidence < 0.9 za sve). Umjesto toga:

  • Dodan prefix u napomena: sub5a_2026-05-05: TODO_FIX_NAME — naziv looks like {kind}; original="..."
  • aktivan = false postavljen (ovi nisu real-klubovi nego import-junk).
ID Original naziv Kind Sport Suggestion (low conf, NOT applied) Action
2611 VIDEO Seminar za trenere/ice seniorskih liga Opatija 2025 heading/event kosarka flagged + aktivan=false
2614 www.zok-rijeka.hr url odbojka OK [VERIFY-from-URL-zok-rijeka] flagged + aktivan=false
2617 http://www.beachvolley-opatija.com/ url odbojka OK [VERIFY-from-URL-beachvolley-opatija] flagged + aktivan=false
2621 www.mok-rijeka.hr url odbojka OK [VERIFY-from-URL-mok-rijeka] flagged + aktivan=false
2627 Ante Kovačića 21, 51 000 Rijeka address odbojka OK [VERIFY-RIJEKA] flagged + aktivan=false
2635 Ćirila Kosovela 3, 51 000 Rijeka address odbojka OK [VERIFY-RIJEKA] flagged + aktivan=false
2639 www.zaokskurinjerijeka.hr url odbojka OK [VERIFY-from-URL-zaokskurinjerijeka] flagged + aktivan=false
2642 zok.crikvenica@gmail.com email odbojka flagged + aktivan=false
2645 Omladinska 10, 51 550 Mali Lošinj address odbojka OK [VERIFY-MALI LOŠINJ] flagged + aktivan=false
2646 Braće Horvatića 6, 51 000 Rijeka address odbojka OK [VERIFY-RIJEKA] flagged + aktivan=false
2647 www.plivackiklub-rijeka.hr url plivanje PK [VERIFY-from-URL-plivackiklub-rijeka] flagged + aktivan=false
2648 Ždrijeb i satnica za 10.Opatija Open heading/event stolni tenis flagged + aktivan=false
2649 Propozicije za 41.Međunarodni Kup Grada Rijeke heading/event stolni tenis flagged + aktivan=false

Razlozi za "13 ≠ 27":

  • Prethodni cleanup (/opt/pgz-sport/data_cleanup_report.md, 2026-05-05 ranije danas) već je popravio 14 odbojkaških klubova s adresom u nazivu (ID 2613, 2616, 2618…2632, 2641…). Vidi tablicu u tom file-u.
  • 4 koja su ostala nepopravljena (2627, 2635, 2645, 2646) + 7 dodatnih koja su URL/email/heading garbage = 13 total danas.
  • 27 originalna procjena vjerojatno uključuje i naslove tipa "Vukovar '91" ili "Slavija Trsat (1920s)" — to su povijesni klubovi, ne adresa-junk.

Susjedni klubovi (kontekst za buduće manualno renaming):

  • ID 2620 i 2628 ne postoje (gap u sekvenci → već obrisani).
  • ID 2618 = "Muški Odbojkaški Klub Gornja Vežica" → adresa Ante Kovačića 21 (id 2627) vjerojatno pripada njemu. TODO: spojiti.
  • ID 2643 = "Ženski Odbojkaški Klub Drenova Rijeka" → adresa Braće Horvatića 6 (id 2646) je njegova. TODO: spojiti.
  • ID 2644 = "ŽOK LOŠINJ" → Omladinska 10, Mali Lošinj (id 2645) je njegova adresa. TODO: spojiti.

5b — KUD verify (49 rows ALL reclassified)

MAJOR FINDING: Niti jedan od 49 redova s sport='kulturno-umjetnicko' nije zapravo KUD. SVA 49 su LOVAČKA DRUŠTVA (hunting clubs). Ovo je wholesale klasifikacijska greška iz ranijeg scrape-a — netko je vjerojatno mappao kategoriju "lov" na "kulturno-umjetničko" greškom (ili default fallback).

Provjera: SELECT * FROM pgz_sport.klubovi WHERE sport='kulturno-umjetnicko' AND naziv NOT ILIKE '%lova%'0 redova.

Action: Svih 49 reclassified u sport='lovstvo', dodan trail u napomena: sub5b_2026-05-05: bio sport=kulturno-umjetnicko, vraćen na lovstvo (LD prefix detected)

Random sample 10 (od 49) — svi corrected:

ID Naziv Sport prije Sport poslije Razlog
1650 LOVAČKO DRUŠTVO ZA UZGOJ, ZAŠTITU I LOV DIVLJAČI "TUHOBIĆ" KRASICA kulturno-umjetnicko lovstvo LD prefix
1693 LOVAČKO DRUŠTVO "SRNDAĆ" BROD MORAVICE kulturno-umjetnicko lovstvo LD prefix
1736 LOVAČKO DRUŠTVO "VEPAR" BRIBIR kulturno-umjetnicko lovstvo LD prefix
1900 LOVAČKO DRUŠTVO "FAZAN" DOBRINJ kulturno-umjetnicko lovstvo LD prefix
1975 LOVAČKO DRUŠTVO "TETRIJEB" ČABAR kulturno-umjetnicko lovstvo LD prefix
2052 HRVATSKO LOVAČKO DRUŠTVO "ZEC" KLANA kulturno-umjetnicko lovstvo LD prefix
2133 LOVAČKO DRUŠTVO "ŠLJUKA 1924" OMIŠALJ kulturno-umjetnicko lovstvo LD prefix
2218 Lovačko društvo "KOBAC 1960" Lovran kulturno-umjetnicko lovstvo LD prefix
2222 Lovačko društvo "MEDVIĐAK" Drivenik Tribalj kulturno-umjetnicko lovstvo LD prefix
2226 Lovačko društvo "OTOK RAB" Rab kulturno-umjetnicko lovstvo LD prefix

(Punu listu vidi u sub5_run.jsonsub5b.)

Bonus issues identified (NOT auto-fixed — require Damir):

  • Ova lovačka društva su mapirana na pogrešne savezi: savez_id=11 (Odbojkaški savez PGŽ), savez_id=14 (Rukometni savez PGŽ), savez_id=32 (Savez školskih sportskih društava PGŽ), ili NULL.
  • Trebala bi biti vezana na Lovački savez PGŽ — ali takav nije u pgz_sport.savezi. Postoji samo id=149: HRVATSKI LOVAČKI SAVEZ (national) i id=142: HRVATSKI KINOLOŠKI SAVEZ.
  • Recommendation: insertati novi savez "Lovački savez PGŽ" (slug u upravo: HLS-PGŽ) ili attach-ati sve na id=149 privremeno.
  • Da li lovstvo uopće pripada u sportski registar? Strogo gledano NE (po Zakonu o sportu RH). Možda treba odluka: ostaviti u pgz_sport.klubovi s sport='lovstvo'+aktivan=false ili premjestiti u zaseban schema.

5c — RSS membership cross-check (PARTIAL-BLOCKED)

Source URL Status Type # članova found # naših flagged Note
https://rss-rijeka.hr/clanovi DNS fail / unreachable RSS Rijeka 0 0 Domain ne resolve-a.
https://www.zssr-pgz.hr DNS fail / unreachable ŽSSR PGŽ 0 0 Domain ne resolve-a.
https://sport-pgz.hr/clanice-zajednice 200 OK ZSPGZ savezi 30 0 Lista samo SAVEZE, NE individualne klubove.
https://www.nspgz.hr 200 OK Nogometni savez PGŽ 0 0 Glasniks su PDF; potreban OCR + parser.

Indirect findings:

  • sport-pgz.hr/rijecki-sportski-savez → info-page Riječkog sportskog saveza, lista 30 saveza-članova (Atletski PGŽ, Boćarski PGŽ, … Vaterpolo PGŽ). NIJE lista klubova-članova.
  • sport-pgz.hr/odbojkaski-savez-pgz (i drugi savez-pages) → mail+predsjednik+oib ali nikakva lista klubova-članova.
  • Iz savez-stranica može se izvući OIB i kontakt podaci za savez sam, što je već dijelom u pgz_sport.savezi.

Statistical flag: 755 aktivnih klubova ima savez_id IS NULL`` — nije RSS-derived ali signalizira da je 33% klubova nema dodjeljen savez. To je orthogonal data-quality problem, ali isti smjer (cross-check / dopuna).

Konkretni updates (5c) na klubovi: Niti jedan red flagovan u napomena od strane 5c — nemam authoritative listu članstva da odluku donesem.


Audit log

redis-cli LPUSH cc:pgz-sport:cleanup "2026-05-05T08:50:00+02:00 sub5 klubovi 5a=13 5b_corrected=49 5c_flagged=0_partial_blocked"

(Pokrenuto na kraju run-a — vidi log key cc:pgz-sport:cleanup.)


Šta je riješeno autonomno

  1. 5a: 13 garbage-naziv klubova flagano u napomeni s TODO_FIX_NAME markerom + postavljen aktivan=false. Originali sačuvani u napomena. NEMA destruktivnih promjena (nikakvog renaming-a).
  2. 5b: 49 lovačkih društava reclassified iz kulturno-umjetnickolovstvo. Trail u napomena.
  3. 5b sample verifikacija: Ne treba — 100% lova-prefix match-ova, nema KUD-ova u toj kategoriji (provjereno SQL-om).
  4. 5c probe: Sve 4 plausible URL-e probano, dokumentirano u tablici i u sub5_run.json.
  5. Audit: JSON detalja + ovaj .md + Redis log entry.

Šta treba Damir ručno

  1. 5a — Manual rename + merge (high prio):
    • id 2627 (Ante Kovačića 21, 51 000 Rijeka) vjerojatno belongs to id 2618 (Muški Odbojkaški Klub "Gornja Vežica"). Verify + merge addresa u 2618.adresa, obrisati 2627.
    • id 2645 (Omladinska 10, 51 550 Mali Lošinj) → adresa od id 2644 (ŽOK LOŠINJ). Merge.
    • id 2646 (Braće Horvatića 6, 51 000 Rijeka) → adresa od id 2643 (ŽOK Drenova). Merge.
    • id 2635 (Ćirila Kosovela 3, 51 000 Rijeka) → ne pripada nijednom postojećem ZOK-u s preglednim mapping-om. Manual research.
    • id 2614, 2617, 2621, 2639, 2647 (URL-ovi) → premjestiti URL u web_stranica susjednog klub-reda + obrisati.
    • id 2642 (email) → premjestiti u email od id 2641 (ŽOK Crikvenica).
    • id 2611, 2648, 2649 → ovo nisu klubovi nego pages naslova s natjecanja. Predlagano: hard-delete (s archive-om u _audit/).
  2. 5b — Strukturna popravka:
    • Dodati savez "Lovački savez PGŽ" u pgz_sport.savezi (ili odlučiti da lovstvo nije in-scope za pgz-sport ERP).
    • Reattach 49 lovačkih društava na taj savez (ili na nacionalni id=149). Trenutno su 4 distinct savez_id-a od kojih su 3 pogrešna.
    • Decide: ostaje li lovstvo u klubovi ili u zaseban schema/tablicu?
  3. 5c — Cross-check ručno (deferred):
    • 755 klubova bez savez_id treba probit po sport+grad protiv individualnih savez-websiteova (nspgz.hr glasnik PDF parsing, kspgz.hr, …). To je big-ass project; ne mogu autonomno.
    • Eventualno: zatražiti od ZSPGZ-a (info@sport-pgz.hr) machine-readable popis klubova-članova svih 30 saveza.

Brutal honesty

  • Ne tvrdim da je flagging-only za 5a "fix" — to je defenzivna mjera. Pravi fix zahtjeva merge-anje (manual) ili dodatni pass s cross-reference protiv sjediste+adresa polja drugih klubova istog sporta — ali to bi moglo dvostruko mappirati i napraviti gubitak. Bolje da Damir to verifikira.
  • 5b je možda prevelik aglomerat: ako je politika ZSPGZ-a "lovstvo nije sport", ovih 49 redova trebalo bi se izbaciti iz pgz_sport.klubovi u zaseban pgz_sport.lovacka_drustva. Ostavio sam ih u klubovi jer su tamo bili.
  • 5c je svjesno delegiran natrag — autonomno scrape-anje 30+ savez-websiteova u jednom run-u nije realno (ni vremenski ni rate-limit-om), a neki nisu javni. Bolje vremenski budgetirati.