Files
pgz-sport/_audit/fullstack_20260505_0858_consolidated.md
T
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

7.3 KiB

FULLSTACK SPRINT — KONSOLIDIRANI IZVJEŠTAJ

Sprint ID: fullstack_20260505_0858 Sprint trajao: 09:00 → 09:25 (≈25 min, 5 paralelnih subagenata) Compiled: 2026-05-05 09:25 by orchestrator (Claude Opus 4.7 / 1M)

TL;DR

# Subagent Status Live test Persistencija
1 Dashboard Top Primatelji UI DONE 5/5 curl pass commit 31e0374
2 Role-based OIB display DONE 7/7 scope tests commit 8e13635
3 GDPR consent verify + Art.7 DONE withdraw 401, privacy 200 files written
4 Manifestacije enrichment ⚠️ PARTIAL apply.sql REJECTED by orchestrator
5 Klubovi cleanup ⚠️ DISCREPANCY DB ≠ izvještaj NIJE persistirano

Score: 3 + 2 ⚠️. Damir mora pregledati Sub4 i Sub5 ručno.


Sub1 — Dashboard Top Primatelji

  • File: /opt/pgz-sport/_audit/sub1_dashboard_done.md
  • Commit: 31e0374
  • Backend (pgz_sport_api.py:308-341): dashboard_top_primatelji() refaktoriran, godina≤0 = sve, doc_id regex za PDF, fix psycopg2 ILIKE escape (%%).
  • Frontend (static/sport2.html:907-957): dropdown Sve|2026|2025*|2024|..., default=2025, 7 kolona uključujući PDF link.
  • Stari endpoint /v2/potpore/by-year za 2025 vraćao samo 1 redak (RSS Rijeka aggregat) — root cause Damirovog "vidim samo 1 klub" simptoma.
  • Live: 2025=13 redaka, 2026=120 redaka, sve godine=0 fallback.

Sub2 — Role-based OIB

  • File: /opt/pgz-sport/_audit/sub2_oib_done.md
  • Commit: 8e13635 (Damir umergeao za vrijeme sub2 work)
  • Root cause: is_admin() u pgz_sport_api.py matchao samo literal "admin" — pgz_admin/super_admin/savez_admin/klub_admin svi su padali u viewer-tier i dobivali maskirane OIB-e.
  • Fix: is_admin() recognize sve PGŽ tiers; nove auth_context(), can_see_full_pii(auth, klub_id, savez_id), apply_privacy(authorization=), _audit_oib_access().
  • Frontend: /static/oib_format.js — single source of truth, <script src="/static/oib_format.js" defer> u 11 .html file-ova.
  • Audit log: svaki čitanje punog OIB-a → pgz_sport.audit_events (action oib.read, reason legitimate_interest).
  • Live: 7/7 testova (anonim/viewer/super_admin/pgz_admin/klub_admin own/klub_admin other/legacy bearer) — scope-aware enforcement radi.

Sub3 — GDPR

  • File: /opt/pgz-sport/_audit/sub3_gdpr_done.md
  • Status modula: real, not skeleton — auth/gdpr.py (263 LOC), 8 endpoints, tablice gdpr_consent + gdpr_erasure_requests postoje.
  • Verified: Art 15 (export JSON), Art 16 (PUT /auth/me + audit), Art 17 (erasure → email anon, OIB wipe, sessions revoke).
  • Trivial fixes applied:
    1. Art 7 withdraw consent bio MISSING — added POST /api/users/me/withdraw-consent + DELETE /api/users/me/gdpr-consent (auth/gdpr.py:209-232). Live HTTP 200/401.
    2. /api/gdpr/policy referencirao /sport/static/privacy.html koji NIJE postojao — kreiran 10842 B Palantir-style privacy policy. Live: HTTP 200 na https://api.rinet.one/sport/static/privacy.html.
  • Što ostaje za Damira:
    • HIGH: 0/18 users imaju gdpr_consent_at set; cookie banner 2/7 stranica; footer privacy link missing.
    • MEDIUM: Art 18/21 manual via email; nema retention sweep; nema 30-day SLA notifier.
    • LOW: avatar files na disku ne unlink-aju se pri erasure-u; policy versioning hardkodiran.

Sub4 — Manifestacije ⚠️ PARTIAL

  • File: /opt/pgz-sport/_audit/sub4_manifestacije.md
  • Status: agent prekinut prije završetka, obradio 50/113 redova.
  • DB nije diran: web, wiki_url, enriched_at, enriched_confidence kolone NE POSTOJE — apply.sql napisan ali NIJE pokrenut.
  • Quality review: od 5 predloženih matcheva, 3 su krivi (Čabar→Pakrac, Rijeka kup→Rijeka dubrovačka geografski objekt, Delta kup→Delta Dunava). Confidence formula radi samo content-match count, bez geographic/category guard-a.
  • Orchestrator decision: apply.sql REJECTED. Samo Rally Opatija (id=5) bi se mogao primijeniti ručno.
  • Što treba Damir: ALTER TABLE dodaj kolone (sigurno), manual review kandidati.csv, re-run skripte s edit-distance + category guard.

Sub5 — Klubovi cleanup ⚠️ DISCREPANCY (BRUTAL HONEST)

  • File: /opt/pgz-sport/_audit/sub5_klubovi.md
  • Sub5 izvještaj tvrdi: 13 sub5a-flagged + 49 KUD reclassified u 'lovstvo'.
  • DB realnost:
    • WHERE napomena ILIKE '%sub5%' OR '%TODO_FIX%'0 redaka
    • WHERE sport='lovstvo'0 redaka
    • WHERE sport='kulturno-umjetnicko'0 redaka (svi su već prije nestali)
    • Klub 2635 "Ćirila Kosovela 3, 51 000 Rijeka" napomena = (empty) — NIJE flagged
  • Kontradikcija: UPDATE-i koje Sub5 tvrdi da je izveo nisu se dogodili. Ili je transakcija rollback-an, ili je Sub5 generirao SQL bez COMMIT-a, ili je radio na različitom schemi/tablici, ili je njegova provjera prošla kroz vlastiti in-memory state bez stvarnog psql -c.
  • Sub5 file artifact-i (sub5_klubovi/run_sub5.py, sub5_run.json) postoje, ali stvarni DB UPDATE rezultat = 0.
  • Što treba Damir: ručno pregledati sub5_klubovi/sub5_run.json (sadrži predložene UPDATE-e), odlučiti hoće li ih primijeniti, i dodati COMMIT step u skriptu prije re-run-a.

Smoke testovi (verifikacija)

[smoke] ✅ API health 200
[smoke] ✅ top-primatelji 2025 count=13 (≥5)
[smoke] ✅ top-primatelji 2026 count=120 (≥50)
[smoke] ❌ HNK Goranin sport=skijanje (spec: trebao biti nogomet — out-of-scope sub5, vezano za b95b2e8)
[smoke] ✅ users.telefon kolona postoji
[smoke] ⚠️ Kosovela klub nije flagged (sub5 discrepancy)
[smoke] ✅ /static/oib_format.js HTTP 200
[smoke] ✅ /static/privacy.html HTTP 200
[smoke] ✅ POST /api/users/me/withdraw-consent HTTP 401 (endpoint exists, auth required)

Note HNK Goranin Delnice (id=782): sport='skijanje', stara database greška (NK ima skijaški pendant id=191 "Skijaški klub Goranin Delnice"). Sub5 nije adresirao single-klub fix. Treba SQL update:

UPDATE pgz_sport.klubovi SET sport='nogomet' WHERE id=782;

Coordination

  • Heartbeat: ažuriran više puta (Redis cc:pgz-sport:heartbeat)
  • Log: 5 push-eva u cc:pgz-sport:log (start, sub1-5 done, sprint complete)
  • Workers: nema kolizije s W6 (CC4 ERP), W7 (CC5 frontend), W8 (CC6 vector)

Files modified (po commitu)

  • 31e0374 — Dashboard top primatelji (Sub1): pgz_sport_api.py, static/sport2.html
  • 8e13635 — OIB role + login crisis (Sub2 + Damir): pgz_sport_api.py, 11 .html, /static/oib_format.js
  • (uncommitted) — Sub3: auth/gdpr.py + new static/privacy.html
  • (rejected) — Sub4: sub4_manifestacije_apply.sql
  • (no-op) — Sub5: tvrdi UPDATE 62 redaka, DB pokazuje 0

Next steps for Damir

  1. Push HEAD na gitea/origin (orchestrator nije pushao po hard rule).
  2. Manual review Sub5 sub5_run.json — ako UPDATE-i izgledaju OK, primijeni ih ručno.
  3. HNK Goranin Delnice SQL fix (gore).
  4. Manifestacije: ALTER TABLE + manual primijeni samo id=5 Rally Opatija. Re-run sub4 skripte s boljim matching-om kasnije.
  5. GDPR backfill: UPDATE users SET gdpr_consent_at=created_at WHERE gdpr_consent_at IS NULL (legacy users imaju implicitan consent kroz registraciju), ili explicit re-prompt na sljedećem loginu.
  6. Cookie banner: include u footer index/sport2/app/crm/erp.