Commit Graph

9 Commits

Author SHA1 Message Date
CC6 Worker 84f1c41008 M12.3: Playwright fallback scraper for JS-heavy federation sites
- enrichment/playwright_scraper.py: fetch_rendered(), scrape_sport_pgz_klub(),
  scrape_federation(). Headless Chromium, 12s timeout, returns rendered text.
  Import-safe when playwright is missing.
- enrich_router._sport_pgz_search() now falls back to the JS path when the
  cheap urllib fetch returns empty or unparseable HTML.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 00:23:00 +02:00
Damir Radulić 8fe2478b84 CC2 R3 frontend: login.html + admin_users.html (M1+M2+M10 UI)
- static/login.html: dark Palantir-style login with PGŽ branding,
  Prijava se / Zaboravljena lozinka, demo account quick-fills,
  GDPR cookie banner, autostore tokens (local/session)
- static/admin_users.html: full user-management admin panel:
  - Collapsible left sidebar (Pregled, Korisnici, Tenanti, Audit log,
    Sigurnost, GDPR, links to ERP/CRM)
  - Users table with filters (q, tenant, role, status, limit)
  - + Dodaj korisnika modal (CRUD via /api/admin/users/*)
  - Suspend / unsuspend / reset-password / delete actions
  - Audit log viewer + Security KPIs + GDPR queue
  - Self-service: change pwd, export data (Art. 20), erasure request (Art. 17)
- pgz_sport_api.py: /login and /admin/users URL routes
- auth/seed_demo.py: added tajnik@atletski.pgz.hr/Atl2026!,
  admin@ak-kvarner.hr/Kvarner2026! demo users

5/5 live tests pass: login JWT, /me, /admin/users, /gdpr/consent, /gdpr/export

Note: existing admin.html (CC4 ERP/OCR work) preserved intact;
admin_users.html is dedicated user-mgmt page linked from sidebar.
2026-05-05 00:20:03 +02:00
Damir Radulić b93ca9a8bf M9 CRM Obrasci + ZZJZ booking detect + e-mail fallback
Obrasci (M9):
- /api/crm/forms — katalog form_templates (15 templata već seedan)
- /api/crm/forms/templates — alias (kompatibilnost)
- /api/crm/forms/{code|id} — detalji + schema_json
- /api/crm/forms/{code|id}/prefill — autopopulacija polja iz baze
  (klub_id/clan_id/user_id → polja na obrascu mapirana po imenima)
- /api/crm/forms/submissions [GET/POST] — lista + create draft
- /api/crm/forms/submissions/{id} — detalji s schema + klub/clan
- /api/crm/forms/submissions/{id}/submit — submit + sha256 potpis sadržaja
- /api/crm/forms/submissions/{id}/sign — re-sign / potpis bez statusa change
- /api/crm/forms/submissions/{id}/approve|reject — workflow
- /api/crm/forms/submissions/{id}/pdf — generirani PDF s metapodacima i potpisom
- /api/crm/forms/{code|id}/submit — shortcut: kreiraj+submit u jednom POST

ZZJZ PGŽ (M8 dopuna):
- /api/crm/zzjz/info — dodan online_booking probe (HTTP scrape best-effort)
- /api/crm/lijecnicki/{id}/zakazi — vraća booking URL ako postoji, inače mailto:
- /api/crm/lijecnicki/zakazi-email — generira mailto: deeplink s pred-popunjenim
  podacima sportaša/kluba (fallback kad nema online termina)
- URL sportske medicine ispravljen na školska/adolescentna medicina (jedini stvarni
  odjel ZZJZ PGŽ koji obavlja sportske preglede).
2026-05-05 00:14:59 +02:00
CC6 Worker 85fd51bfd9 M12.1: enrich v3 — preview + /apply persists to DB (klubovi/savezi/clanovi)
- POST /v2/enrich/{kind}/{eid} now scrapes Wikipedia HR + sport-pgz.hr +
  primary site, runs relevance filter so contact info from off-topic pages
  isn't lifted, optionally calls DeepSeek for opis_djelatnosti, returns
  {current, proposed, sources, last_enriched_at} for diff UI.
- POST /v2/enrich/{kind}/{eid}/apply UPDATES klubovi/savezi/clanovi for
  whitelisted empty fields, sets metadata.enriched_at +
  metadata.enrichment_source + metadata.enrichment_history, writes a row
  to pgz_sport.enrichment_log (new table).
- GET /v2/enrich/log read-back endpoint.
- Tested on klub 3 (KK Kvarner 2010): opis_djelatnosti persisted; metadata
  carries enriched_at + sources.
- New tables/columns: pgz_sport.enrichment_log; metadata jsonb on klubovi/savezi.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 00:14:17 +02:00
Damir Radulić 492c8fdd87 M1+M2+M10 (CC2 R3): JWT auth + admin users + GDPR backend
- auth/auth_v2.py: JWT login/refresh/logout/me + bcrypt + tenant_id/role/tier claims
- auth/admin_users.py: /api/admin/users CRUD + invite/role/suspend + bulk CSV
- auth/gdpr.py: cookie consent + Art.20 export + Art.17 erasure + admin queue
- auth/seed_demo.py: 3 demo tenants + 4 users (damir@pgz.hr / PGZ2026!)
- Removed legacy /api/auth/login + /api/auth/me from pgz_sport_api.py
- Wired auth/admin/gdpr routers into FastAPI

5/5 live curl tests pass: damir@pgz.hr login → JWT with tenant_id=1, role=pgz_admin, tier=0
2026-05-05 00:09:09 +02:00
Damir Radulić c12a8e9698 M8 CRM Liječnički pregledi: lista + isteci + ZZJZ PGŽ scheduling
- /api/crm/lijecnicki[CRUD] s filterima (klub/clan/status/placeno) + summary
- /api/crm/lijecnicki/uskoro-isticu — istekli + ≤30 dana (parametri days, include_expired)
- /api/crm/lijecnicki/{id} — detalji s status_calc + dana_do_isteka
- /api/crm/lijecnicki/{id}/zakazi — mock booking (upisuje termin u napomenu)
- /api/crm/zzjz/info — kontakt podaci ZZJZ PGŽ
- /api/crm/zzjz/termini — mock dostupnih termina za sportsku medicinu
  (deterministička dostupnost; realni scraper TODO)
2026-05-05 00:08:42 +02:00
Damir Radulić 1bd34ed678 M7 CRM Članarine: CRUD + dug + uplata + HUB-3 PDF + EPC QR
- /api/crm/clanarine[CRUD] s filterima (godina/klub/clan/status), summary
- /api/crm/clanarine/dug — dužnici (z opcionim days_overdue)
- /api/crm/clanarine/{id}/uplata — registracija parcijalne/cijele uplate
- /api/crm/clanarine/notify-bulk — mock e-mail kampanja (lista primatelja)
- /api/crm/clanarine/{id}/uplatnica.pdf — HUB-3 A4 PDF s ugrađenim EPC QR
- /api/crm/clanarine/{id}/qr.png — samo EPC BCD/002 SCT QR PNG
- /api/crm/clanarine/{id}/payment-info — JSON za UI gumbe + bank deep linkovi

crm/payments.py — HUB-3 PDF generator (ReportLab) + EPC QR (qrcode lib),
poziv-na-broj model HR00 = OIB-godina-id, format_eur HR notation.
2026-05-04 23:54:26 +02:00
claude-cc1 b7cb050843 CC1 R2 — full Round 2 done (8/8 stavki)
- geocode_objekti_v2.py + DB updates (Kastav, Rujevica, Platak, Petehovac, Crikvenica, Krk hand-curated)
- Maps URL → /maps/search/?api=1 format for proper pin
- Dashboard: year selector for nositelji, click → klub/PDF panel; top savezi clickable
- Universal sort (asc/desc) on Savezi/Klubovi/Sportaši/Objekti/Manifestacije/Financije
- Card↔Table toggle on Financije
- Manifestacije: source_url direct open, Google fallback
- Forenzika: severity/tip filter, search, run-scan, Liverić PEP custom findings + DB alerts
- Enrich endpoint /api/v2/enrich/{kind}/{id} + button on savez/klub/sportaš panels
- New 'Mreža' section: D3 force graph from /api/v1/presenter/graph-real

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 23:50:30 +02:00
Damir Radulić a7ec0a86be PGŽ Sport Platform — Round 1+2 baseline (sport2.html + API) 2026-05-04 23:39:08 +02:00