Files
pgz-sport/_audit/sub5_klubovi.md
T
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

146 lines
11 KiB
Markdown
Raw 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.
# 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.json``sub5b`.)
**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
```bash
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-umjetnicko` → `lovstvo`. 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.