# PGŽ SPORT INTELLIGENCE PLATFORM — MASTER HANDOFF ## Data: 2026-05-05 02:15 CEST ## Status: Predprezentacijska sprint, prezentacija županu jutros --- ## 🎯 MISIJA Multi-tenant ERP/CRM platforma za PGŽ Odjel za sport + savezi + klubovi. Rok: **danas ujutro** prezentacija županu Lukanoviću. Cilj: pretvoriti prikaz podataka u **operativni alat** koji rješava 80% birokratskih poslova. --- ## 🏗 INFRASTRUKTURA ### GPU server (jedini produkcijski) - **Host**: 144.76.68.5 (Hetzner GEX44, RTX 4000 Ada 20GB) - **SSH**: `ssh -p 5852 root@144.76.68.5` (pwd `5852Dan1TR5852`) - **Bridge API**: `POST https://api.rinet.one/bridge/exec` Header `X-API-KEY: rinet-yS4ZnKlwUqsjk` ### Stack - **PostgreSQL 18**: 10.10.0.2:6432 / `rinet_v3` / user `rinet` / pwd `R1net2026!SecureDB#v7` - **Schema**: `pgz_sport.*` (klubovi, savezi, clanovi, users, sys_audit, ...) - **Service**: `systemctl restart pgz-sport` (FastAPI port 8095) - **Live URL**: https://sport.rinet.one/ - **API base**: `/sport/api/...` (nginx strip prefix → :8095) ### Repo - **Git**: https://git.rinet.one/damir/pgz-sport (Gitea local) - **Local dir**: /opt/pgz-sport/ (HOME=/root, safe.directory=/opt/pgz-sport) - **Branch**: master - **Auto-push**: agenti rade `git push gitea master` nakon svakog commita ### Sve URL-ove (svi rade 200) | URL | Što | |-----|-----| | `/` | Public portal (sport2.html) | | `/login` | Login forma | | `/app` | Operativna aplikacija (po roli) | | `/admin` | Admin panel | | `/admin/users` | User management | | `/crm` | CRM workspace | | `/erp` | ERP (OCR, putni nalozi) | | `/audit` | Blockchain audit log | | `/kpi` | KPI dashboard | | `/static/*` | Static fileserve mount | | `/sport/api/*` | API endpoints | --- ## 🤖 CC SWARM — 6 PARALELNIH AGENATA ### Aktivne tmux sesije ``` cc1: a22bbe34-7801-4560-991b-219f77818711 Round 2+3B + orchestrator cc2: c8cf6289-33d9-4195-97f5-834cf0844cf3 Auth, GDPR, multi-tenant cc3: 3123d6b5-59fd-4864-a9d7-2fcca6e70f1c Frontend, sidebar, dashboard cc4: 69b5473b-4033-4872-b50c-94080e737d64 ERP, OCR, putni nalozi cc5: a966a143-8821-4827-9cb5-9594477def9a CRM, članarine, ZZJZ, obrasci cc6: 9e120f23-a3e0-4580-b84f-704b87671037 Blockchain, enrichment, worker ``` ### Pokretanje CC u tmux ```bash ssh -p 5852 root@144.76.68.5 tmux new-session -d -s ccN tmux send-keys -t ccN:0 "su - claude" Enter sleep 2 tmux send-keys -t ccN:0 "cd /opt/pgz-sport && unset ANTHROPIC_API_KEY && claude --resume UUID --dangerously-skip-permissions" Enter sleep 5 tmux send-keys -t ccN:0 Enter # confirm trust prompt ``` ### Monitoring ```bash bash /opt/pgz-sport/swarm.sh tiled # 6 panela u jednom prozoru bash /opt/pgz-sport/swarm.sh status # 1x snapshot bash /opt/pgz-sport/swarm.sh git # commit history bash /opt/pgz-sport/swarm.sh ccN # attach na specifični agent ``` ### Slanje zadataka — ČIST FORMAT ```python # Spremi task u /opt/pgz-sport/cc_tasks/sess_taskname.md (base64 + bridge) # Pa pošalji CC da pročita i implementira: tmux send-keys -t ccN:0 "Procitaj /opt/pgz-sport/cc_tasks/FILE.md i implementiraj sve. Backup deploy git commit. Radi autonomno do kraja." Enter sleep 3 tmux send-keys -t ccN:0 Enter # submit ``` ⚠️ **NIKAD ne stavljaj brackets `()` u inline prompt** — bash puca s "syntax error". Uvijek koristi taskfile. --- ## 📂 KLJUČNI FAJLOVI ``` /opt/pgz-sport/ ├── pgz_sport_api.py # main FastAPI app (port 8095) ├── auth/auth_v2.py # JWT auth + tenants + roles ├── routers/ │ ├── enrich_router.py # /v2/enrich + /apply (M12) │ ├── audit_seal_router.py # /api/audit/seal Polygon │ ├── audit_coverage_router.py │ ├── ... (još) ├── workers/ │ ├── ocr_worker.py │ ├── enrichment_worker.py # 24/7 daemon (5min loop) ├── blockchain/seal.py # Polygon PoS sealing ├── permissions.py # can_edit_invoice, can_approve_putni_nalog ├── data/sport_federations.json # sport → savez map (HBS, HKS, HRS, ...) ├── static/ │ ├── sport2.html # public portal (~144KB) │ ├── login.html # login forma │ ├── app.html # operativna app + Moj profil + GDPR │ ├── admin.html │ ├── admin_users.html # user mgmt │ ├── crm.html # članarine + liječnički + obrasci │ ├── erp.html # OCR + putni nalozi + računi │ ├── audit.html # audit log │ ├── kpi.html # KPI dashboard │ └── shared/ │ ├── sidebar.css # zajednički sidebar styling │ └── sidebar.js # NAV_SECTIONS s href URLs ├── cc_tasks/ # task fajlovi za CC agente │ ├── round3_brief.md │ ├── round3b_critical.md │ ├── cc{1-6}_*.md # per-agent prompt fajlovi └── swarm.sh # tmux monitor script ``` --- ## 🔐 KORISNICI | Email | Lozinka | Role | Tenant | Tier | |-------|---------|------|--------|------| | damir@pgz.hr | PGZ2026! | pgz_admin | Primorsko-goranska županija | 0 | | tajnik@atletski.pgz.hr | Atl2026! | savez_admin | Atletski savez PGŽ | 1 | | admin@ak-kvarner.hr | Kvarner2026! | klub_admin | AK Kvarner Rijeka | 2 | JWT login: `POST /sport/api/auth/login` → access_token + refresh_token + user object. Frontend sprema u `localStorage.pgz_access` (i `pgz_refresh`, `pgz_user`). `getToken()` u JS čita `pgz_access` (prvo localStorage pa sessionStorage). --- ## 🎨 SIDEBAR (shared/sidebar.js) ### Sekcije (sve URL-ove BEZ `/sport/` prefiksa!) ```js const SIDEBAR_SECTIONS = [ {title:'PORTAL', items: dashboard, savezi, klubovi, sportasi, manifestacije (svi /static/sport2.html#X)}, {title:'OPERATIVA', items: profil, kalendar, notif (/app#X)}, {title:'CRM', items: clanarine, lijecnicki, obrasci, dokumenti (/crm#X)}, {title:'ERP', items: racuni, putni, placanja, xlsx (/erp#X)}, {title:'ANALITIKA', items: kpi, financije, mreza, forenzika, audit}, {title:'ADMIN', requireRole: ['pgz_admin','super_admin'], items: korisnici, tenanti, sigurnost, sustav (/admin#X)} ]; ``` ### Footer - Avatar + ime + role (klik otvara user menu) - Public portal link kad nije logiran --- ## 📊 STANJE BAZE (10.04.2026) ``` pgz_sport.savezi: 246 (16 sa scrape email) pgz_sport.klubovi: 2244 (23 marked inactive non-PGŽ; 14 odbojkaških s adresom mjesto naziv — TREBA cleanup) pgz_sport.clanovi: 3243 (sources: hbs_savez 844, manual 840, godisnjak_2025_HOO 703, hns_semafor 651) pgz_sport.clan_sezona: 689 (78 athletes with seasonal stats) pgz_sport.utakmice_log: 9267 (with club logos) pgz_sport.clan_godisnjak: 2398 pgz_sport.sportski_objekti: 106 (sve geocoded) pgz_sport.sufinanciranje_sport: 110 pgz_sport.dokumenti: 5692 pgz_sport.users: 11+ (3 demo + admins) pgz_sport.sys_audit: ? (audit log) pgz_sport.lijecnicki_pregledi: ? (CC5) pgz_sport.invoices, invoice_lines, putni_nalozi: ? (CC4) ``` ### Test case — SPORTAŠ JOSIP ZEC (id=449) - Klub: NK OŠK Omišalj - Stats: 257 nastupa, 182 gola, 75 žuti, 39 crveni, 15 sezona, 16 utakmica - Mora raditi `GET /sport/api/sportas/449/profil` --- ## ✅ ŠTO RADI (testirano) - ✅ Login JWT flow (3 demo usera) - ✅ Sportaš profile panel (Josip Zec test 257/182/15) - ✅ Network 3D graph (react-force-graph-3d, kao app.rinet.one/klasik/control) - ✅ Forenzika scan (Velimir Liverić PEP) - ✅ Geocoding objekata (s OSM cross-check) - ✅ HUB-3 PDF + EPC QR za članarine - ✅ ZZJZ PGŽ scheduling integration - ✅ OCR + invoices CRUD (DeepSeek V3 sakriven kao "Ri.NET AI") - ✅ Putni nalozi + dnevnice (HR pravilnik 2025) - ✅ Polygon blockchain seal (wallet 0xD874345dcB17baBDfbFac9bD7838AdE0D4a5d368) - ✅ TOTP 2FA (setup + verify + disable) - ✅ Avatar upload (POST /sport/api/auth/me/avatar) - ✅ GDPR export endpoint (POST /sport/api/users/me/gdpr-export → JSON) - ✅ Sidebar shared (sidebar.css + sidebar.js) - ✅ 24/7 enrichment_worker daemon --- ## ⚠️ ŠTO NE RADI / TREBA POPRAVITI ### P0 (kritični za prezentaciju) 1. **GDPR export gumb** — `