Damir Radulić
6e5ada8517
Merge agent3-payments: SEPA + CSV import + match workflow
2026-05-05 18:35:01 +02:00
Damir Radulić
47df057270
Merge agent2-putni: Putni nalozi CRUD + status workflow
2026-05-05 18:34:56 +02:00
Damir Radulić
7625e59173
Merge agent4-export: Universal Export ▾ CSV/XLSX/PDF
2026-05-05 18:34:51 +02:00
Damir Radulić
c4640ca3af
Merge agent1-ocr: OCR u ERP/CRM
2026-05-05 18:34:46 +02:00
Damir Radulić
38383d07c5
Task 4: Universal Export ▾ — CSV/XLSX/PDF dropdown across all screens
...
- routers/export_router.py: /api/v2/export?format=...&endpoint=...&filters=...
- static/js/export_dropdown.js: shared attachExportDropdown helper
- sport2/app/crm_v2/erp_full: Export ▾ button wired to representative tables
- pgz_sport_api.py: mount export_router with try/except
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-05 18:33:36 +02:00
Damir Radulić
9b0ed43b92
RUSH 4-sub: filteri Klubovi/Sportaši + manifestacije card view + CRM v2 redesign
...
RUSH-1 Klubovi: list_klubovi() LEFT JOIN v_klubovi_financiranje (prima_pgz/rss/grad_rijeka, u_godisnjaku, ukupno_potpora). financiran=true sad OR od 3 davatelja (drop legacy klubovi.pgz_sufinanciran s 1312 false-positive). Sort sort=potpora&order=desc. UI: gold ukupno_potpora + tooltip + sortable kolona. Defaults priority view (financirani+godišnjak ON, hns_roster OFF). Test: priority=604, +hns=36, all=1641, financiran=15 sorted ZAMET 80208€.
RUSH-2 Sportaši: SELECT widened (slika_url, reprezentativac, kategoriziran, broj_dresa). avatarUrl() helper s 3 forme (apsolutni / lokalni /sport/uploads/avatars / initials fallback) + 32px circular avatar lijevo od imena. Test: priority=3712, no-priority=6086, +hns=1439, 1990-2000=645.
RUSH-3 Manifestacije: bugfix razina filter HTTP 500 (ambiguous column nakon LEFT JOIN savezi → m.razina/mjesto/organizator). 3 dropdowna iz meta (26 mjesta / 8 razina / 50 organizatora), view toggle 🃏 Kartice / 📋 Tablica (localStorage), 🔗 link ikona u card+table, source_url → Google fallback. Test: default=3, mjesto=Lošinj=2, razina=Tradicionalna=3, organizator=AK Kvarner=1.
RUSH-4 CRM v2: tab strip rewrite (10 taba u spec redu Članarine|Liječnički|Obrasci|E-mail|Accounts|Contacts|Leads|Opps|Activities|Cases, sticky+scrollable+gold underline). Pipeline → Opps tab. Novi e-mail templates tab (5 endpointa, 3 seed templates, +Novi modal). Card layout (.cgrid/.ccard) za Accounts/Contacts/Leads/Opps. Export dropdown 📥 ▾ CSV/XLSX(SheetJS CDN)/PDF na svaki tab. Test: /crm_v2 200, 10/10 tab labela, 10 Export dropdowna + 31 exportTab() handlera.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-05 18:33:20 +02:00
Damir Radulić
55a27fb315
Task 3: Plaćanja — POST/PATCH + CSV batch import + SEPA XML mock
...
- routers/erp_full_router.py: POST/PATCH/import-csv/sepa-export
- static/erp_full.html: high-end UI s match workflow + SEPA export + summary tiles
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-05 18:29:51 +02:00
Damir Radulić
efa15d0086
Task 2: Putni nalozi — full CRUD + status workflow
...
- routers/erp_full_router.py: GET/POST/PATCH/DELETE /api/v2/erp/putni-nalozi
- status workflow: draft → poslano → odobreno/odbijeno → isplaceno
- cost_total auto-calc, approved_at/paid_at on transitions
- alias under /expense-reports/* preserved
- static/erp_full.html: novi UI lista + modal + status buttons
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-05 18:28:53 +02:00
Damir Radulić
f488623920
Task 1: OCR u ERP/CRM — /api/ocr/upload + tab Računi (OCR)
...
- routers/ocr_router.py: POST /api/ocr/upload (Tesseract+pdf2image, regex field extraction)
- pgz_sport_api.py: mount ocr_router with try/except guard
- static/erp_full.html: nova tab "📷 OCR" + panel
- static/crm_v2.html: OCR upload modal/tab
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-05 18:28:22 +02:00
damir
b72d037141
CRITICAL FIX (Slika 11, 12): /api/v2/auth/me alias + frontend fix
...
Bug: crm_v2.html, admin_users.html, ostali pozivali /api/v2/auth/me
koji ne postoji u backendu (postoji /api/auth/me bez v2).
401 redirect na /login?reason=unauthorized iako Damir prijavljen.
Fix:
- Frontend: replace /api/v2/auth/me → /api/auth/me u svim file-ovima
- Backend: dodan defensive alias @app.get('/api/v2/auth/me')
2026-05-05 18:25:52 +02:00
damir
8127e2ef22
Slika 3: Savez 3 KPI (ukupna potpora, sportaša, dokumenata)
...
Endpoint:
- /api/v2/savez/{id}/kpi (ukupna_potpora, broj_sportasa, broj_klubova, najvisi_rang, broj_dokumenata, broj_manifestacija)
Frontend sport2.html:
- loadSavezKpi() function
- Auto-call after openSavez(id) panel render
2026-05-05 18:24:05 +02:00
damir
7608839473
Auth fix: apiPost/apiPut/apiDelete uses Bearer token
...
sport2.html:
- apiPost: localStorage pgz_access → Authorization: Bearer
- apiPut, apiDelete added
- Better error toast
Login redirect (multiple files):
- Wrap auto-redirect in __pgz_made_api_call check
- Don't redirect on initial page load if user has no API call yet
2026-05-05 18:22:52 +02:00
damir
1bc30d7881
/sport/dokumenti UI podrzava i rows i dokumenti response key
2026-05-05 18:13:51 +02:00
damir
80ed621683
Frontend Financije: 4 dropdown (godina, davatelj, sport, vrsta) + listeners
...
sport2.html:
- loadFinancije: dynamic dropdown options from /v2/potpore/meta
- refreshFinancije: sport/vrsta/davatelj filter params
- 4 dropdown change listeners
2026-05-05 18:11:45 +02:00
damir
a428363d42
V8 MEGA: meta endpoints + manifestacije + HNS V8 harvester batch
...
Endpoints:
- /v2/potpore/meta — dropdown options (sportovi, vrste, davatelji, godine)
- /v2/potpore/by-year — sport, vrsta filters
- /v2/manifestacije/meta — mjesta, razine, organizatori
- /v2/manifestacije — lista s filterima
HNS:
- 20 PGŽ priority klubova batch harvester pokrenut (HNK Goranin, HNK Orijent 1919, HNK Rijeka, NK Crikvenica, ...)
- ETA 30 min
2026-05-05 18:10:02 +02:00
damir
f07fdad919
Crisis V7 MEGA: sufinanciranje_sport + panel + CRM auth
...
DB:
- pgz_sport.sufinanciranje_sport.je_klub flag (RSS programi/totals false)
- pgz_sport.sufinanciranje_sport.klub_id matched
Endpoints:
- /v2/potpore/by-year: samo_klubovi=True default + davatelj filter
Frontend:
- sport2.html PANEL FORCE HIDE CSS (right:-100vw default)
- crm_v2.html: redirect to /login only on actual 401, not on page load
2026-05-05 15:02:47 +02:00
damir
007825acee
Bug hunt V7:
...
DB:
- Aggressive je_klub=false flag for programs/treninzi/totals (>100K€ no klub_id)
- 53 ne-klubovi flagged false (RSS Rijeka ukupni, Stručni rad, Potpora loptačkim, etc)
Frontend (sport2.html):
- Panel back button (← Natrag) + history stack
- window._panelHistory + pushPanelState + panelBack functions
- closePanel resets history
2026-05-05 14:56:53 +02:00
Damir Radulić
1e611d59f1
HNS sprint: 3-tab drill-down + parallel deep scraper dispatch
...
HNS-1 verify: smoke test 93409 OK, gap 854 uncovered, throughput ~60/min
HNS-2 dispatch: scripts/hns_dispatch.sh + 5 parallel workers shard'd po roster ID; coverage 265→1098 distinct_seasons (93.7% of 1172 roster), 125→971 distinct_matches; total seasons 3170→13371, matches 23515→150071
HNS-3 UI: 6-tab panel collapsed na 3 (🏆 Karijera / 📅 Utakmice / 👤 Profil); novi /api/v2/clan/{id}/hns-matches?limit=30 + /clan/{id}/hns-profile (bio + summary + HNS deep link); prof-grid 3-col card s gold jersey badge; OIB RBAC-mask. Test Josip Zec 449: 72 sez/30 utak.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-05 14:24:05 +02:00
damir
448273945c
/sport/* aliases u app: admin, dokumenti, crm/v2, erp/full
2026-05-05 14:13:32 +02:00
damir
360b8008ba
Crisis V6: panel expand + klub matching + ne-klub filter + samo_klubovi default
...
DB:
- pgz_sport.potpore_nositelji.je_klub flag (false za RSS programs/savezi)
- Re-match klub_id case-insensitive trim normalize
Endpoint:
- /api/dashboard/top-primatelji: samo_klubovi=True default
Frontend:
- sport2.html #panel/#dpanel: 70vw / 1100px max-width za HNS karijera
- mobile responsive za panel
2026-05-05 14:09:47 +02:00
Damir Radulić
ce544e660c
7-sub sprint UI residual: footer login + kalendar CRUD + notif center + CRM extra tabs
...
A: shared/sidebar.js footer onclick → handleFootClick (Guest→/sport/login, logged-in→logout()), a11y role+keyboard, popup link fix
B: app.html SECTIONS['kalendar'] kalOpenModal/Save/Edit/Delete + Akcije kolona, mock savez:kalendar maknut
C: app.html renderNotifCenter() (sve 4 role) + sidebar bell unread badge (30s poll)
F: crm_v2.html +443 linija — Članarine, Liječnički, Obrasci tabovi (split view + dynamic schema modal)
G: index.html minor + sidebar dokumenti link refresh
Note: backend (kalendar_router, notif_router, crm_router, erp_full_router uploads, dokumenti unified) već u commit f7b5114 .
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-05 13:55:33 +02:00
damir
f7b5114f58
PDF link target=_blank + nginx timeouts + priority filteri (samo s podacima)
...
nginx (sport.rinet.one):
- proxy_read_timeout 60s → 300s
- proxy_send_timeout 300s
- proxy_buffering off (PDF stream)
- client_max_body_size 50M → 100M
Endpoints:
- /api/v2/klubovi/financirani: +with_data filter (samo s potporama/godišnjakom/HNS)
- /api/v2/sportasi/filtered: +samo_priority +samo_s_hns
Frontend:
- PDF link target=_blank rel=noopener
- window._klub_only_priority = true (default)
- window._sportas_only_priority = true (default)
DB View:
- pgz_sport.v_nogomet_priority (prima_potpore, u_godisnjaku, ima_hns_roster)
2026-05-05 13:51:07 +02:00
damir
c6a5ec62aa
Dashboard UI: davatelj dropdown + dynamic years + KORISNIK truncate + PDF link
2026-05-05 13:43:30 +02:00
Damir Radulić
16b980e842
6-sub sprint: Dokumenti+HNS profil+Admin+ERP+CRM+PGŽ filter
...
SUB1 Dokumenti: pgz:dokumenti SECTIONS handler u app.html (klikabilan grid 19 godišnjaka, PDF stream)
SUB2 HNS profil: sport2.html drill-down — bio-chips (visina/težina/noga/poz/dres) + HNS deep + Google + Wiki + 🏆 Karijera/📅 Utakmice tabovi (Josip Zec id=449: 257 nast/182 gol/15 sez)
SUB3 Admin Users: sidebar.js href fix /admin/users → /sport/admin/users + razriješen audit ID konflikt
SUB4 ERP Full: 5 novih endpointa (invoice-uploads, racuni/ulazni/{rid}/uploads, expense-reports, putni-nalog-racuni, payments) + 3 nova taba (📎 Uploads/OCR, ✈ Putni, 💰 Plaćanja) + inline stavke drill-down + sidebar entry
SUB5 CRM Salesforce-Lite: dodan crm_v2 sidebar entry (router 956 linija već mounted)
SUB6 PGŽ filter: 2 nova endpointa /api/v2/savezi/priority-sort + /api/v2/clanovi/priority-sort; togglePGZFilter wired u Klubovi/Savezi/Sportaši (sport2.html + app.html); ⭐ 💰 📖 badge prefix; klubovi 1536/1641, savezi 35/246, sportaši 4979/5499
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-05 13:17:56 +02:00
damir
1d02c0897d
Sidebar: +ERP +CRM +Dokumenti, godišnjaci import (18 PDFs), filter helpers
...
- pgz nav now includes /erp/full, /crm/v2, /admin/users, /dokumenti
- 4 dokumenti endpoints: list, godišnjaci/list, godišnjak/{godina} PDF, detail
- 18 godišnjaka u pgz_sport.dokumenti (2006-2024) with savez_id=333
- PGŽ filter helpers (window._pgz_filter_priority, togglePGZFilter)
- navItemClick handler for nav items with href
2026-05-05 13:08:11 +02:00
damir
9fb512932a
HNS+UI: 4 nova endpointa + multi-sport schema (M2M kategorije + player_stats)
...
Endpoints:
- GET /api/v2/enrich-sources — sport→source mapping
- GET /api/v2/klubovi/priority-sort — financirani/godišnjak prvi
- GET /api/v2/clan/{id}/kategorije — many-to-many kategorije
- GET /api/v2/clan/{id}/full — kompletna slika (profil+kategorije+sezone+utakmice+stats)
- POST /api/v2/export/klubovi — XLSX export selektiranih
Schema:
- pgz_sport.clan_kategorije (M2M: igrač u juniorskoj+seniorskoj)
- pgz_sport.player_stats (multi-sport: nogomet/košarka/rukomet/odbojka/vaterpolo)
- pgz_sport.klub_roster (multi-source)
- pgz_sport.enrichment_sources (sport→izvor)
- View: v_pgz_priority_klubovi (financiran || u_godisnjaku)
- View: v_klubovi_priority_sort (priority sort)
Sport harvesters scaffold:
- scripts/sport_harvesters/__base.py (SportHarvester class)
- hks_basketball.py, hrs_handball.py, hos_volleyball.py, hvs_waterpolo.py
2026-05-05 10:42:49 +02:00
damir
c68fd4471e
HNS endpoints: /clan/{id}/hns-career + /klubovi/pgz-financirani + /dashboard/hns-coverage
...
Backed by: pgz_sport.hns_player_seasons, hns_klub_roster, v_pgz_financirani_klubovi
Used by: cc-hns subagents for UI integration
2026-05-05 10:22:36 +02:00
damir
a20230187f
Playwright logout test: dialog handler + wait_for_url for async flow
2026-05-05 09:24:59 +02:00
damir
e07292ba44
logout() proper fix: revoke backend + clear ALL session keys
...
Old logout() was demo placeholder:
- only cleared 'app-role' + 'jwt' (NOT pgz_access/refresh/user)
- did NOT call POST /auth/logout to revoke JWT
- redirected to /static/sport2.html (wrong)
New logout() now:
1. POST /auth/logout to revoke JWT server-side
2. Clear ALL keys: pgz_access, pgz_refresh, pgz_user, app-role, jwt, access_token, refresh_token, pgz_session_id (both localStorage + sessionStorage)
3. Redirect to /login
Verified by Playwright E2E: token absent after logout.
2026-05-05 09:24:12 +02:00
damir
a0fb328029
Playwright E2E: better logout selector chain + JS fallback
...
Test now tries (in order):
1. .sb-foot .lo (topbar logout in sidebar foot)
2. .lo (any logout class)
3. #pgz-menu-logout (sidebar.js menu link)
4. a/button :has-text('Odjava')
5. JS fallback: window.logout() or PGZSidebar.logout()
Also: dialog handler accepts confirm() automatically.
2026-05-05 09:23:13 +02:00
damir
dd2f7daaf8
CRISIS V3: definitive apiAuth + mobile hamburger + Playwright E2E test
...
apiAuth in app.html:
- Pre-checks JWT exp client-side BEFORE making request
- On expired: clears localStorage + redirects /login?reason=expired
- On 401 from server: clears + redirects /login?reason=unauthorized
- Single-flight redirect via window.__pgz_redirecting flag
login.html:
- Toast for ?reason=expired (red) / ?reason=unauthorized (orange)
app.html mobile:
- Hamburger button injected into topbar (.tb)
- Mobile CSS: sidebar slide-in -280→0, backdrop overlay, full-width drill-down
- toggleMobileSidebar() global function
- @media (max-width:768px) display:inline-flex, sidebar fixed pos
scripts/playwright_e2e.py:
- Desktop test (1280x800): login, JWT persist, profile, logo, logout
- Mobile test (375x812 iPhone X): viewport, login flow, hamburger, no h-scroll
- Output: _audit/playwright_<TS>/results.json + screenshots/*.png
Reproducible: TS=YYYYmmdd_HHMM python3 scripts/playwright_e2e.py
2026-05-05 09:21:39 +02:00
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
Damir Radulić
31e0374465
Dashboard top primatelji wired to live endpoint (default 2025, year filter)
...
- Frontend (sport2.html): refreshDashNositelji() koristi /api/dashboard/top-primatelji
umjesto /v2/potpore/by-year (koji je za 2025 vraćao samo 1 agregirani redak).
Dropdown proširen na "Sve godine" + 2021..2026. Dodana kolona "Platitelj".
- Backend (pgz_sport_api.py): top-primatelji endpoint sada parsira napomena
'doc_id=N' i JOIN-a pgz_sport.dokumenti za pdf_url; godina<=0 → sve godine;
dodane kolone vrsta + pdf_url + doc_title.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-05 09:11:47 +02:00
CC Data Integrity
49ac2c0dc8
Data integrity sweep: clanovi clean — 3 HNS dups merged, 1 trim normalized, 4 constraints active
...
Subagent A: merged 3 HNS profile/roster duplicate pairs (3243 → 3240 rows).
Authoritative auths preferred /igraci/ source_url over /klubovi/ roster scrape.
Manuel Boras Mandić (id=481) reconciled — pozicija=Vratar, hns_igrac_id=436387.
Subagent B: 1 trim auto-applied (id=634); 4 ALL CAPS held for manual review.
Subagent C: 0 strict cross-klub transfers; 56 soft groups in review queue.
Subagent D: 4 constraints applied (no_camelcase, trimmed, hns_uniq partial, normalize trigger);
2 skipped (length>=2 — 22 historical violators; klub+name+dob unique — 68 NULL-DOB groups).
Backup: pgz_sport.clanovi_backup_20260505_0836 (3243 rows untouched).
Audit: 5 sys_audit rows (3 PURGE, 1 NORMALIZE, 1 C_DETECTION_RUN).
Smoke: 5/5 endpoints 200; HNK Lovran 31 → 30 clanovi confirmed.
Full report: _audit/data_integrity_20260505_0836/CONSOLIDATED.md
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-05 09:08:35 +02:00
damir
4e4d69c04a
DI exec: applied CC-DI Subagent A+B SQL — 3245 clanovi, Manuel Boras merged
2026-05-05 09:04:14 +02:00
damir
e7102c720d
Dashboard top-primatelji: psycopg2 LIKE escape fix (%% in CASE WHEN)
...
CASE WHEN ... ILIKE '%X%' patterns conflicted with %s param placeholder.
Escaped to %%X%%. Endpoint now returns 200 with full klubovi list +
inferred davatelj_naziv (RSS / Županijski / Grad Rijeka / fallback).
2026-05-05 09:01:25 +02:00
damir
b95b2e8423
BIG FIX: profile save + sport classification + KUD separation
...
1) auth/auth_v2.py — update_me bug fix:
PUT /auth/me return value was 'return me(user)' but me() is a
FastAPI route handler, not callable directly. Replaced with explicit
re-fetch returning correct JSON shape. Profile changes now persist
in UI after save.
2) DB: HNK Goranin Delnice (id 782) sport='skijanje' → 'nogomet'
+ napomena cross-contamination cleaned (id 782, 192, 347, 2280)
+ general rule: NK/HNK/Nogometni klub → nogomet
+ RK/Rukometni klub → rukomet
+ OK/Odbojkaški klub → odbojka
3) DB: KUD/folklorne/lovačke/vatrogasne udruge marked as
sport='kulturno-umjetnicko' + razina='NE-sportsko' so frontend
can filter them out of sportski savezi list
4) Backup: pgz_sport.klubovi_backup_20260505_0857
Verified: PUT /auth/me with damir@pgz.hr persists telefon change to DB
and returns fresh data
2026-05-05 08:57:09 +02:00
CC4
125ba6dbfb
CC4: fix 3 outstanding bugs (dokumenti dup, upload, kategorizirani SQL)
...
Bug #1 — `/api/v2/dokumenti/{did:int}` duplicate registration (route shadowing):
- Bila dva @router.get-a za isti path, drugi (s chunks) bio dead code
- Renamed duplicate na /dokumenti/{did}/full → eksplicitan RAG-rich varianta
- /dokumenti/{did} ostaje simple (8 osnovnih polja), /full vraća chunks za RAG
Bug #2 — `/api/v2/dokumenti/upload` MISSING:
- Dodan @router.post("/dokumenti/upload") s multipart formom
- Polja: file, title, vrsta, razina, organizacija, sport, izvor_url, godina, kratak_opis
- Tekst ekstrakcija: pdftotext za PDF, raw decode za TXT
- Pohrana: /opt/pgz-sport/_data/dokumenti_uploads/{ts}_{sha12}_{safe_fname}
- Insert u pgz_sport.dokumenti (vraća dokument_id, fname, chars, sha12)
- Audit log entry preko erp.audit_helper
- Validacija: max 32 MB, dozvoljeno PDF/DOC/DOCX/TXT/RTF
Bug #3 — SQL alias bug u /api/v2/kategorizirani/list:
- Već popravljen u Sub1 commitu eb1b49f
- Verify: /kategorizirani/list i /kategorizirani/by-sport oba 200, count=270
Smoke 5/5 ✓:
- GET /v2/dokumenti -> 200
- GET /v2/dokumenti/1577 (simple) -> 200, 8 keys, no chunks
- GET /v2/dokumenti/1577/full (RAG) -> 200, has_chunks, count=0
- POST /v2/dokumenti/upload (multipart)-> 200, doc_id=31214, chars=50, size=52
- GET /v2/kategorizirani/list -> 200, 270 redova
/api/debug/dashboard:
- services: pgz-sport, pgz-debug-tail, pgz-auto-triage, nginx ACTIVE
- db: ok
- 0 novih grešaka nakon restart-a (samo stari nginx-access 502 iz prijašnjih restarta)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-05 08:52:47 +02:00
CC1
3e60e5095a
CC1 audit fixes #6/#8/#9 from CONSOLIDATED.md
...
#9 sportas trailing-slash (verified clean):
Frontend constructs /sportas/{id}/profil cleanly (sport2.html:L1582).
Live test: 200 on /sportas/449/profil; 307 on trailing-slash variant
(FastAPI auto-redirect, harmless). No fix needed.
#8 [VERIFY]/[UNRESOLVED] klubovi surfaced to audit log:
3 manual_review klubovi (2619 Čavle, 2630 Opatija, 4426 empty) inserted
into pgz_sport.sys_audit with action='klub.manual_review_pending',
visible in /audit page for human triage. Total audit rows: 633.
#6 backup-table archival:
Moved 26 *_backup_*/*_premerge_*/*_pre_*/*_dedup_*/*_deprecated_*/*_garbage_*
tables (~97k rows) from pgz_sport → pgz_sport_archive schema.
- Snapshot dump: _audit/db_snapshots/backup_tables_20260505_085057.sql.gz (56 MB)
- Script: scripts/archive_backup_tables.sql (idempotent, with rollback)
- pgz_sport canonical tables: 112 → 86
- All live API endpoints still 200, db=ok, errors_logged stable at 23
- Josip Zec test 257/182/15 still PASS
.gitignore: exclude _audit/db_snapshots/ (large pg_dump archives)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-05 08:52:07 +02:00
damir
aad034a59d
PHASE 5: sidebar Debug link + swarm_monitor.py daemon
...
- static/shared/sidebar.js: '🩺 Debug' link in pgz_admin sidebar
- scripts/swarm_monitor.py: detects stuck/idle CC agents,
Telegram alerts on session expired or limit prompts
- pgz-swarm-monitor.service running 60s checks
Full debug stack now active:
- pgz-debug-tail: error stream
- pgz-auto-triage: pattern → CC dispatch
- pgz-swarm-monitor: agent health
- /api/debug/* dashboard
2026-05-05 08:48:02 +02:00
damir
52db3d91a4
DEBUG observability: router properly mounted before root() handler
2026-05-05 08:47:10 +02:00
damir
63ca005b6e
DEBUG OBSERVABILITY: live error feed + auto-triage bot + dashboard
...
PHASE 1 — DEBUG mode:
- /etc/systemd/system/pgz-sport.service.d/debug.conf: DEBUG=1, LOG_LEVEL=DEBUG, PYTHONUNBUFFERED=1, UVICORN_LOG_LEVEL=debug
PHASE 2 — Error stream:
- /opt/pgz-sport/scripts/debug_tail.sh: tail journalctl + nginx → /var/log/pgz-sport-debug/{stream,errors}.jsonl
- pgz-debug-tail.service (always restart, multiplexes 4 sources)
PHASE 3 — Auto-triage bot:
- /opt/pgz-sport/scripts/auto_triage.py: classifies errors, dispatches CC agents
- Patterns: 5xx spike → CC4, 401/403 spike → CC2, 4xx API → CC3, ImportError/DB → CC4
- Rate limit: 6 telegram/5min
- Records decisions in triage_decisions.jsonl
- pgz-auto-triage.service
PHASE 4 — Live dashboard:
- routers/debug_router.py mounted in pgz_sport_api
- GET /api/debug/health — services + DB + error count
- GET /api/debug/errors?limit=N — last N errors (JSON)
- GET /api/debug/decisions — auto-fix decisions
- GET /api/debug/stream — full log tail
- GET /api/debug/dashboard — live HTML refresh 5s
Damir admin tier dashboard: https://sport.rinet.one/sport/api/debug/dashboard
2026-05-05 08:46:09 +02:00
CC1
7adcec3309
CC1: 3-subagent deep audit — Frontend / API gap / DB integrity
...
Reports in _audit/:
audit_FRONTEND_COVERAGE.md — SA-1 (Explore): 9 HTML files, 0 orphan handlers (clean)
audit_API_GAP.md — SA-2 (Explore): 356 backend routes vs 54 frontend paths
23 missing routes / 39 call sites
audit_DB_INTEGRITY.md — SA-3 (general-purpose): 8 SQL probes, FKs/NULLs clean,
48 dup-OIB clusters, 518 low-cov klubovi
audit_CONSOLIDATED.md — top 10 critical with owner matrix (cc1/cc4/cc5/cc6)
Headlines:
Frontend: clean (post-R3 refactors landed)
API gap: CRM module systemic — 16 of 23 missing routes need /crm prefix in crm.html
6 missing routes are trailing-slash bugs in crm.html
DB: 48 OIB dup clusters in klubovi (~100 rows) need merge+unique-index
518/2244 klubovi (23%) <33% coverage → enrichment_worker target list
14 scoreboard-string klubovi rows (RK ... HRL Zapad od X) → DELETE
~30 backup tables (~97k rows) cluttering pgz_sport schema
Owner allocation:
cc1 → #6 backup-table archival, #8 verify, #9 sportas trailing-slash
cc4 → #1 OIB dedup script, #4 scoreboard DELETE, #10 schema CHECKs
cc5 → #2 /crm prefix sweep on crm.html, #3 trailing-slash sweep, #7 notif endpoint
cc6 → #5 enrichment_worker batch on filled<4 klubovi
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-05 08:29:04 +02:00
CC4
3e5b98a935
CC4: 3-subagent backend hardening done + CRM audit_log fix
...
Sub1 (commit eb1b49f ): 4 v2 listing/discovery endpoints + SQL fix
Sub2: CRM 4 modula PASS (M7 članarine, M8 liječnički, M9 obrasci, dokumenti partial)
Sub3: ERP 4 modula GREEN — racuni/putni/placanja/xlsx, E2E demo flow (7 steps) PASS
Critical fix this commit:
- erp/audit_helper.py (centralni helper za audit_log writer)
- routers/clanarine_router.py: audit hook na POST /clanarine
- routers/lijecnicki_router.py: audit hook na POST /lijecnicki
- routers/obrasci_router.py: audit hook na POST /submissions + /submit
Verify: prije 0 / poslije 1 audit entry za POST /api/crm/clanarine
"33|create|api|clan=4946 klub=2320 300.0€"
Outstanding (next round):
- /api/v2/dokumenti plain route shadowing with RAG
- /api/v2/dokumenti/upload missing
- SQL alias bug u pgz_sport_v2_router.py:3099
Reports:
_audit/audit_CC4_FINAL.md (konsolidirani)
_audit/audit_CRM_VERIFIED.md
_audit/audit_ERP_VERIFIED.md
_audit/audit_ENDPOINTS_ADDED.md
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-05 08:28:49 +02:00
CC4-Sub1
eb1b49f0db
CC4 sub1: add missing v2 listing/discovery endpoints + fix kategorizirani SQL
...
- GET /api/v2/klubovi (v2 alias for /api/klubovi listing)
- GET /api/v2/savezi (v2 alias for /api/savezi listing)
- GET /api/v2/sport[/] (namespace discovery index)
- FIX /api/v2/kategorizirani/list (column alias used in WHERE -> 500 -> 200)
Source audit: _audit/audit_20260505_023639/errors.json
Smoke (anon+auth+public): 200 OK on all five endpoints.
Backup: _backups/r3_cc4/pgz_sport_v2_router.py.bak.1777962063
2026-05-05 08:23:28 +02:00
damir
4fc8327789
R7+ orchestrator + CC3 logo home: combined patches
...
Orchestrator-side:
- routers/img_proxy_router.py: 4xx/5xx → 1x1 transparent PNG (eliminates cascade <img onerror>)
- static/sport2.html: removed standalone three.min.js (3d-force-graph bundles), bumped to 1.73.4
CC3 (before limit hit):
- Logo home link applied to ALL HTML pages (admin.html, admin_users.html, audit.html, crm.html, erp.html, kpi.html, login.html)
- Backups in _backups/*.cc3_pre_logo.$ts
CC4 R3 (before plan mode):
- _backups/r3_cc4/ocr.py.pre_S2.$ts
Audit screenshots (80 pages) committed to _audit/audit_20260505_023639/shots/
2026-05-05 08:20:07 +02:00
CC1
662f448590
CC1: Playwright audit 20260505_023639 — 57 errors across 80 pages
...
Outputs in _audit/audit_20260505_023639/:
ERROR_REPORT.md — markdown grouped by category & page
errors.json — structured 57 findings
shots/ — 80 full-page PNG screenshots (ignored by git)
run.log — verbose trace
Sweep: 10 anonymous public URLs + 3 demo accounts (pgz_admin, savez_admin,
klub_admin) × 22 sidebar sections each (PORTAL/OPERATIVA/CRM/ERP/ANALITIKA;
ADMIN only for pgz_admin).
Categories:
console_error 29
console_warning 16
http_4xx_5xx 8
page_error 3
empty_page 1
Hot spots (top 20 in flag file):
ANALITIKA/an_mreza — 8 errors per role × 3 roles = 24 total (CDN/init issue)
anon/public/erp — 3
PORTAL/portal_dashboard, portal_sportasi, CRM/crm_clanarine,
ANALITIKA/an_financije — 2 errors per role × 3 = stable across roles
Flag: _audit/CC1_DONE_20260505_023639.flag with summary YAML for cc2-6 to consume.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-05 08:05:18 +02:00
CC4
e28c10d25b
CC4: ERP — računi, putni, plaćanja, XLSX, OCR end-to-end verified
...
Demo dataset (S3): 5 INA gorivo, 3 Konzum office, 2 Telekom, 1 Hotel za PN
- count=13 invoices kinds={cestarina,gorivo,hotel,oprema,ostalo}
- year_total=€818.15, putni_nalozi_year=€639.62
Final E2E smoke (10/10 ✓):
1. GET /erp → 200 / 61.8 KB
2. GET /api/erp/invoices → 13 redova, 5 kinds
3. GET /api/erp/putni-nalozi (alias plural) → 200
4. GET /api/erp/placanja → 6 kandidata (neplaćeni računi + odobreni PN)
5. POST /api/erp/placanja → HUB-3 PDF 11.1 KB
6. GET /api/erp/placanja/invoice/2/pdf → 200 application/pdf
7. GET /api/erp/export/invoices.xlsx → 200 valid PK header
8. GET /api/erp/export/putni.xlsx → 200 valid PK header
9. GET /api/erp/stats → month=€278.15 year=€818.15 pn_year=€639.62
10. Branding: 3× "Ri.NET AI" / 0× DeepSeek u /erp
Coverage:
- /erp#racuni: GET list, POST create (s/bez OCR), DELETE (admin-only), filter ✓
- /erp#putni: GET, POST, PATCH approve|reject|submit|pay (s body.action) ✓
- /erp#placanja: GET kandidati, POST kreiraj HUB-3 (invoice|putni_nalog), GET pdf ✓
- /erp#xlsx: invoices.xlsx + putni.xlsx ✓
- OCR: INA gorivo → vendor=INA, OIB=27759560625, brutto=€63.15, PDV=€12.63, cat=gorivo ✓
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-05 08:03:04 +02:00
CC4
8c97a5b778
CC4 R7 ERP S2: DELETE invoice + /putni-nalozi alias + /placanja + /export/putni.xlsx
...
erp/ocr.py:
- DELETE /api/erp/invoices/{id} (samo pgz_admin) + cascade payment cleanup + audit
(briše vezana payments, otkapča invoice_uploads.invoice_id NULL, audit log "delete")
erp/putni_nalozi.py:
- GET/POST /api/erp/putni-nalozi (alias plural od /putni-nalog) za CC1 brief kompatibilnost
- GET /api/erp/putni-nalozi/{id}
- PATCH /api/erp/putni-nalozi/{id} sa body.action: approve|reject|submit|pay (route kroz lifecycle)
- PATCH /api/erp/putni-nalog/{id} (singular alias)
- GET /api/erp/export/putni.xlsx — openpyxl 19 stupaca (klub, voditelj, ruta, datumi, km, dnevnice, ukupno, status...)
- GET /api/erp/placanja — lista neplaćenih računa + odobrenih putnih naloga (kandidati za isplatu)
- POST /api/erp/placanja {kind:invoice|putni_nalog, id, iban, model, opis, poziv_na_broj}
→ generira HUB-3 PDF + EPC QR (reuse crm.payments.build_hub3_pdf), pohranjuje u
_data/uploads/placanja/{kind}_{id}_HUB3_*.pdf
- GET /api/erp/placanja/{kind}/{id}/pdf → streama zadnji generirani PDF, ili kreira on-demand
- Dodan from pathlib import Path (fix NameError)
Live tests:
- DELETE /invoices/4 → 200 (test invoice obrisan)
- GET /putni-nalozi → 200, /putni-nalozi/1 → 200
- GET /placanja → 200 lista; POST → ok pdf 11 KB; GET pdf → 200 application/pdf %PDF-
- /placanja invoice 1 (INA €63.15) i putni_nalog 2 (€133.08) PDF generirani
- /export/putni.xlsx → 200 application/vnd.openxmlformats... PK header valid
- OCR INA gorivo: vendor=INA, OIB=27759560625, brutto=€63.15, PDV=€12.63, cat=gorivo
- UI 3× "Ri.NET AI" / 0× "DeepSeek"
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-05 08:01:49 +02:00
damir
c38f15a566
R7+: 5x P0 demo fixes — HNS direct link, avatar cache, logo home, klub→sportaši, smarter enrichment
...
1) HNS direct link u research_links: za sportaš s profile_url/source_url
(npr. https://semafor.hns.family/igraci/X/ ...) generira [⭐ DIRECT] link na vrhu liste,
umjesto generic Google search. _research_links sada prima row dict.
2) Avatar cache buster: applyMeToHeader dodaje ?t=Date.now() na sve avatar img tagove.
Avatar upload handler dodatno persistira novi avatar_url u localStorage.pgz_user
tako da preživi page refresh + cross-page navigacije.
3) Logo home link: <div class='logo'> → <a href='/' class='logo'> u app.html i sport2.html.
Klik na PGŽ SPORT logo vodi na public portal.
4) Klub → Sportaši drill-down: u klub Info tabu dodan button
'👥 Vidi sportaše ovog kluba (N)' koji prebacuje na k-clan tab.
Plus '🌐 Službena stranica' link kad klub ima web.
5) Smarter klub enrichment:
- URL validacija (skip placeholder strings poput 'godisnjak_zspgz_2025')
- Domain candidate guesser (slug → 16 candidate URLs s common HR TLD-ovima i sport prefix-ima)
- Parallel HEAD probe (8 threads, 10s budget) — first 200 + name token match wins
- Subpage scrape (/kontakt, /uprava, /o-nama, /o-klubu, /predsjednik) za richer evidence
- HNK Orijent (id 3766) test: pogađa https://www.orijent.hr/ , predlaže web+email+telefon+opis
E2E verified:
- 9/9 sidebar URL-ova → 200
- /users/me/gdpr-export → 200 (28KB JSON)
- /users/me/request-deletion → 200 (DB row pgz_sport.gdpr_erasure_requests)
- /enrich/klub/3766 → 4 proposed fields (web, email, telefon, opis)
- HNS sportaš research_links: ⭐ HNS profil DIRECT link na vrhu
Backend: routers/enrich_router.py
Frontend: static/app.html, static/sport2.html
Backups: _backups/sprint_1777940670/
Tag: R7-demo-ready
2026-05-05 02:24:30 +02:00