diff --git a/HANDOFF_PGZ_SPORT_05may.md b/HANDOFF_PGZ_SPORT_05may.md new file mode 100644 index 0000000..2f42b20 --- /dev/null +++ b/HANDOFF_PGZ_SPORT_05may.md @@ -0,0 +1,373 @@ +# 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** — `