8.9 KiB
8.9 KiB
PGŽ SPORT — AUTONOMNI RUN — 29.04.2026 (Damir radio, Claude radio sam)
TL;DR
Sve glavne stavke gotove. Sustav radi end-to-end: login → korisnici CRUD → sportaš profil → HNS scraper → Qdrant embedding → cron jobs. Damir treba samo testirati u browseru i javiti što vizualno smeta.
ŠTO JE NAPRAVLJENO
Faza 1+2 — DB konsolidacija (gotovo prije današnjeg run-a)
userstablica canonical (19 FK),sys_usersmigrirana → 8 redakasys_*renamed →*_DEPRECATED_20260429- 9 korisnika postavljeno (default pwd
PgzSport2026!+must_change)
Faza 3+4 — Login UI + must_change_pwd
- Login modal s 2 taba (👤 Korisnik / 🔓 Admin token)
- "🔐 PRIJAVA" pill u sidebar footer
- must_change_pwd modal nakon prvog login-a
- Auto-401 redirect na svaki v2 endpoint
- Backend:
/auth/loginvraćamust_change_pwd, user_type, ime, prezime, klub_id, savez_id - Backend:
/auth/meenriched (klubovi[], savezi[], roles[]) - Backend:
/auth/change-password(s old_password verifikacijom osim u must_change flow-u) - Lockout zaštita: 5 failed → 15 min lock
Faza 5+6 — RBAC + admin user CRUD
get_current_userextended (user_type, klub_id, savez_id, aktivan)- RBAC helpers:
is_super,is_pgz_admin,can_manage_users,require_role tenant_filter_users(user)— pgz_: sve, savez_: scope na savez_id, klub_*: scope na klub_id- Endpoints:
/users/list, /users/create, /users/{id} PUT, /users/{id}/reset-password, /users/{id}/toggle-active, /users/{id}/unlock, /users/{id}/audit, /admin/audit, /admin/permissions-matrix, /admin/permissions/grant, /users/klub-link POST/DELETE, /admin/impersonate - Smoke: pgz_user (Marija) vidi svih 9, klub_admin bez klub_id → 0 (filter ispravan)
Faza 7 — Korisnici full CRUD UI (gotovo)
- Search + tip filter + Novi korisnik gumb
- Tablica: ID, email, ime+prezime, tip, klub/savez, status (aktivan/locked), failed_login_count, last_login, akcije
- Akcije: edit, reset pwd, toggle aktivan, unlock, impersonate (super_admin), audit
- Modal: create (s default pwd), edit (sve polja), reset-pwd (generira temp pwd, prikazuje u prompt)
- Audit viewer: globalni i per-user
Faza 8 — CSS unifikacija s app.rinet.one/klasik
- :root tokeni replikirani iz
/opt/rinet-v4/app/src/index.css(Palantir Gotham theme) - Master tokens: bg/bg2/bg3/bg4/bg5, border/border2/border3, text/text2/text3/text-bright/text-dim, accent/accent2/accent-glow, green/red/amber/cyan, sans (IBM Plex), mono (JetBrains), radius/radius-lg, chart1..4
- Legacy aliases:
--text-2 → --text,--bg-2 → --bg2,--gold → --amber,--r → --radius-lg, etc. - Master utility classes:
.ri-card, .ri-glass, .ri-tbl, .ri-btn(-primary,-ghost), .ri-kpi-value, .risk-{critical,high,medium,low} - Icons: Lucide-style stroke 1.5, opacity 0.7
Faza 9 — Sportaš profil (semafor.hns.family stil)
- Schema extension
pgz_sport.clanovi: slug, slika_url, source, source_id, source_url, source_synced_at, pozicija, dominantna_noga, visina_cm, tezina_kg, broj_dresa, reprezentativac, reprezentacija_kategorija, biografija, mjesto_rodenja - Nova tablica
pgz_sport.utakmice_log(per-igrač match log s pogocima/karticama/minutama) pgz_sport.kluboviextended: hns_klub_id, hns_slug, hrs_klub_id, hks_klub_id, hvs_klub_id, logo_url, web_stranica, source_synced_at- Nova tablica
pgz_sport.scraper_runs(run history s status/errors) pgz_sport.natjecanjaextended: source, source_id, source_url, pgz_relevant- Backend:
/api/v2/sportas/{cid}/profile(sportas + seasons + career + matches + totals) - Backend:
/api/v2/klub/{kid}/sportasi(roster po klubu) - Backend:
/api/v2/sportas/search?q= - Frontend:
pageSportas(semafor-style profile s photo/KPI/seasons/matches),pageKlubRoster - Helper:
gotoSportas(id),gotoKlubRoster(id)
Faza 10 — HNS Semafor scraper foundation
/opt/pgz-sport/scrapers/hns_semafor.py(10K7B)- Modes:
seed,klub,player <hns_pid>,daily - SEED_MAP: 16 PGŽ klubova → HNS COMET ID (NK Klana=1569, NK Krk=1558, NK Mune=1576, NK Vihor=4326, NK Doker=107415, HNK Kozala=3090, HNK Lovran=1574, HNK Goranin=1565, NK Risnjak=1583, NK Lokomotiva=1570, NK Omladinac Vrata=1579, NK Draga=1554, NK Zamet=1589, NK Vrbovsko=1588, NK Rikard Benčić=1582, NK OŠK Omišalj=3071)
- BeautifulSoup parser za /igraci/{id}/{slug}/
- Auto-create klub ako ne postoji u DB
- TEST: Marko Komadina (HNS#1167145) → clan_id=145 (Marko/Komadina/2012-10-14/Rijeka/photo OK/NK Klana)
- Rate limit: 1.6s između zahtjeva, ASCII UA
- TODO: roster discovery (match IDs → /utakmice/{id}/ → roster), ostali savezi (HRS/HKS/HVS)
Faza 11 — Qdrant embedding
/opt/pgz-sport/scrapers/embedder.py(7K3B)- Kolekcija
pgz_sport_v1(1024 dim, BGE-M3, Cosine) - Modes:
init,savezi,klubovi,sportasi,all - Stable ID: SHA1(prefix:src_id) → uint63
- Embedded: 220 savezi + 1637 klubovi + 47 sportaši (uključujući Komadina)
- Endpoint:
http://localhost:9879/api/embeddings(BGE-M3 CUDA)
Faza 12 — Cron jobs (autonomous learning)
/etc/cron.d/pgz-sport:0 4 * * *— daily HNS Semafor scrape17 * * * *— hourly embed klubovi refresh27 * * * *— hourly embed sportasi refresh30 3 * * 0— weekly embed savezi refresh0 2 * * 1— weekly log truncation
TOKEN ROTATION
- GitHub PAT obnovljen: spremljen u
/opt/.env.rinet(chmod 600) - Validan: dradulic - Damir Radulic
- Git credential helper konfiguriran globally
STANJE NAKON RUN-A
Servisi
pgz-sport.service— active (port 8095)- BGE-M3 embedder — active (port 9879, CUDA)
- Qdrant — active (port 6333)
- PostgreSQL — active (port 5432, PgBouncer 6432)
- Cron — active
Live URLs
- https://api.rinet.one/sport/ — frontend (211KB)
- https://api.rinet.one/sport/api/v2/auth/* — auth
- https://api.rinet.one/sport/api/v2/users/* — admin user mgmt
- https://api.rinet.one/sport/api/v2/sportas/* — sportaš profil
- https://api.rinet.one/sport/api/v2/klub/{id}/sportasi — roster
File locations
- Backend:
/opt/pgz-sport/pgz_sport_v2_router.py(56K),pgz_sport_api.py(1308 linija v1) - Frontend:
/opt/pgz-sport/static/index.html(~211KB) - Scrapers:
/opt/pgz-sport/scrapers/{hns_semafor.py, embedder.py} - Backups:
/opt/pgz-sport/_backups/(više backup-a po fazi) - Logs:
/opt/pgz-sport/_logs/{embedder.log, hns_scraper.log, hns_cron.log, embed_cron.log} - Handoff:
/opt/pgz-sport/_handoff/HANDOFF_*.md
ŠTO PREOSTAJE (TODO za sutra)
- HNS klub roster discovery — kroz match IDs (klub stranica daje match IDs → fetch /utakmice/{id}/ → extract roster). Trenutno
cmd_klubuhns_semafor.pyje placeholder. - HRS/HKS/HVS scrapers — slični semafor portali za rukomet/košarku/odbojku. Treba istražiti URL strukture.
- Klub fixes: tajnici 7+8 (Davor Šimunović, Tihomir Brnčić) nemaju
klub_idset. Treba ih povezati na njihove klubove (Kvarner i Zamet) za tenant filter da radi. - Frontend permissions matrix UI — backend endpoint postoji, frontend ne.
- Frontend klub-link UI — assignment korisnik↔klub kroz user_klub_links.
- Sportaš ručni unos — frontend forma za klubove da ručno upišu sportaše (već imaju /clanovi/create ali bez novih polja).
- HNS match log scrape — utakmice_log još nije popunjen za nikoga (ni za Komadinu — to bi povećalo profil dramatično).
- HEAD / 405 — cosmetics (root endpoint ne podržava HEAD, GET only).
TEHNIČKE KONSTANTE (uvijek valjane)
- Bridge:
curl -X POST https://api.rinet.one/bridge/exec -H "X-API-KEY: rinet-yS4ZnKlwUqsjk"(paramcmd) - DB: host=localhost port=5432 (direct) ili 6432 (PgBouncer), dbname=rinet_v3, user=rinet, pwd=
R1net2026!SecureDB#v7 - Embed:
http://localhost:9879/api/embeddings(BGE-M3, dim=1024) - Qdrant:
http://10.10.0.2:6333, kolekcijapgz_sport_v1 - Sport service: port 8095, systemd
pgz-sport.service
TEST SCENARIJ
- Otvori
https://api.rinet.one/sport/(hard refresh Ctrl+Shift+R) - Klik 🔐 PRIJAVA → email + pwd
- Default users (svi
PgzSport2026!):- pgz.djelatnik@pgz.hr (Marija, pgz_user)
- pgz.finance@pgz.hr (pgz_finance)
- tajnik.hnk@rijeka.hr (savez_admin)
- sportas.test@example.hr (klub_clan)
- Korisnici → vidi RBAC tenant filter na djelu
- Test sportaš:
/sport/api/v2/sportas/145/profile→ Marko Komadina - Test roster:
/sport/api/v2/klub/2200/sportasi→ NK Klana
KORISNIČKE LOZINKE STANJE (29.04.2026)
| id | pwd state | |
|---|---|---|
| 1 | damir@rinet.one | original (super_admin) |
| 2 | pgz.lukanovic@pgz.hr | Damir je promijenio tijekom testa |
| 3 | pgz.djelatnik@pgz.hr | default + must_change |
| 4 | pgz.finance@pgz.hr | default + must_change |
| 5 | zzjz.medical@zzjzpgz.hr | default + must_change |
| 6 | tajnik.hnk@rijeka.hr | default + must_change |
| 7 | tajnik.kvarner@kk.hr | default + must_change |
| 8 | tajnik.zamet@rk.hr | default + must_change |
| 9 | sportas.test@example.hr | default + must_change |