PGŽ Sport Platform — Round 1+2 baseline (sport2.html + API)

This commit is contained in:
Damir Radulić
2026-05-04 23:39:08 +02:00
commit a7ec0a86be
1820 changed files with 694455 additions and 0 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,867 @@
#!/usr/bin/env python3
"""
pgz_sport_extended_api.py - Multi-tenant + ERP/CRM extension for /api/v1/*
Author: Damir Radulić (damir@rinet.one)
Date: 28.04.2026
Port: 8095 (mounted under /api/v2/)
Endpoints: auth, users, roles, klub-access, invoices, forms, alerts, expense reports, RAG sport agent
"""
from fastapi import APIRouter, HTTPException, Query, Body, Header, Depends, UploadFile, File, Form
from pydantic import BaseModel
from typing import Optional, List, Dict, Any
from datetime import date, datetime, timedelta
import psycopg2, psycopg2.extras
import hashlib, secrets, json, requests, os, re, time
DB = dict(host='localhost', port=5432, dbname='rinet_v3', user='rinet', password='R1net2026!SecureDB#v7')
QDRANT = "http://10.10.0.2:6333"
EMBED = "http://localhost:9879/api/embeddings"
COLL = "pgz_sport_v1"
router = APIRouter(prefix="/api/v2", tags=["pgz_sport_v2"])
# ---------------- DB helpers ----------------
def db_query(sql: str, params=()):
with psycopg2.connect(**DB) as c:
cur = c.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
cur.execute(sql, params)
if cur.description: return cur.fetchall()
return []
def db_one(sql: str, params=()):
rows = db_query(sql, params)
return rows[0] if rows else None
def db_exec(sql: str, params=()):
with psycopg2.connect(**DB) as c:
cur = c.cursor()
cur.execute(sql, params)
if cur.description:
r = cur.fetchone()
return r[0] if r else None
c.commit()
# ---------------- Auth helpers ----------------
def hash_pw(pw: str) -> str:
return hashlib.sha256(pw.encode()).hexdigest()
def make_token() -> str:
return secrets.token_urlsafe(32)
def get_current_user(authorization: Optional[str] = Header(None)) -> Optional[Dict]:
if not authorization: return None
token = authorization.replace('Bearer ','').strip()
th = hashlib.sha256(token.encode()).hexdigest()
s = db_one("""SELECT s.user_id, u.email, u.full_name, u.status
FROM pgz_sport.user_sessions s
JOIN pgz_sport.users u ON u.id=s.user_id
WHERE s.token_hash=%s AND s.revoked=false AND s.expires_at>now()""", (th,))
if not s: return None
return s
def require_user(user = Depends(get_current_user)):
if not user: raise HTTPException(401, "Authentication required")
return user
def user_has_role(user_id: int, role_code: str, scope_type: str = None, scope_id: int = None) -> bool:
sql = """SELECT 1 FROM pgz_sport.user_roles ur
JOIN pgz_sport.roles r ON r.id=ur.role_id
WHERE ur.user_id=%s AND r.code=%s AND ur.active=true
AND (ur.expires_at IS NULL OR ur.expires_at>now())"""
args = [user_id, role_code]
if scope_type:
sql += " AND (ur.scope_type=%s OR ur.scope_type='global')"
args.append(scope_type)
if scope_id:
sql += " AND (ur.scope_id=%s OR ur.scope_id IS NULL)"
args.append(scope_id)
return bool(db_one(sql, tuple(args)))
# ============== AUTH ENDPOINTS ==============
class LoginReq(BaseModel):
email: str
password: str
@router.post("/auth/login")
def login(req: LoginReq):
u = db_one("""SELECT id, email, full_name, password_hash, status
FROM pgz_sport.users WHERE email=%s""", (req.email.lower().strip(),))
if not u or u['status'] != 'active':
raise HTTPException(401, "Invalid credentials")
if not u['password_hash'] or u['password_hash'] != hash_pw(req.password):
raise HTTPException(401, "Invalid credentials")
token = make_token()
th = hashlib.sha256(token.encode()).hexdigest()
expires = datetime.now() + timedelta(days=30)
db_exec("""INSERT INTO pgz_sport.user_sessions (user_id, token_hash, expires_at)
VALUES (%s,%s,%s)""", (u['id'], th, expires))
db_exec("UPDATE pgz_sport.users SET last_login=now() WHERE id=%s", (u['id'],))
db_exec("""INSERT INTO pgz_sport.audit_events (user_id, action) VALUES (%s,'login')""", (u['id'],))
roles = db_query("""SELECT r.code, r.naziv, ur.scope_type, ur.scope_id
FROM pgz_sport.user_roles ur JOIN pgz_sport.roles r ON r.id=ur.role_id
WHERE ur.user_id=%s AND ur.active=true""", (u['id'],))
return {
"token": token,
"expires_at": expires.isoformat(),
"user": {"id":u['id'],"email":u['email'],"full_name":u['full_name'],"roles":roles}
}
@router.post("/auth/logout")
def logout(user = Depends(require_user)):
th = hashlib.sha256(user.get('_token','').encode()).hexdigest()
db_exec("UPDATE pgz_sport.user_sessions SET revoked=true WHERE user_id=%s", (user['user_id'],))
return {"status":"ok"}
@router.get("/auth/me")
def me(user = Depends(require_user)):
roles = db_query("""SELECT r.code, r.naziv, ur.scope_type, ur.scope_id
FROM pgz_sport.user_roles ur JOIN pgz_sport.roles r ON r.id=ur.role_id
WHERE ur.user_id=%s AND ur.active=true""", (user['user_id'],))
klubovi = db_query("""SELECT k.id, k.naziv, ukl.link_type, ukl.primary_klub
FROM pgz_sport.user_klub_links ukl JOIN pgz_sport.klubovi k ON k.id=ukl.klub_id
WHERE ukl.user_id=%s AND (ukl.do_datuma IS NULL OR ukl.do_datuma>now()::date)""",
(user['user_id'],))
return {**user, "roles":roles, "klubovi":klubovi}
# ============== USER MANAGEMENT (super_admin / pgz_admin) ==============
class CreateUserReq(BaseModel):
email: str
full_name: str
password: Optional[str] = None
oib: Optional[str] = None
phone: Optional[str] = None
role_code: str = 'klub_user'
scope_type: Optional[str] = None
scope_id: Optional[int] = None
@router.post("/users")
def create_user(req: CreateUserReq, user = Depends(require_user)):
if not (user_has_role(user['user_id'],'super_admin') or
user_has_role(user['user_id'],'pgz_admin') or
user_has_role(user['user_id'],'klub_admin', 'klub', req.scope_id)):
raise HTTPException(403, "Forbidden")
pw_hash = hash_pw(req.password) if req.password else None
uid = db_exec("""INSERT INTO pgz_sport.users
(email, full_name, oib, phone, password_hash, status, email_verified)
VALUES (%s,%s,%s,%s,%s,'active',false) RETURNING id""",
(req.email.lower().strip(), req.full_name, req.oib, req.phone, pw_hash))
role_id = db_one("SELECT id FROM pgz_sport.roles WHERE code=%s", (req.role_code,))
if role_id:
db_exec("""INSERT INTO pgz_sport.user_roles (user_id, role_id, scope_type, scope_id, granted_by)
VALUES (%s,%s,%s,%s,%s)""", (uid, role_id['id'], req.scope_type, req.scope_id, user['user_id']))
db_exec("""INSERT INTO pgz_sport.audit_events (user_id, action, resource_type, resource_id)
VALUES (%s,'create_user','user',%s)""", (user['user_id'], uid))
return {"id": uid, "email": req.email}
@router.get("/users")
def list_users(klub_id: Optional[int]=None, role: Optional[str]=None, limit:int=100, user = Depends(require_user)):
where, args = ["1=1"], []
if klub_id:
where.append("EXISTS (SELECT 1 FROM pgz_sport.user_klub_links ukl WHERE ukl.user_id=u.id AND ukl.klub_id=%s)")
args.append(klub_id)
if role:
where.append("""EXISTS (SELECT 1 FROM pgz_sport.user_roles ur JOIN pgz_sport.roles r ON r.id=ur.role_id
WHERE ur.user_id=u.id AND r.code=%s AND ur.active=true)""")
args.append(role)
args.append(limit)
return db_query(f"""SELECT u.id, u.email, u.full_name, u.status, u.last_login,
(SELECT array_agg(r.code) FROM pgz_sport.user_roles ur JOIN pgz_sport.roles r ON r.id=ur.role_id
WHERE ur.user_id=u.id AND ur.active=true) AS roles
FROM pgz_sport.users u WHERE {' AND '.join(where)} ORDER BY u.id LIMIT %s""", args)
class GrantRoleReq(BaseModel):
user_id: int
role_code: str
scope_type: Optional[str] = None
scope_id: Optional[int] = None
expires_at: Optional[datetime] = None
@router.post("/users/grant-role")
def grant_role(req: GrantRoleReq, user = Depends(require_user)):
if not user_has_role(user['user_id'],'super_admin'):
if not user_has_role(user['user_id'],'pgz_admin'):
raise HTTPException(403, "Only super_admin or pgz_admin can grant roles")
role = db_one("SELECT id FROM pgz_sport.roles WHERE code=%s", (req.role_code,))
if not role: raise HTTPException(404, "Unknown role")
db_exec("""INSERT INTO pgz_sport.user_roles
(user_id, role_id, scope_type, scope_id, granted_by, expires_at)
VALUES (%s,%s,%s,%s,%s,%s) ON CONFLICT DO NOTHING""",
(req.user_id, role['id'], req.scope_type, req.scope_id, user['user_id'], req.expires_at))
db_exec("""INSERT INTO pgz_sport.audit_events
(user_id, action, resource_type, resource_id, meta)
VALUES (%s,'grant_role','user',%s,%s::jsonb)""",
(user['user_id'], req.user_id, json.dumps({'role':req.role_code,'scope':req.scope_type})))
return {"status":"ok"}
@router.get("/roles")
def list_roles():
return db_query("SELECT id, code, naziv, opis, permissions FROM pgz_sport.roles ORDER BY id")
# ============== KLUB MEMBERSHIP LINKS ==============
class LinkUserKlubReq(BaseModel):
user_id: int
klub_id: int
clan_id: Optional[int] = None
link_type: str # 'sportas','trener','tajnik','predsjednik','clan_uprave','volonter'
od_datuma: Optional[date] = None
primary_klub: bool = True
napomena: Optional[str] = None
@router.post("/klub-links")
def link_user_klub(req: LinkUserKlubReq, user = Depends(require_user)):
if not (user_has_role(user['user_id'],'super_admin') or
user_has_role(user['user_id'],'pgz_admin') or
user_has_role(user['user_id'],'klub_admin','klub', req.klub_id)):
raise HTTPException(403, "Forbidden")
db_exec("""INSERT INTO pgz_sport.user_klub_links
(user_id, klub_id, clan_id, link_type, od_datuma, primary_klub, napomena)
VALUES (%s,%s,%s,%s,%s,%s,%s) ON CONFLICT DO NOTHING""",
(req.user_id, req.klub_id, req.clan_id, req.link_type,
req.od_datuma or date.today(), req.primary_klub, req.napomena))
return {"status":"ok"}
# ============== INVOICES (ERP) ==============
class CreateInvoiceReq(BaseModel):
klub_id: int
invoice_kind: str # 'ulazni'|'izlazni'
invoice_no: str
vendor_name: Optional[str] = None
vendor_oib: Optional[str] = None
customer_name: Optional[str] = None
customer_oib: Optional[str] = None
invoice_date: date
due_date: Optional[date] = None
amount_net: Optional[float] = None
amount_vat: Optional[float] = None
amount_gross: float
vat_rate: Optional[float] = 25
description: Optional[str] = None
category: Optional[str] = None
account_code: Optional[str] = None
@router.post("/invoices")
def create_invoice(req: CreateInvoiceReq, user = Depends(require_user)):
if not (user_has_role(user['user_id'],'super_admin') or
user_has_role(user['user_id'],'klub_admin','klub',req.klub_id)):
raise HTTPException(403, "Forbidden")
iid = db_exec("""INSERT INTO pgz_sport.invoices
(klub_id, invoice_kind, invoice_no, vendor_name, vendor_oib, customer_name, customer_oib,
invoice_date, due_date, amount_net, amount_vat, amount_gross, vat_rate,
description, category, account_code, created_by)
VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)
RETURNING id""", (req.klub_id, req.invoice_kind, req.invoice_no,
req.vendor_name, req.vendor_oib, req.customer_name, req.customer_oib,
req.invoice_date, req.due_date, req.amount_net, req.amount_vat, req.amount_gross,
req.vat_rate, req.description, req.category, req.account_code, user['user_id']))
db_exec("""INSERT INTO pgz_sport.audit_events
(user_id, action, resource_type, resource_id)
VALUES (%s,'create_invoice','invoice',%s)""", (user['user_id'], iid))
return {"id": iid}
@router.get("/invoices")
def list_invoices(klub_id: Optional[int]=None, kind: Optional[str]=None,
status: Optional[str]=None, year: Optional[int]=None,
limit:int=200, user=Depends(require_user)):
where, args = ["1=1"], []
if klub_id: where.append("klub_id=%s"); args.append(klub_id)
if kind: where.append("invoice_kind=%s"); args.append(kind)
if status: where.append("payment_status=%s"); args.append(status)
if year: where.append("EXTRACT(year FROM invoice_date)=%s"); args.append(year)
args.append(limit)
return db_query(f"""SELECT id, invoice_no, invoice_kind, vendor_name, customer_name,
invoice_date, due_date, amount_gross, currency, payment_status, category, klub_id
FROM pgz_sport.invoices WHERE {' AND '.join(where)}
ORDER BY invoice_date DESC LIMIT %s""", args)
@router.get("/invoices/{invoice_id}")
def get_invoice(invoice_id: int, user=Depends(require_user)):
inv = db_one("SELECT * FROM pgz_sport.invoices WHERE id=%s", (invoice_id,))
if not inv: raise HTTPException(404)
inv['lines'] = db_query("""SELECT * FROM pgz_sport.invoice_lines
WHERE invoice_id=%s ORDER BY line_no""", (invoice_id,))
inv['payments'] = db_query("""SELECT * FROM pgz_sport.payments
WHERE invoice_id=%s ORDER BY payment_date""", (invoice_id,))
return inv
# ============== INVOICE OCR UPLOAD ==============
class OcrUploadReq(BaseModel):
klub_id: int
file_name: str
file_path: str
file_size: Optional[int] = None
mime: Optional[str] = None
sha256: Optional[str] = None
@router.post("/invoice-uploads")
def create_upload(req: OcrUploadReq, user = Depends(require_user)):
if not (user_has_role(user['user_id'],'super_admin') or
user_has_role(user['user_id'],'klub_admin','klub',req.klub_id) or
user_has_role(user['user_id'],'klub_user','klub',req.klub_id)):
raise HTTPException(403, "Forbidden")
uid = db_exec("""INSERT INTO pgz_sport.invoice_uploads
(klub_id, uploaded_by, file_name, file_path, file_size, mime, sha256)
VALUES (%s,%s,%s,%s,%s,%s,%s) RETURNING id""",
(req.klub_id, user['user_id'], req.file_name, req.file_path,
req.file_size, req.mime, req.sha256))
return {"id":uid, "status":"queued_for_ocr"}
@router.get("/invoice-uploads")
def list_uploads(klub_id: Optional[int]=None, status: Optional[str]=None, limit:int=100):
where, args = ["1=1"], []
if klub_id: where.append("klub_id=%s"); args.append(klub_id)
if status: where.append("ocr_status=%s"); args.append(status)
args.append(limit)
return db_query(f"""SELECT id, klub_id, file_name, ocr_status, ai_invoice_no,
ai_amount_gross, ai_vendor_name, ai_invoice_date, uploaded_at, processed_at
FROM pgz_sport.invoice_uploads WHERE {' AND '.join(where)}
ORDER BY uploaded_at DESC LIMIT %s""", args)
# ============== EXPENSE REPORTS ==============
class ExpenseReportReq(BaseModel):
klub_id: int
user_id: Optional[int] = None
clan_id: Optional[int] = None
report_type: str # 'putni_nalog','putni_trosak','dnevnice','vlastiti_auto'
destination: Optional[str] = None
purpose: Optional[str] = None
date_from: date
date_to: date
vehicle_type: Optional[str] = None
km_driven: Optional[float] = None
cost_transport: float = 0
cost_lodging: float = 0
cost_meals: float = 0
cost_other: float = 0
dnevnice_count: int = 0
notes: Optional[str] = None
@router.post("/expense-reports")
def create_expense(req: ExpenseReportReq, user = Depends(require_user)):
cost_total = (req.cost_transport + req.cost_lodging + req.cost_meals + req.cost_other +
(req.km_driven or 0)*0.42 + req.dnevnice_count*30)
eid = db_exec("""INSERT INTO pgz_sport.expense_reports
(klub_id, user_id, clan_id, report_type, destination, purpose, date_from, date_to,
vehicle_type, km_driven, cost_transport, cost_lodging, cost_meals, cost_other,
cost_total, dnevnice_count, notes)
VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)
RETURNING id""", (req.klub_id, req.user_id or user['user_id'], req.clan_id,
req.report_type, req.destination, req.purpose, req.date_from, req.date_to,
req.vehicle_type, req.km_driven, req.cost_transport, req.cost_lodging,
req.cost_meals, req.cost_other, cost_total, req.dnevnice_count, req.notes))
return {"id": eid, "cost_total": float(cost_total)}
@router.get("/expense-reports")
def list_expenses(klub_id: Optional[int]=None, status: Optional[str]=None, limit:int=100):
where, args = ["1=1"], []
if klub_id: where.append("klub_id=%s"); args.append(klub_id)
if status: where.append("status=%s"); args.append(status)
args.append(limit)
return db_query(f"""SELECT * FROM pgz_sport.expense_reports
WHERE {' AND '.join(where)} ORDER BY created_at DESC LIMIT %s""", args)
# ============== FORMS ==============
@router.get("/forms/templates")
def list_form_templates(kategorija: Optional[str]=None):
where, args = ["active=true"], []
if kategorija: where.append("kategorija=%s"); args.append(kategorija)
return db_query(f"""SELECT id, code, naziv, kategorija, opis, schema_json, required_role
FROM pgz_sport.form_templates WHERE {' AND '.join(where)} ORDER BY kategorija, naziv""", args)
@router.get("/forms/templates/{code}")
def get_form_template(code: str):
t = db_one("SELECT * FROM pgz_sport.form_templates WHERE code=%s AND active=true", (code,))
if not t: raise HTTPException(404)
return t
class SubmitFormReq(BaseModel):
template_code: str
klub_id: int
clan_id: Optional[int] = None
data: Dict[str, Any]
submit: bool = False # True = submit, False = save draft
@router.post("/forms/submit")
def submit_form(req: SubmitFormReq, user = Depends(require_user)):
t = db_one("SELECT id FROM pgz_sport.form_templates WHERE code=%s", (req.template_code,))
if not t: raise HTTPException(404, "Unknown template")
sid = db_exec("""INSERT INTO pgz_sport.form_submissions
(template_id, template_code, klub_id, user_id, clan_id, data, status, submitted_at)
VALUES (%s,%s,%s,%s,%s,%s::jsonb,%s,%s) RETURNING id""",
(t['id'], req.template_code, req.klub_id, user['user_id'], req.clan_id,
json.dumps(req.data), 'submitted' if req.submit else 'draft',
datetime.now() if req.submit else None))
db_exec("""INSERT INTO pgz_sport.audit_events
(user_id, action, resource_type, resource_id, meta)
VALUES (%s,'submit_form','form',%s,%s::jsonb)""",
(user['user_id'], sid, json.dumps({'template':req.template_code})))
return {"id": sid}
@router.get("/forms/submissions")
def list_submissions(klub_id: Optional[int]=None, template_code: Optional[str]=None,
status: Optional[str]=None, limit:int=100):
where, args = ["1=1"], []
if klub_id: where.append("klub_id=%s"); args.append(klub_id)
if template_code: where.append("template_code=%s"); args.append(template_code)
if status: where.append("status=%s"); args.append(status)
args.append(limit)
return db_query(f"""SELECT id, template_code, klub_id, user_id, clan_id, status,
submitted_at, approved_at, reference_no
FROM pgz_sport.form_submissions WHERE {' AND '.join(where)}
ORDER BY created_at DESC LIMIT %s""", args)
# ============== ALERTS ==============
@router.get("/alerts")
def list_alerts(klub_id: Optional[int]=None, severity: Optional[str]=None,
resolved: bool=False, limit:int=100):
where, args = ["rijeseno=%s"], [resolved]
if klub_id: where.append("klub_id=%s"); args.append(klub_id)
if severity: where.append("razina=%s"); args.append(severity.upper())
args.append(limit)
return db_query(f"""SELECT id, tip, razina, poruka, klub_id, clan_id, due_date,
iznos, datum, rijeseno, created_at
FROM pgz_sport.alertovi WHERE {' AND '.join(where)}
ORDER BY
CASE razina WHEN 'CRITICAL' THEN 1 WHEN 'WARNING' THEN 2 ELSE 3 END,
due_date NULLS LAST LIMIT %s""", args)
@router.post("/alerts/{alert_id}/resolve")
def resolve_alert(alert_id: int, user = Depends(require_user)):
db_exec("""UPDATE pgz_sport.alertovi SET rijeseno=true, rijeseno_at=now(), rijeseno_od=%s
WHERE id=%s""", (user['user_id'], alert_id))
return {"status":"ok"}
@router.post("/alerts/scan")
def trigger_scan(user = Depends(require_user)):
"""Run alert rules now."""
if not (user_has_role(user['user_id'],'super_admin') or user_has_role(user['user_id'],'pgz_admin')):
raise HTTPException(403)
return {"status":"scan_queued","note":"Scan triggers will be honoured on next cron tick"}
# ============== CLUB DASHBOARD ==============
@router.get("/klub/{klub_id}/dashboard")
def klub_dashboard(klub_id: int):
klub = db_one("SELECT * FROM pgz_sport.v_klub_full WHERE id=%s", (klub_id,))
if not klub: raise HTTPException(404)
return {
"klub": klub,
"clanovi_count": db_one("SELECT COUNT(*) AS n FROM pgz_sport.clanovi WHERE klub_id=%s AND aktivan=true", (klub_id,)),
"lijecnicki_isteka_30d": db_one("""SELECT COUNT(*) AS n FROM pgz_sport.lijecnicki_pregledi lp
JOIN pgz_sport.clanovi c ON c.id=lp.clan_id
WHERE c.klub_id=%s AND lp.vrijedi_do BETWEEN now()::date AND now()::date+interval '30 days'""", (klub_id,)),
"alerts_open": db_query("""SELECT id, tip, razina, poruka, due_date FROM pgz_sport.alertovi
WHERE klub_id=%s AND rijeseno=false ORDER BY
CASE razina WHEN 'CRITICAL' THEN 1 WHEN 'WARNING' THEN 2 ELSE 3 END LIMIT 10""", (klub_id,)),
"invoices_unpaid": db_one("""SELECT COUNT(*) AS n, COALESCE(SUM(amount_gross),0) AS sum_eur
FROM pgz_sport.invoices WHERE klub_id=%s AND payment_status='unpaid'""", (klub_id,)),
"clanarine_status": db_one("""SELECT
SUM(CASE WHEN status='podmireno' THEN 1 ELSE 0 END) AS placena,
SUM(CASE WHEN status='nepodmireno' THEN 1 ELSE 0 END) AS neplacena,
SUM(CASE WHEN status='djelomicno' THEN 1 ELSE 0 END) AS djelomicno,
COALESCE(SUM(iznos_propisan-COALESCE(iznos_placen,0)),0) AS dug_total
FROM pgz_sport.clanarine WHERE klub_id=%s AND godina=EXTRACT(year FROM now())::int""", (klub_id,)),
"form_drafts": db_query("""SELECT id, template_code, status, updated_at
FROM pgz_sport.form_submissions WHERE klub_id=%s AND status='draft'
ORDER BY updated_at DESC LIMIT 5""", (klub_id,)),
}
# ============== AI RAG SPORT AGENT ==============
class AskReq(BaseModel):
query: str
limit: int = 5
@router.post("/sport/ask")
def sport_ask(req: AskReq):
"""RAG over pgz_sport_v1 — return relevant context for an LLM."""
# Embed query
try:
r = requests.post(EMBED, json={"input":[req.query, req.query]}, timeout=30)
j = r.json()
emb = j.get('embeddings', [j.get('embedding')])[0]
except Exception as e:
raise HTTPException(503, f"Embedder unavailable: {e}")
# Search qdrant
r = requests.post(f"{QDRANT}/collections/{COLL}/points/search",
json={"vector": emb, "limit": req.limit, "with_payload": True}, timeout=30)
if r.status_code >= 400: raise HTTPException(503, f"Qdrant: {r.text[:200]}")
hits = r.json()['result']
return {
"query": req.query,
"results": [
{"score": h['score'],
"type": h['payload'].get('tip', h['payload'].get('type')),
"title": h['payload'].get('naziv') or h['payload'].get('title') or '?',
"snippet": (h['payload'].get('tekst') or '')[:500],
"payload": {k:v for k,v in h['payload'].items() if k != 'tekst'}}
for h in hits
]
}
# ============== CALENDAR / SCHEDULE ==============
@router.post("/sport/lawyer")
def sport_lawyer(payload: dict):
"""
AI Pravnik — odgovara na sve pravne, regulatorne i proceduralne nedoumice
iz pravilnika HOO, MINT, županije i klubova. Koristi RAG + DeepSeek/Groq LLM.
"""
q = (payload.get("query") or payload.get("question") or "").strip()
if not q:
raise HTTPException(400, "query je prazan")
# 1) RAG v2 — Fetch 25 candidates → dedup → top 6 unique docs
import requests as _requests
try:
emb_r = _requests.post(
"http://localhost:9879/api/embeddings",
json={"input": [q]}, timeout=20
)
if not emb_r.ok:
raise HTTPException(500, f"embed failed: {emb_r.status_code}")
_r = emb_r.json(); emb = _r.get("embedding") or _r.get("embeddings",[None])[0]
except Exception as e:
raise HTTPException(500, f"embedding error: {e}")
# Fetch 25 candidates (will dedup)
try:
qr = _requests.post(
"http://10.10.0.2:6333/collections/pgz_sport_v1/points/search",
json={"vector": emb, "limit": 25, "with_payload": True, "score_threshold": 0.35},
timeout=20
)
if not qr.ok:
raise HTTPException(500, f"qdrant http {qr.status_code}: {qr.text[:200]}")
all_hits = qr.json().get("result", [])
except HTTPException: raise
except Exception as e:
raise HTTPException(500, f"qdrant error: {e}")
if not all_hits:
return {"query": q, "answer": "Nema relevantnih pravilnika u bazi za ovaj upit. Probaj preformulirati pitanje konkretnije, npr. uključi specifičan sport, godinu, ili tip dokumenta (pravilnik, zakon, kriterij).", "sources": []}
# 2) Dedup by document — keep top chunk per unique doc_id/title (not all chunks of same doc)
seen_docs = {} # key = doc_id or normalized title
for h in all_hits:
p = h.get("payload") or {}
# Normalize doc identity
doc_key = p.get("doc_id") or p.get("source_url") or p.get("title", "?")
if doc_key not in seen_docs or h.get("score", 0) > seen_docs[doc_key].get("score", 0):
seen_docs[doc_key] = h
# Sort by score, take top 6 unique docs
unique_hits = sorted(seen_docs.values(), key=lambda x: x.get("score", 0), reverse=True)[:6]
hits = unique_hits
# 3) PGŽ-relevance boost: prefer PGŽ-specific docs over general national
PGZ_KW = ['pgž','pgz','primorsk','rijeka','kvarner','crikvenic','opatij','krk','cres','lošinj','rab']
def pgz_boost(h):
p = h.get("payload") or {}
all_t = ((p.get("title","") or "") + " " + (p.get("text","")[:300] or "") + " " + (p.get("source_url","") or "")).lower()
if any(k in all_t for k in PGZ_KW):
return h.get("score", 0) * 1.15 # 15% boost
return h.get("score", 0)
hits = sorted(hits, key=pgz_boost, reverse=True)
# 4) Build context with metadata
ctx_chunks = []
sources = []
for i, h in enumerate(hits):
p = h.get("payload") or {}
text = (p.get("text") or "")[:1200] # more context per chunk
title = p.get("title", "(bez naslova)")
url = p.get("source_url") or p.get("url", "")
doc_type = p.get("doc_type", "")
publish_date = p.get("publish_date", "")
source = p.get("source", "")
date_str = f", {publish_date[:10]}" if publish_date else ""
if text and len(text) > 50:
ctx_chunks.append(f"[{i+1}] {title}{date_str} ({doc_type or source}):\n{text}")
sources.append({
"id": i+1, "title": title, "url": url,
"doc_type": doc_type, "publish_date": publish_date,
"source": source, "score": round(float(h.get("score", 0)), 3)
})
context = "\n\n".join(ctx_chunks)
# 3) LLM call — DeepSeek primary
SYSTEM = """Ti si AI PRAVNIK Zajednice sportova Primorsko-goranske županije (ZSPGŽ).
Specijaliziran si za hrvatsko sportsko pravo i propise koje primjenjuje ZSPGŽ.
ZNANJE TI DOLAZI ISKLJUČIVO IZ PRILOŽENIH IZVORA. Nikada ne izmišljaj ni datume ni iznose ni članke.
PRAVILA ODGOVORA:
1. KRATAK DIREKTAN ODGOVOR PRVI (1-3 rečenice). Što tražitelj treba znati odmah.
2. DETALJI: konkretni iznosi, rokovi, članci pravilnika, postupci. Citiraj BROJEVE [1], [2]... za svaki podatak.
3. AKO INFORMACIJA NIJE U IZVORIMA: jasno kaži "Ovo pitanje nije pokriveno priloženim pravilnicima — preporučujem provjeru izravno na sport-pgz.hr ili kod nadležne osobe."
4. AKO POSTOJE SLIČNI ALI NE IDENTIČNI PRAVILNICI: navedi razliku jasno.
5. PRIORITET: ZSPGŽ pravilnici > PGŽ županijski > nacionalni HOO/MINT > zakonski tekst.
6. STIL: stručan, ali razumljiv. Hrvatski jezik. Bez fraza poput "kako je navedeno" — direktno citiraj.
7. NE PONAVLJAJ pitanje. Ne počinji s "Prema priloženim pravilnicima..." — direktno na odgovor.
FORMAT:
**Odgovor:** [1-3 rečenice s ključnim podacima i [1] referencama]
**Detalji:**
- [bullet] [konkretan podatak] [referenca]
- [bullet] [postupak] [referenca]
**Reference:** [auto generirano ispod, ne pisati u odgovoru]
Ako tražitelj pita o konkretnom iznosu/rokovima a nemaš to u izvorima, **nemoj nagađati** — kaži da nisi siguran i preporuči direktan kontakt."""
user_msg = f"PITANJE: {q}\n\nPRILOŽENI PRAVILNICI/IZVORI:\n{context}\n\nODGOVOR (sa referencama [1], [2]...):"
answer = ""
llm_used = "none"
# Try DeepSeek
try:
ds_key = os.environ.get("DEEPSEEK_API_KEY")
if ds_key:
r = _requests.post(
"https://api.deepseek.com/v1/chat/completions",
headers={"Authorization": f"Bearer {ds_key}"},
json={
"model": "deepseek-chat",
"messages": [
{"role": "system", "content": SYSTEM},
{"role": "user", "content": user_msg},
],
"temperature": 0.15,
"max_tokens": 2000,
},
timeout=60,
)
if r.ok:
answer = r.json()["choices"][0]["message"]["content"]
llm_used = "deepseek"
except Exception as e:
pass
# Fallback Groq
if not answer:
try:
gk = os.environ.get("GROQ_API_KEY")
if gk:
r = _requests.post(
"https://api.groq.com/openai/v1/chat/completions",
headers={"Authorization": f"Bearer {gk}"},
json={
"model": "llama-3.3-70b-versatile",
"messages": [
{"role": "system", "content": SYSTEM},
{"role": "user", "content": user_msg},
],
"temperature": 0.15,
"max_tokens": 2000,
},
timeout=60,
)
if r.ok:
answer = r.json()["choices"][0]["message"]["content"]
llm_used = "groq"
except Exception as e:
pass
# Local Ollama fallback
if not answer:
try:
r = _requests.post(
"http://localhost:11434/api/chat",
json={
"model": "qwen2.5:7b",
"messages": [
{"role": "system", "content": SYSTEM},
{"role": "user", "content": user_msg},
],
"stream": False,
"options": {"temperature": 0.15, "num_predict": 1500},
},
timeout=120,
)
if r.ok:
answer = r.json().get("message", {}).get("content", "")
llm_used = "ollama_qwen2.5"
except Exception:
pass
if not answer:
# No LLM available — return pure RAG with notice
answer = "**[LLM nije dostupan, evo top relevantnih izvora:]**\n\n"
for i, src_item in enumerate(sources[:3], 1):
answer += f"**[{i}] {src_item['title']}**\n"
answer += f"_{src_item.get('doc_type','')}, score={src_item['score']:.2f}_\n\n"
llm_used = "rag_only"
# Audit
try:
from psycopg2 import connect
conn = connect(host='localhost', dbname='rinet_v3', user='rinet', password='R1net2026!SecureDB#v7')
cu = conn.cursor()
cu.execute("""INSERT INTO pgz_sport.sys_audit (action, target_type, target_text, payload)
VALUES (%s,%s,%s,%s::jsonb)""",
('lawyer.query', 'sport_lawyer', q[:500],
json.dumps({"llm": llm_used, "hits": len(hits), "sources": len(sources)})))
conn.commit(); conn.close()
except Exception:
pass
return {
"query": q,
"answer": answer,
"sources": sources,
"llm": llm_used,
"hits_count": len(hits),
}
@router.get("/calendar/upcoming")
def calendar_upcoming(klub_id: Optional[int]=None, days_ahead: int=30):
end = datetime.now() + timedelta(days=days_ahead)
out = []
# Liječnički pregledi koji ističu
where = ""; args = []
if klub_id:
where = "AND c.klub_id=%s"; args = [klub_id]
args = [end] + args
rows = db_query(f"""SELECT 'lijecnicki_istek' AS type,
'Liječnički istječe — '||c.ime||' '||c.prezime AS title,
lp.vrijedi_do AS date, c.klub_id, lp.clan_id, k.naziv AS klub_naziv
FROM pgz_sport.lijecnicki_pregledi lp
JOIN pgz_sport.clanovi c ON c.id=lp.clan_id
LEFT JOIN pgz_sport.klubovi k ON k.id=c.klub_id
WHERE lp.vrijedi_do BETWEEN now()::date AND %s::date {where}
ORDER BY lp.vrijedi_do""", args)
out.extend(rows)
# Računi koji dospijevaju
args2 = [end]
if klub_id: args2.append(klub_id)
where2 = " AND klub_id=%s" if klub_id else ""
rows = db_query(f"""SELECT 'invoice_due' AS type,
'Račun '||invoice_no||' — '||COALESCE(vendor_name,'?')||' — '||amount_gross::text||' EUR' AS title,
due_date AS date, klub_id, NULL::int AS clan_id, NULL::text AS klub_naziv
FROM pgz_sport.invoices WHERE due_date BETWEEN now()::date AND %s::date
AND payment_status='unpaid'{where2}
ORDER BY due_date""", args2)
out.extend(rows)
# Alerts otvorene
args3 = [end]
if klub_id: args3.append(klub_id)
where3 = " AND klub_id=%s" if klub_id else ""
rows = db_query(f"""SELECT 'alert' AS type, poruka AS title, due_date AS date,
klub_id, clan_id, NULL::text FROM pgz_sport.alertovi
WHERE rijeseno=false AND due_date IS NOT NULL AND due_date<=%s::date{where3}
ORDER BY due_date""", args3)
out.extend(rows)
return sorted(out, key=lambda x: x.get('date') or date.max)
# ============== EKOSUSTAV STATS (extended) ==============
@router.get("/ekosustav/v2")
def ekosustav_v2():
return {
"savezi": db_one("""SELECT
COUNT(*) AS total,
COUNT(*) FILTER (WHERE razina='nacional') AS nacional,
COUNT(*) FILTER (WHERE razina='zupanijski') AS zupanijski,
COUNT(*) FILTER (WHERE razina='gradski') AS gradski
FROM pgz_sport.savezi"""),
"klubovi": db_one("""SELECT
COUNT(*) AS total,
COUNT(oib) AS s_oib,
COUNT(*) FILTER (WHERE entity_id IS NOT NULL) AS linked
FROM pgz_sport.klubovi"""),
"documents": db_one("""SELECT
COUNT(*) AS total,
COUNT(*) FILTER (WHERE LENGTH(COALESCE(text_extracted,''))>=200) AS extracted
FROM sport.documents"""),
"qdrant_points": (lambda: requests.get(f"{QDRANT}/collections/{COLL}").json()['result']['points_count'])(),
"users": db_one("""SELECT COUNT(*) FROM pgz_sport.users WHERE status='active'"""),
"alerts_open": db_one("""SELECT
COUNT(*) FILTER (WHERE razina='CRITICAL') AS critical,
COUNT(*) FILTER (WHERE razina='WARNING') AS warning,
COUNT(*) FILTER (WHERE razina='INFO') AS info
FROM pgz_sport.alertovi WHERE rijeseno=false"""),
"forms_templates": db_one("SELECT COUNT(*) FROM pgz_sport.form_templates WHERE active=true"),
"invoices": db_one("""SELECT
COUNT(*) AS total,
COUNT(*) FILTER (WHERE payment_status='unpaid') AS unpaid,
COALESCE(SUM(amount_gross),0)::numeric AS total_eur
FROM pgz_sport.invoices"""),
}
# =========== MULTIPART UPLOAD + USER CREATE (added 28apr) ===========
UPLOAD_DIR = "/var/lib/pgz-sport/invoices"
os.makedirs(UPLOAD_DIR, exist_ok=True)
@router.post("/invoice-uploads/file")
async def upload_invoice_file(
file: UploadFile = File(...),
klub_id: int = Form(...),
invoice_kind: str = Form("ulazni"),
user = Depends(require_user)
):
"""Multipart upload — saves to disk + queues for OCR."""
if not (user_has_role(user['user_id'],'super_admin') or
user_has_role(user['user_id'],'klub_admin','klub',klub_id) or
user_has_role(user['user_id'],'klub_user','klub',klub_id)):
raise HTTPException(403, "Forbidden")
raw = await file.read()
sha = hashlib.sha256(raw).hexdigest()
safe = re.sub(r'[^a-zA-Z0-9._-]','_', file.filename or 'invoice')
path = f"{UPLOAD_DIR}/{klub_id}_{int(time.time())}_{sha[:8]}_{safe}"
with open(path, 'wb') as f:
f.write(raw)
uid = db_exec("""INSERT INTO pgz_sport.invoice_uploads
(klub_id, uploaded_by, file_name, file_path, file_size, mime, sha256, ocr_status)
VALUES (%s,%s,%s,%s,%s,%s,%s,'pending') RETURNING id""",
(klub_id, user['user_id'], file.filename, path, len(raw), file.content_type, sha))
db_exec("INSERT INTO pgz_sport.audit_events(user_id,action,resource_type,resource_id,meta) VALUES (%s,'upload_invoice','invoice_upload',%s,%s)",
(user['user_id'], uid, json.dumps({'klub_id':klub_id,'kind':invoice_kind,'sha':sha[:16]})))
return {"upload_id": uid, "ocr_status": "pending", "klub_id": klub_id, "size": len(raw), "sha": sha[:16]}
# =========== USER CREATE (simple, no token required from super_admin via API) ===========
class CreateUserReq(BaseModel):
email: str
full_name: Optional[str] = None
password: str
role: str = "viewer"
klub_id: Optional[int] = None
oib: Optional[str] = None
phone: Optional[str] = None
@router.post("/users")
def api_create_user(req: CreateUserReq, user = Depends(require_user)):
"""Create new user. Requires super_admin or pgz_admin or klub_admin."""
if not (user_has_role(user['user_id'],'super_admin') or
user_has_role(user['user_id'],'pgz_admin') or
(req.klub_id and user_has_role(user['user_id'],'klub_admin','klub',req.klub_id))):
raise HTTPException(403, "Need super_admin/pgz_admin/klub_admin")
# Existing user?
existing = db_one("SELECT id FROM pgz_sport.users WHERE email=%s", (req.email,))
if existing:
raise HTTPException(409, f"User {req.email} already exists (id={existing['id']})")
# Create
uid = db_exec("""INSERT INTO pgz_sport.users (email, full_name, oib, phone, password_hash, status)
VALUES (%s,%s,%s,%s,%s,'active') RETURNING id""",
(req.email, req.full_name, req.oib, req.phone, hash_pw(req.password)))
# Assign role
role_row = db_one("SELECT id FROM pgz_sport.roles WHERE code=%s", (req.role,))
if role_row:
scope = ('klub', req.klub_id) if req.klub_id else ('global', None)
db_exec("""INSERT INTO pgz_sport.user_roles (user_id, role_id, scope_type, scope_id, granted_by, active)
VALUES (%s,%s,%s,%s,%s,true)""",
(uid, role_row['id'], scope[0], scope[1], user['user_id']))
db_exec("INSERT INTO pgz_sport.audit_events(user_id,action,resource_type,resource_id,meta) VALUES (%s,'create_user','user',%s,%s)",
(user['user_id'], uid, json.dumps({'email':req.email,'role':req.role,'klub_id':req.klub_id})))
return {"user_id": uid, "email": req.email, "role": req.role, "klub_id": req.klub_id}
@@ -0,0 +1,546 @@
--
-- PostgreSQL database dump
--
\restrict h6bd7kGvxEavN2pokB3ndj68pJKRaJXQanRfq1xgOELkeOAc9Wagkc4WNCfcjsu
-- Dumped from database version 18.3 (Ubuntu 18.3-1.pgdg24.04+1)
-- Dumped by pg_dump version 18.3 (Ubuntu 18.3-1.pgdg24.04+1)
SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET transaction_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET xmloption = content;
SET client_min_messages = warning;
SET row_security = off;
--
-- Data for Name: users; Type: TABLE DATA; Schema: pgz_sport; Owner: rinet
--
INSERT INTO pgz_sport.users (id, email, full_name, oib, phone, password_hash, google_sub, google_picture, status, email_verified, billing_user_id, preferred_language, last_login, created_at, updated_at) VALUES (1, 'damir@rinet.one', 'Damir Radulić', NULL, NULL, '85fa650a5b0eccda59a31462d3c47b17c006457128463e6f9d1dfef1a58775b8', NULL, NULL, 'active', true, NULL, 'hr', '2026-04-28 20:07:02.031202+02', '2026-04-28 19:45:29.031684+02', '2026-04-28 19:45:29.031684+02');
--
-- Data for Name: audit_events; Type: TABLE DATA; Schema: pgz_sport; Owner: rinet
--
INSERT INTO pgz_sport.audit_events (id, user_id, action, resource_type, resource_id, meta, ip_address, user_agent, ts) VALUES (1, 1, 'init_multitenant', 'system', NULL, '{"sprint": "28apr2026_v3"}', NULL, NULL, '2026-04-28 19:45:29.035228+02');
INSERT INTO pgz_sport.audit_events (id, user_id, action, resource_type, resource_id, meta, ip_address, user_agent, ts) VALUES (2, 1, 'login', NULL, NULL, NULL, NULL, NULL, '2026-04-28 19:59:05.376178+02');
INSERT INTO pgz_sport.audit_events (id, user_id, action, resource_type, resource_id, meta, ip_address, user_agent, ts) VALUES (3, 1, 'login', NULL, NULL, NULL, NULL, NULL, '2026-04-28 20:06:03.826532+02');
INSERT INTO pgz_sport.audit_events (id, user_id, action, resource_type, resource_id, meta, ip_address, user_agent, ts) VALUES (4, 1, 'login', NULL, NULL, NULL, NULL, NULL, '2026-04-28 20:06:31.911253+02');
INSERT INTO pgz_sport.audit_events (id, user_id, action, resource_type, resource_id, meta, ip_address, user_agent, ts) VALUES (5, 1, 'login', NULL, NULL, NULL, NULL, NULL, '2026-04-28 20:07:02.040007+02');
INSERT INTO pgz_sport.audit_events (id, user_id, action, resource_type, resource_id, meta, ip_address, user_agent, ts) VALUES (6, 1, 'upload_invoice', 'invoice_upload', 1, '{"sha": "c428f6c87073e866", "kind": "ulazni", "klub_id": 524}', NULL, NULL, '2026-04-28 20:07:02.100652+02');
--
-- Data for Name: audit_log; Type: TABLE DATA; Schema: pgz_sport; Owner: rinet
--
INSERT INTO pgz_sport.audit_log (id, "timestamp", tablica, operacija, record_id, korisnik, ip, promijenjeno_polje, stara_vrijednost, nova_vrijednost) VALUES (1, '2026-04-25 16:52:36.922732+02', 'klubovi', 'UPDATE', NULL, 'damir', NULL, 'predsjednik', NULL, 'NULL (verifikacija potrebna)');
--
-- Data for Name: roles; Type: TABLE DATA; Schema: pgz_sport; Owner: rinet
--
INSERT INTO pgz_sport.roles (id, code, naziv, opis, permissions, created_at) VALUES (1, 'super_admin', 'Super Admin', 'Pun pristup sistemu', '{"all": true}', '2026-04-28 19:45:28.993151+02');
INSERT INTO pgz_sport.roles (id, code, naziv, opis, permissions, created_at) VALUES (2, 'pgz_admin', 'PGŽ Admin', 'PGŽ-level administracija', '{"pgz_admin": true, "klubovi_view": true, "savezi_admin": true, "proracun_admin": true}', '2026-04-28 19:45:28.995845+02');
INSERT INTO pgz_sport.roles (id, code, naziv, opis, permissions, created_at) VALUES (3, 'savez_admin', 'Savez Admin', 'Administrator saveza', '{"savez_admin": true, "klubovi_savez": true}', '2026-04-28 19:45:28.996447+02');
INSERT INTO pgz_sport.roles (id, code, naziv, opis, permissions, created_at) VALUES (4, 'klub_admin', 'Klub Admin', 'Administrator kluba', '{"klub_admin": true, "forms_submit": true, "clanovi_admin": true, "invoice_admin": true}', '2026-04-28 19:45:28.996848+02');
INSERT INTO pgz_sport.roles (id, code, naziv, opis, permissions, created_at) VALUES (5, 'klub_user', 'Klub User', 'Redovni korisnik kluba (trener, tajnik)', '{"klub_view": true, "clanovi_view": true, "forms_submit": true}', '2026-04-28 19:45:28.997157+02');
INSERT INTO pgz_sport.roles (id, code, naziv, opis, permissions, created_at) VALUES (6, 'clan', 'Član', 'Sportaš/član kluba', '{"self_view": true, "forms_my_submit": true}', '2026-04-28 19:45:28.997444+02');
INSERT INTO pgz_sport.roles (id, code, naziv, opis, permissions, created_at) VALUES (7, 'viewer', 'Viewer', 'Read-only public access', '{"public_view": true}', '2026-04-28 19:45:28.997746+02');
--
-- Data for Name: sys_users; Type: TABLE DATA; Schema: pgz_sport; Owner: rinet
--
INSERT INTO pgz_sport.sys_users (id, email, password_hash, ime, prezime, oib, telefon, user_type, klub_id, savez_id, permissions, aktivan, last_login, failed_login_count, locked_until, auth_provider, google_sub, created_at, updated_at, created_by, note) VALUES (1, 'damir@rinet.one', '5fc66857e7c07f685c6d1a64594983c568628619f273b509ddb3e6b44d0cba11', 'Damir', 'Radulić', NULL, NULL, 'super_admin', NULL, NULL, '{}', true, NULL, 0, NULL, 'local', NULL, '2026-04-28 21:23:00.931158+02', '2026-04-28 21:23:00.931158+02', NULL, NULL);
INSERT INTO pgz_sport.sys_users (id, email, password_hash, ime, prezime, oib, telefon, user_type, klub_id, savez_id, permissions, aktivan, last_login, failed_login_count, locked_until, auth_provider, google_sub, created_at, updated_at, created_by, note) VALUES (2, 'pgz.lukanovic@pgz.hr', '45bbcdc6bbc5af630845f6a1cd1bc3d24aeca58b38d017ae4d9b13c64e0fb5f4', 'Zlatko', 'Lukanović', NULL, NULL, 'pgz_admin', NULL, NULL, '{}', true, NULL, 0, NULL, 'local', NULL, '2026-04-28 21:45:42.429263+02', '2026-04-28 21:45:42.429263+02', NULL, NULL);
INSERT INTO pgz_sport.sys_users (id, email, password_hash, ime, prezime, oib, telefon, user_type, klub_id, savez_id, permissions, aktivan, last_login, failed_login_count, locked_until, auth_provider, google_sub, created_at, updated_at, created_by, note) VALUES (3, 'pgz.djelatnik@pgz.hr', 'd5ddd74b31dfff17de8ee6ec25a8d5f5310326cfb99d64c1822cd17a3372b10f', 'Marija', 'Horvat', NULL, NULL, 'pgz_user', NULL, NULL, '{}', true, NULL, 0, NULL, 'local', NULL, '2026-04-28 21:45:42.429263+02', '2026-04-28 21:45:42.429263+02', NULL, NULL);
INSERT INTO pgz_sport.sys_users (id, email, password_hash, ime, prezime, oib, telefon, user_type, klub_id, savez_id, permissions, aktivan, last_login, failed_login_count, locked_until, auth_provider, google_sub, created_at, updated_at, created_by, note) VALUES (4, 'pgz.finance@pgz.hr', 'e514f457534678f6184923cabe6bc215d3284ebea61bce5ac1974047b5810e19', 'Ivana', 'Babić', NULL, NULL, 'pgz_finance', NULL, NULL, '{}', true, NULL, 0, NULL, 'local', NULL, '2026-04-28 21:45:42.429263+02', '2026-04-28 21:45:42.429263+02', NULL, NULL);
INSERT INTO pgz_sport.sys_users (id, email, password_hash, ime, prezime, oib, telefon, user_type, klub_id, savez_id, permissions, aktivan, last_login, failed_login_count, locked_until, auth_provider, google_sub, created_at, updated_at, created_by, note) VALUES (5, 'zzjz.medical@zzjzpgz.hr', '4b424ae34fd87c560677419dfced9228f339a5e844bad2434ce53c5b536a1984', 'Marko', 'Petković', NULL, NULL, 'pgz_zzjz', NULL, NULL, '{}', true, NULL, 0, NULL, 'local', NULL, '2026-04-28 21:45:42.429263+02', '2026-04-28 21:45:42.429263+02', NULL, NULL);
INSERT INTO pgz_sport.sys_users (id, email, password_hash, ime, prezime, oib, telefon, user_type, klub_id, savez_id, permissions, aktivan, last_login, failed_login_count, locked_until, auth_provider, google_sub, created_at, updated_at, created_by, note) VALUES (6, 'tajnik.hnk@rijeka.hr', 'febbab33206be19b0cc37e62bc68330a0f2f4648bcec27df1eaea492c689d56d', 'Pero', 'Kvaternik', NULL, NULL, 'savez_admin', NULL, 1, '{}', true, NULL, 0, NULL, 'local', NULL, '2026-04-28 21:45:42.429263+02', '2026-04-28 21:45:42.429263+02', NULL, NULL);
INSERT INTO pgz_sport.sys_users (id, email, password_hash, ime, prezime, oib, telefon, user_type, klub_id, savez_id, permissions, aktivan, last_login, failed_login_count, locked_until, auth_provider, google_sub, created_at, updated_at, created_by, note) VALUES (7, 'tajnik.kvarner@kk.hr', 'dd7718a2c5efe8f3ac27bd6259925e11223603b643bfae56d8ab8f189bbe3c77', 'Ana', 'Marković', NULL, NULL, 'klub_admin', NULL, NULL, '{}', true, NULL, 0, NULL, 'local', NULL, '2026-04-28 21:45:42.429263+02', '2026-04-28 21:45:42.429263+02', NULL, NULL);
INSERT INTO pgz_sport.sys_users (id, email, password_hash, ime, prezime, oib, telefon, user_type, klub_id, savez_id, permissions, aktivan, last_login, failed_login_count, locked_until, auth_provider, google_sub, created_at, updated_at, created_by, note) VALUES (8, 'tajnik.zamet@rk.hr', 'cdce1c4405f83116caa34ed6ca1cd1b73a0bca0a0ab443ad73e09ae36c150332', 'Davor', 'Šimunović', NULL, NULL, 'klub_admin', NULL, NULL, '{}', true, NULL, 0, NULL, 'local', NULL, '2026-04-28 21:45:42.429263+02', '2026-04-28 21:45:42.429263+02', NULL, NULL);
INSERT INTO pgz_sport.sys_users (id, email, password_hash, ime, prezime, oib, telefon, user_type, klub_id, savez_id, permissions, aktivan, last_login, failed_login_count, locked_until, auth_provider, google_sub, created_at, updated_at, created_by, note) VALUES (9, 'sportas.test@example.hr', 'dcc140499509d64cd1b954c5efd12f933be898b21360684f33a09892f6febda1', 'Luka', 'Modrić', NULL, NULL, 'klub_clan', NULL, NULL, '{}', true, NULL, 0, NULL, 'local', NULL, '2026-04-28 21:45:42.429263+02', '2026-04-28 21:45:42.429263+02', NULL, NULL);
--
-- Data for Name: sys_audit; Type: TABLE DATA; Schema: pgz_sport; Owner: rinet
--
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (1, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Kako kategorizirati odbojkaša prema HOO pravilniku?', '{"llm": "deepseek", "hits": 8, "sources": 5}', NULL, NULL, '2026-04-28 21:39:45.81286+02', 'GENESIS_PGZ_SPORT_2026', 'cc82c5087a3570f52dd415777fbd6c089ae012d0eaf5a653a0ab82472f3020ef', 1);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (2, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Koji su uvjeti za sufinanciranje sportskog programa iz proračuna PGŽ?', '{"llm": "deepseek", "hits": 8, "sources": 3}', NULL, NULL, '2026-04-28 21:46:05.779942+02', 'cc82c5087a3570f52dd415777fbd6c089ae012d0eaf5a653a0ab82472f3020ef', 'ae124a80e32f70f9dc791483b8c933a55e9f7af1c7a0d9a54cc10bd8eda2e0e8', 2);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (3, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Kako kategorizirati odbojkaša prema HOO pravilniku?', '{"llm": "deepseek", "hits": 8, "sources": 5}', NULL, NULL, '2026-04-28 21:46:37.649209+02', 'ae124a80e32f70f9dc791483b8c933a55e9f7af1c7a0d9a54cc10bd8eda2e0e8', '86cb095dfa4f3bbc2dd259947c3cef9ea2aa8c4ecf40bf9d0ef30eab3e4dadc5', 3);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (4, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Koji su uvjeti za sufinanciranje sportskog programa iz proračuna PGŽ?', '{"llm": "deepseek", "hits": 8, "sources": 3}', NULL, NULL, '2026-04-28 21:46:47.068418+02', '86cb095dfa4f3bbc2dd259947c3cef9ea2aa8c4ecf40bf9d0ef30eab3e4dadc5', 'b9116496dc8b9cac2e767badabe2c72c423cec1542976e5c4f8dbdad9a6ffbf9', 4);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (5, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Koliko često sportaš mora obaviti liječnički pregled?', '{"llm": "deepseek", "hits": 8, "sources": 3}', NULL, NULL, '2026-04-28 21:46:56.756009+02', 'b9116496dc8b9cac2e767badabe2c72c423cec1542976e5c4f8dbdad9a6ffbf9', '8d3bcc90bbed7af23368f95e863f89b34e78c47113b4fbe847942e4c77778590', 5);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (6, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Što je potrebno za prijavu sportaša u registar HNS-a?', '{"llm": "deepseek", "hits": 8, "sources": 3}', NULL, NULL, '2026-04-28 21:47:04.350552+02', '8d3bcc90bbed7af23368f95e863f89b34e78c47113b4fbe847942e4c77778590', '0ad5b22b886053460a6e18851fa5ef05ac71806b12d11e939fc1c93f936a6a62', 6);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (7, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Koje su obveze tajnika kluba za godišnje izvješće?', '{"llm": "deepseek", "hits": 8, "sources": 3}', NULL, NULL, '2026-04-28 21:47:13.828479+02', '0ad5b22b886053460a6e18851fa5ef05ac71806b12d11e939fc1c93f936a6a62', '5aa179cbae51ddebb02b5ae549b7f233b4967284fd364fd37eb9bf44baeb76c7', 7);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (8, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Tko određuje koeficijent kategorije kluba u PGŽ?', '{"llm": "deepseek", "hits": 8, "sources": 4}', NULL, NULL, '2026-04-28 21:47:23.951591+02', '5aa179cbae51ddebb02b5ae549b7f233b4967284fd364fd37eb9bf44baeb76c7', '1e8d26932869e7f9b90bbc5477746b10e8944e847741dc896181feb768ae4d49', 8);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (9, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Što sadrži program javnih potreba u sportu Grada Rijeke?', '{"llm": "deepseek", "hits": 8, "sources": 4}', NULL, NULL, '2026-04-28 21:47:32.010763+02', '1e8d26932869e7f9b90bbc5477746b10e8944e847741dc896181feb768ae4d49', '7805ef3f6fd232a311a38e2af1a60bc36cbd11007abd3d2faa9a5f989764be70', 9);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (10, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Kakve su sankcije za doping u atletici?', '{"llm": "deepseek", "hits": 8, "sources": 5}', NULL, NULL, '2026-04-28 21:47:39.708735+02', '7805ef3f6fd232a311a38e2af1a60bc36cbd11007abd3d2faa9a5f989764be70', '4ee545b511e94de55d1a5af71cf1058fed682c39289d87b54fddf7301d8ce813', 10);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (11, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Kako kategorizirati odbojkaša prema HOO pravilniku?', '{"llm": "deepseek", "hits": 8, "sources": 5}', NULL, NULL, '2026-04-28 21:47:40.899276+02', '4ee545b511e94de55d1a5af71cf1058fed682c39289d87b54fddf7301d8ce813', '51b8330a091c8b3f17784bf707f7d52c79808fe571269ce08e89957769b3005b', 11);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (12, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Koji su uvjeti za sufinanciranje sportskog programa iz proračuna PGŽ?', '{"llm": "deepseek", "hits": 8, "sources": 3}', NULL, NULL, '2026-04-28 21:47:49.600982+02', '51b8330a091c8b3f17784bf707f7d52c79808fe571269ce08e89957769b3005b', '3394dd1b1b9fcf749a5ffc1351a6202dd954d9e674ea186c15d63dff50097998', 12);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (13, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Koliko često sportaš mora obaviti liječnički pregled?', '{"llm": "deepseek", "hits": 8, "sources": 3}', NULL, NULL, '2026-04-28 21:47:57.331833+02', '3394dd1b1b9fcf749a5ffc1351a6202dd954d9e674ea186c15d63dff50097998', '4e5b8514b9a943fd83e3537eff4066605fc9e38b612879dc36f7ff09a929c91b', 13);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (14, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Što je potrebno za prijavu sportaša u registar HNS-a?', '{"llm": "deepseek", "hits": 8, "sources": 3}', NULL, NULL, '2026-04-28 21:48:04.700253+02', '4e5b8514b9a943fd83e3537eff4066605fc9e38b612879dc36f7ff09a929c91b', '3dda986771ad3aa2314856a635c88d38ff700d3fcf2c608cc4ada0ff16da04cd', 14);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (15, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Koje su obveze tajnika kluba za godišnje izvješće?', '{"llm": "deepseek", "hits": 8, "sources": 3}', NULL, NULL, '2026-04-28 21:48:14.644534+02', '3dda986771ad3aa2314856a635c88d38ff700d3fcf2c608cc4ada0ff16da04cd', '8d3ddcdd1363f1467e5a4cc76caf3e8a93af5629c02f9c3f9924c60743f0e62d', 15);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (16, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Tko određuje koeficijent kategorije kluba u PGŽ?', '{"llm": "deepseek", "hits": 8, "sources": 4}', NULL, NULL, '2026-04-28 21:48:24.08297+02', '8d3ddcdd1363f1467e5a4cc76caf3e8a93af5629c02f9c3f9924c60743f0e62d', 'ce2504a50ff9c50cbed6c51a86e7569c06ff2c71df9ca153dfe39b41364cfa08', 16);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (17, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Što sadrži program javnih potreba u sportu Grada Rijeke?', '{"llm": "deepseek", "hits": 8, "sources": 4}', NULL, NULL, '2026-04-28 21:48:31.975034+02', 'ce2504a50ff9c50cbed6c51a86e7569c06ff2c71df9ca153dfe39b41364cfa08', '45e1e0cf3a70b956e302b34f513d074eb9f961990681c49a1145cb346b509824', 17);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (18, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Kakve su sankcije za doping u atletici?', '{"llm": "deepseek", "hits": 8, "sources": 5}', NULL, NULL, '2026-04-28 21:48:39.350733+02', '45e1e0cf3a70b956e302b34f513d074eb9f961990681c49a1145cb346b509824', '3846ce48e8fa4a0ff9bb042dcfaaee3bad6b9087b063a7a2bb39adf335f54b86', 18);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (19, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Kako kategorizirati odbojkaša prema HOO pravilniku?', '{"llm": "deepseek", "hits": 8, "sources": 5}', NULL, NULL, '2026-04-28 21:48:44.715048+02', '3846ce48e8fa4a0ff9bb042dcfaaee3bad6b9087b063a7a2bb39adf335f54b86', 'ddd196100d1c72ed3af17f78be88c6fe04ce4a208d8877d2555e714ab405b9ac', 19);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (20, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Koji su uvjeti za sufinanciranje sportskog programa iz proračuna PGŽ?', '{"llm": "deepseek", "hits": 8, "sources": 3}', NULL, NULL, '2026-04-28 21:48:55.385108+02', 'ddd196100d1c72ed3af17f78be88c6fe04ce4a208d8877d2555e714ab405b9ac', '74f8507064b98def8f87aac011d6742d95c9c39c8bbe3eed2229e74d39ddaaac', 20);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (21, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Koliko često sportaš mora obaviti liječnički pregled?', '{"llm": "deepseek", "hits": 8, "sources": 3}', NULL, NULL, '2026-04-28 21:49:05.94362+02', '74f8507064b98def8f87aac011d6742d95c9c39c8bbe3eed2229e74d39ddaaac', 'c2a29416d62a9ce4b34909dea5b8b7568be40e4f5632d54c7690f0114cc0e837', 21);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (22, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Što je potrebno za prijavu sportaša u registar HNS-a?', '{"llm": "deepseek", "hits": 8, "sources": 3}', NULL, NULL, '2026-04-28 21:49:13.081573+02', 'c2a29416d62a9ce4b34909dea5b8b7568be40e4f5632d54c7690f0114cc0e837', 'b77322c90763ca697ec06818af1f92df98d4936b3476ea3152e77151fd842be1', 22);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (23, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Koje su obveze tajnika kluba za godišnje izvješće?', '{"llm": "deepseek", "hits": 8, "sources": 3}', NULL, NULL, '2026-04-28 21:49:22.979803+02', 'b77322c90763ca697ec06818af1f92df98d4936b3476ea3152e77151fd842be1', 'dfd86420633a7686ba6420c721c5ea6ae077370bfde237e134955b9abc45516d', 23);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (24, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Tko određuje koeficijent kategorije kluba u PGŽ?', '{"llm": "deepseek", "hits": 8, "sources": 4}', NULL, NULL, '2026-04-28 21:49:29.554985+02', 'dfd86420633a7686ba6420c721c5ea6ae077370bfde237e134955b9abc45516d', 'c5ce4c6836324cd04be7773a1f10e9a0af2b3af792efe9f1531dfa7bf45de3ff', 24);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (25, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Što sadrži program javnih potreba u sportu Grada Rijeke?', '{"llm": "deepseek", "hits": 8, "sources": 4}', NULL, NULL, '2026-04-28 21:49:36.681882+02', 'c5ce4c6836324cd04be7773a1f10e9a0af2b3af792efe9f1531dfa7bf45de3ff', 'd6734e7f18473a57edbb2826d14b394e2f8f7d1514fd6086862fb252ee6c5eab', 25);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (26, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Kakve su sankcije za doping u atletici?', '{"llm": "deepseek", "hits": 8, "sources": 5}', NULL, NULL, '2026-04-28 21:49:43.735169+02', 'd6734e7f18473a57edbb2826d14b394e2f8f7d1514fd6086862fb252ee6c5eab', '710ba3f39e692e93510d7d969ed8a1f6e1f330274596ad2ba747e61170b3724d', 26);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (27, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Kako kategorizirati odbojkaša prema HOO pravilniku?', '{"llm": "deepseek", "hits": 8, "sources": 5}', NULL, NULL, '2026-04-28 21:49:50.701899+02', '710ba3f39e692e93510d7d969ed8a1f6e1f330274596ad2ba747e61170b3724d', '16b7d5261b42a3dfb486a0fde5cde1966ca8d97f3e43da3eb5998c38c5f118b0', 27);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (28, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Koji su uvjeti za sufinanciranje sportskog programa iz proračuna PGŽ?', '{"llm": "deepseek", "hits": 8, "sources": 3}', NULL, NULL, '2026-04-28 21:50:00.114435+02', '16b7d5261b42a3dfb486a0fde5cde1966ca8d97f3e43da3eb5998c38c5f118b0', '0d34a9efdf376c2b8ae1d36aafc58d45a4a3cbee48e8fa5b656a2c55d51c4e22', 28);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (29, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Koliko često sportaš mora obaviti liječnički pregled?', '{"llm": "deepseek", "hits": 8, "sources": 3}', NULL, NULL, '2026-04-28 21:50:07.530646+02', '0d34a9efdf376c2b8ae1d36aafc58d45a4a3cbee48e8fa5b656a2c55d51c4e22', 'e82fff154dc00e541b56066daa209447f389666afc36e5e418b31257de99c8a5', 29);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (30, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Što je potrebno za prijavu sportaša u registar HNS-a?', '{"llm": "deepseek", "hits": 8, "sources": 3}', NULL, NULL, '2026-04-28 21:50:15.009227+02', 'e82fff154dc00e541b56066daa209447f389666afc36e5e418b31257de99c8a5', '72ef9ff9af08c1f887aecee49c54cbf0e142fa24273a8d1007463f37b5f7e2cf', 30);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (31, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Koje su obveze tajnika kluba za godišnje izvješće?', '{"llm": "deepseek", "hits": 8, "sources": 3}', NULL, NULL, '2026-04-28 21:50:24.117512+02', '72ef9ff9af08c1f887aecee49c54cbf0e142fa24273a8d1007463f37b5f7e2cf', 'ba5ab371ed55c7ac24d3e3bf58cd7458bc8cdc5dd8c1bb7f9e9c0a3579ec5438', 31);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (32, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Tko određuje koeficijent kategorije kluba u PGŽ?', '{"llm": "deepseek", "hits": 8, "sources": 4}', NULL, NULL, '2026-04-28 21:50:30.146851+02', 'ba5ab371ed55c7ac24d3e3bf58cd7458bc8cdc5dd8c1bb7f9e9c0a3579ec5438', 'cbec883c514f7b5a8f0c4dbf4570c8fe6fcd08954309d0733046801b1978c806', 32);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (33, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Što sadrži program javnih potreba u sportu Grada Rijeke?', '{"llm": "deepseek", "hits": 8, "sources": 4}', NULL, NULL, '2026-04-28 21:50:39.242714+02', 'cbec883c514f7b5a8f0c4dbf4570c8fe6fcd08954309d0733046801b1978c806', 'a027f04f78b9406894d348a9284e3cfca1c09c1674054796577ff03efa01fbd7', 33);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (34, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Kakve su sankcije za doping u atletici?', '{"llm": "deepseek", "hits": 8, "sources": 5}', NULL, NULL, '2026-04-28 21:50:46.320136+02', 'a027f04f78b9406894d348a9284e3cfca1c09c1674054796577ff03efa01fbd7', 'fde998b810512fc5c50c69e226fd86ecf95dc30c0f38e14014785ac6782a1cab', 34);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (35, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Liječnički pregledi sportaša', '{"llm": "deepseek", "hits": 8, "sources": 3}', NULL, NULL, '2026-04-28 21:53:22.984643+02', 'fde998b810512fc5c50c69e226fd86ecf95dc30c0f38e14014785ac6782a1cab', 'f461d8a89e5bde3250b650b06261f6cdb93bd1b41608a83199a3331937819c1a', 35);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (36, NULL, NULL, 'schema.test', 'test_table', NULL, 'v6 setup test', '{"schema": "v6", "blockchain": true}', NULL, NULL, '2026-04-28 22:06:50.991864+02', 'f461d8a89e5bde3250b650b06261f6cdb93bd1b41608a83199a3331937819c1a', '6e293e13c1044d687404ade26ffd0208736ac041e5fe90c84b3a071df68d4486', 36);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (37, NULL, NULL, 'user.klub_link.create', 'sys_user_klub_links', 3, NULL, '{"role": "tajnik", "klub_id": null, "user_id": 2, "savez_id": 10}', NULL, NULL, '2026-04-28 22:20:38.823803+02', '6e293e13c1044d687404ade26ffd0208736ac041e5fe90c84b3a071df68d4486', 'c88cbc0c3de00d32cc1c799f6cf0de6baea9578bd2b88069c5729d03a7a30d19', 37);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (38, NULL, NULL, 'user.klub_link.create', 'sys_user_klub_links', 4, NULL, '{"role": "tajnik", "klub_id": 174, "user_id": 6, "savez_id": null}', NULL, NULL, '2026-04-28 22:20:38.874401+02', 'c88cbc0c3de00d32cc1c799f6cf0de6baea9578bd2b88069c5729d03a7a30d19', 'de43fd2e5ddc1530ef53f4743a74505be0891e1d536ed4ce965e1c24d1d71ac5', 38);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (39, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Kako kategorizirati odbojkaša?', '{"llm": "deepseek", "hits": 8, "sources": 4}', NULL, NULL, '2026-04-28 22:21:03.197332+02', 'de43fd2e5ddc1530ef53f4743a74505be0891e1d536ed4ce965e1c24d1d71ac5', 'bd0bec24c9cab8174786e3c3b97be88ec025fee492f11a2ac66225b7318ae8dc', 39);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (40, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Koja je cijena po prijeđenom km kod obračuna troškova putnih naloga?', '{"llm": "deepseek", "hits": 6, "sources": 2}', NULL, NULL, '2026-04-28 23:27:16.013163+02', 'bd0bec24c9cab8174786e3c3b97be88ec025fee492f11a2ac66225b7318ae8dc', 'f382b126a7e8f307cfaef40ae529e3213c7f76a2efc64732bada1be0c3327ca0', 40);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (41, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Tko ima pravo na sufinanciranje sporta u PGZ?', '{"llm": "deepseek", "hits": 1, "sources": 0}', NULL, NULL, '2026-04-29 07:08:41.784819+02', 'f382b126a7e8f307cfaef40ae529e3213c7f76a2efc64732bada1be0c3327ca0', '241d1fd9a2f57d3c4556aed0ec700d798e73bd84bc8891bb9bdb21f3466db5a1', 41);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (42, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Pravilnik o kategorizaciji sportaša u Hrvatskom olimpijskom odboru', '{"llm": "deepseek", "hits": 6, "sources": 6}', NULL, NULL, '2026-04-29 07:36:04.01401+02', '241d1fd9a2f57d3c4556aed0ec700d798e73bd84bc8891bb9bdb21f3466db5a1', '92b07a0580ce2ac53b1dddf7a8fad1fec958a56ca534bdcadc60fbfbbb6f735d', 42);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (43, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Pravilnik o kategorizaciji sportaša u Hrvatskom olimpijskom odboru', '{"llm": "deepseek", "hits": 6, "sources": 6}', NULL, NULL, '2026-04-29 07:36:25.317113+02', '92b07a0580ce2ac53b1dddf7a8fad1fec958a56ca534bdcadc60fbfbbb6f735d', '21829d6216333055329c08be815cfe227ba2a342d9088b51a1cc2bad76336a7d', 43);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (44, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Pravilnik o kategorizaciji sportaša HOO', '{"llm": "deepseek", "hits": 5, "sources": 5}', NULL, NULL, '2026-04-29 07:39:10.78041+02', '21829d6216333055329c08be815cfe227ba2a342d9088b51a1cc2bad76336a7d', 'fa9d49a65fea70228e4957c8f7d9907842d26149b81a60d2f3e1a796de0748ae', 44);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (45, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Plan razvoja sporta u Hrvatskoj 2019-2026', '{"llm": "deepseek", "hits": 5, "sources": 5}', NULL, NULL, '2026-04-29 07:39:20.23281+02', 'fa9d49a65fea70228e4957c8f7d9907842d26149b81a60d2f3e1a796de0748ae', '4dd040e7652d775ba53f8845a6ecb9db7edeef3a8daf369b4b9f7bbcf6015e7d', 45);
INSERT INTO pgz_sport.sys_audit (id, user_id, user_email, action, target_type, target_id, target_text, payload, ip_address, user_agent, created_at, prev_hash, row_hash, chain_idx) VALUES (46, NULL, NULL, 'lawyer.query', 'sport_lawyer', NULL, 'Natječaj za sufinanciranje sporta', '{"llm": "deepseek", "hits": 6, "sources": 5}', NULL, NULL, '2026-04-29 07:39:26.785165+02', '4dd040e7652d775ba53f8845a6ecb9db7edeef3a8daf369b4b9f7bbcf6015e7d', '3668482714c78fb0b8c645df80f54a3b2612ebab0f3918708ca56df2647fc41f', 46);
--
-- Data for Name: sys_permissions; Type: TABLE DATA; Schema: pgz_sport; Owner: rinet
--
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (1, 'klub.read.own', 'Pregled vlastitog kluba', NULL, 'klubovi');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (2, 'klub.read.all', 'Pregled svih klubova', NULL, 'klubovi');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (3, 'klub.edit.own', 'Uređivanje vlastitog kluba', NULL, 'klubovi');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (4, 'klub.edit.all', 'Uređivanje svih klubova', NULL, 'klubovi');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (5, 'klub.create', 'Stvaranje klubova', NULL, 'klubovi');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (6, 'klub.delete', 'Brisanje klubova', NULL, 'klubovi');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (7, 'clan.read.own', 'Pregled članova vlastitog kluba', NULL, 'clanovi');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (8, 'clan.read.all', 'Pregled članova svih klubova', NULL, 'clanovi');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (9, 'clan.edit.own', 'Uređivanje članova vlastitog kluba', NULL, 'clanovi');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (10, 'clan.edit.all', 'Uređivanje članova svih klubova', NULL, 'clanovi');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (11, 'clan.medical.read', 'Pregled medicinskih podataka', NULL, 'clanovi');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (12, 'clan.medical.edit', 'Uređivanje medicinskih podataka', NULL, 'clanovi');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (13, 'finance.read.own', 'Pregled financija vlastitog kluba', NULL, 'finance');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (14, 'finance.read.all', 'Pregled financija svih klubova', NULL, 'finance');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (15, 'finance.edit.own', 'Uređivanje financija vlastitog kluba', NULL, 'finance');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (16, 'finance.edit.all', 'Uređivanje financija svih klubova', NULL, 'finance');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (17, 'finance.invoice.read', 'Pregled računa', NULL, 'finance');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (18, 'finance.invoice.create', 'Stvaranje računa', NULL, 'finance');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (19, 'finance.expense.read', 'Pregled putnih naloga', NULL, 'finance');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (20, 'finance.expense.create', 'Stvaranje putnih naloga', NULL, 'finance');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (21, 'funding.read.own', 'Pregled sufinanciranja vlastitog kluba', NULL, 'funding');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (22, 'funding.read.all', 'Pregled sufinanciranja svih klubova', NULL, 'funding');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (23, 'funding.approve', 'Odobravanje sufinanciranja', NULL, 'funding');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (24, 'manifestacije.read', 'Pregled manifestacija', NULL, 'manifestacije');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (25, 'manifestacije.create', 'Stvaranje manifestacija', NULL, 'manifestacije');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (26, 'manifestacije.edit', 'Uređivanje manifestacija', NULL, 'manifestacije');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (27, 'lijecnicki.read.own', 'Pregled liječničkih vlastitog kluba', NULL, 'medical');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (28, 'lijecnicki.read.all', 'Pregled liječničkih svih klubova', NULL, 'medical');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (29, 'lijecnicki.edit.own', 'Uređivanje liječničkih vlastitog kluba', NULL, 'medical');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (30, 'lijecnicki.edit.all', 'Uređivanje liječničkih svih klubova', NULL, 'medical');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (31, 'lijecnicki.specijalisti', 'Upravljanje specijalistima', NULL, 'medical');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (32, 'docs.read', 'Pregled pravilnika i dokumenata', NULL, 'docs');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (33, 'docs.upload', 'Upload pravilnika', NULL, 'docs');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (34, 'docs.delete', 'Brisanje dokumenata', NULL, 'docs');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (35, 'ai.chat', 'Korištenje AI asistenta', NULL, 'ai');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (36, 'ai.lawyer', 'Korištenje pravnika asistenta', NULL, 'ai');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (37, 'ai.advanced', 'Napredne AI funkcije', NULL, 'ai');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (38, 'reports.dashboard', 'Pregled dashboarda', NULL, 'reports');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (39, 'reports.export', 'Eksport izvješća', NULL, 'reports');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (40, 'reports.financial', 'Financijska izvješća', NULL, 'reports');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (41, 'reports.forensic', 'Forenzička izvješća', NULL, 'reports');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (42, 'admin.users.read', 'Pregled korisnika', NULL, 'admin');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (43, 'admin.users.create', 'Stvaranje korisnika', NULL, 'admin');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (44, 'admin.users.edit', 'Uređivanje korisnika', NULL, 'admin');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (45, 'admin.users.delete', 'Brisanje korisnika', NULL, 'admin');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (46, 'admin.permissions', 'Upravljanje dozvolama', NULL, 'admin');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (47, 'admin.audit', 'Pregled audit log-a', NULL, 'admin');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (48, 'admin.system', 'Sistemska podešavanja', NULL, 'admin');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (49, 'natjecanja.read', 'Pregled natjecanja', NULL, 'natjecanja');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (50, 'natjecanja.create', 'Stvaranje natjecanja', NULL, 'natjecanja');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (51, 'natjecanja.edit', 'Uređivanje natjecanja', NULL, 'natjecanja');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (52, 'alerts.read.own', 'Pregled alerta vlastitog kluba', NULL, 'alerts');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (53, 'alerts.read.all', 'Pregled svih alerta', NULL, 'alerts');
INSERT INTO pgz_sport.sys_permissions (id, code, naziv, opis, kategorija) VALUES (54, 'alerts.resolve', 'Rješavanje alerta', NULL, 'alerts');
--
-- Data for Name: sys_role_permissions; Type: TABLE DATA; Schema: pgz_sport; Owner: rinet
--
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'klub.read.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'klub.read.all', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'klub.edit.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'klub.edit.all', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'klub.create', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'klub.delete', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'clan.read.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'clan.read.all', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'clan.edit.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'clan.edit.all', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'clan.medical.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'clan.medical.edit', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'finance.read.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'finance.read.all', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'finance.edit.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'finance.edit.all', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'finance.invoice.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'finance.invoice.create', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'finance.expense.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'finance.expense.create', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'funding.read.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'funding.read.all', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'funding.approve', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'manifestacije.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'manifestacije.create', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'manifestacije.edit', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'lijecnicki.read.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'lijecnicki.read.all', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'lijecnicki.edit.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'lijecnicki.edit.all', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'lijecnicki.specijalisti', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'docs.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'docs.upload', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'docs.delete', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'ai.chat', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'ai.lawyer', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'ai.advanced', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'reports.dashboard', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'reports.export', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'reports.financial', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'reports.forensic', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'admin.users.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'admin.users.create', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'admin.users.edit', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'admin.users.delete', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'admin.permissions', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'admin.audit', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'admin.system', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'natjecanja.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'natjecanja.create', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'natjecanja.edit', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'alerts.read.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'alerts.read.all', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('super_admin', 'alerts.resolve', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'klub.read.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'klub.read.all', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'klub.edit.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'klub.edit.all', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'klub.create', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'klub.delete', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'clan.read.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'clan.read.all', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'clan.edit.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'clan.edit.all', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'clan.medical.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'clan.medical.edit', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'finance.read.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'finance.read.all', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'finance.edit.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'finance.edit.all', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'finance.invoice.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'finance.invoice.create', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'finance.expense.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'finance.expense.create', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'funding.read.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'funding.read.all', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'funding.approve', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'manifestacije.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'manifestacije.create', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'manifestacije.edit', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'lijecnicki.read.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'lijecnicki.read.all', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'lijecnicki.edit.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'lijecnicki.edit.all', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'lijecnicki.specijalisti', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'docs.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'docs.upload', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'docs.delete', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'ai.chat', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'ai.lawyer', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'ai.advanced', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'reports.dashboard', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'reports.export', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'reports.financial', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'reports.forensic', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'admin.users.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'admin.users.create', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'admin.users.edit', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'admin.users.delete', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'admin.permissions', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'admin.audit', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'admin.system', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'natjecanja.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'natjecanja.create', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'natjecanja.edit', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'alerts.read.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'alerts.read.all', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_admin', 'alerts.resolve', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_user', 'klub.read.all', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_user', 'clan.read.all', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_user', 'finance.read.all', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_user', 'funding.read.all', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_user', 'manifestacije.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_user', 'lijecnicki.read.all', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_user', 'docs.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_user', 'ai.chat', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_user', 'ai.lawyer', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_user', 'reports.dashboard', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_user', 'reports.export', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_user', 'natjecanja.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_user', 'alerts.read.all', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_finance', 'klub.read.all', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_finance', 'finance.read.all', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_finance', 'finance.edit.all', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_finance', 'finance.invoice.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_finance', 'funding.read.all', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_finance', 'funding.approve', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_finance', 'docs.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_finance', 'ai.chat', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_finance', 'ai.lawyer', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_finance', 'reports.dashboard', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_finance', 'reports.export', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_finance', 'reports.financial', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_finance', 'reports.forensic', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_finance', 'alerts.read.all', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_finance', 'alerts.resolve', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_zzjz', 'clan.read.all', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_zzjz', 'clan.medical.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_zzjz', 'clan.medical.edit', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_zzjz', 'lijecnicki.read.all', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_zzjz', 'lijecnicki.edit.all', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_zzjz', 'lijecnicki.specijalisti', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_zzjz', 'docs.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_zzjz', 'ai.chat', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('pgz_zzjz', 'reports.dashboard', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_admin', 'klub.read.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_admin', 'klub.edit.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_admin', 'clan.read.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_admin', 'clan.edit.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_admin', 'finance.read.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_admin', 'finance.edit.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_admin', 'finance.invoice.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_admin', 'finance.invoice.create', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_admin', 'finance.expense.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_admin', 'finance.expense.create', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_admin', 'funding.read.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_admin', 'manifestacije.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_admin', 'manifestacije.create', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_admin', 'manifestacije.edit', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_admin', 'lijecnicki.read.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_admin', 'docs.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_admin', 'docs.upload', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_admin', 'ai.chat', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_admin', 'ai.lawyer', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_admin', 'reports.dashboard', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_admin', 'reports.export', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_admin', 'natjecanja.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_admin', 'natjecanja.create', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_admin', 'natjecanja.edit', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_admin', 'alerts.read.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_admin', 'alerts.resolve', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_user', 'klub.read.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_user', 'clan.read.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_user', 'finance.read.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_user', 'funding.read.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_user', 'manifestacije.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_user', 'docs.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_user', 'ai.chat', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_user', 'reports.dashboard', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_user', 'natjecanja.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('savez_user', 'alerts.read.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_admin', 'klub.read.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_admin', 'klub.edit.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_admin', 'clan.read.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_admin', 'clan.edit.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_admin', 'clan.medical.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_admin', 'finance.read.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_admin', 'finance.edit.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_admin', 'finance.invoice.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_admin', 'finance.invoice.create', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_admin', 'finance.expense.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_admin', 'finance.expense.create', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_admin', 'funding.read.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_admin', 'manifestacije.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_admin', 'lijecnicki.read.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_admin', 'lijecnicki.edit.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_admin', 'docs.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_admin', 'docs.upload', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_admin', 'ai.chat', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_admin', 'ai.lawyer', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_admin', 'reports.dashboard', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_admin', 'reports.export', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_admin', 'natjecanja.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_admin', 'alerts.read.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_admin', 'alerts.resolve', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_user', 'klub.read.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_user', 'clan.read.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_user', 'finance.read.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_user', 'manifestacije.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_user', 'docs.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_user', 'ai.chat', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_user', 'reports.dashboard', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_user', 'natjecanja.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_user', 'alerts.read.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_clan', 'klub.read.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_clan', 'clan.read.own', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_clan', 'docs.read', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('klub_clan', 'ai.chat', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('guest', 'klub.read.all', true);
INSERT INTO pgz_sport.sys_role_permissions (user_type, permission_code, granted) VALUES ('guest', 'manifestacije.read', true);
--
-- Data for Name: sys_sessions; Type: TABLE DATA; Schema: pgz_sport; Owner: rinet
--
--
-- Data for Name: sys_user_klub_links; Type: TABLE DATA; Schema: pgz_sport; Owner: rinet
--
INSERT INTO pgz_sport.sys_user_klub_links (id, user_id, klub_id, savez_id, role, primary_link, od_datuma, do_datuma, aktivan, granted_by, granted_at, note) VALUES (3, 2, NULL, 10, 'tajnik', true, NULL, NULL, true, NULL, '2026-04-28 22:20:38.823803+02', NULL);
INSERT INTO pgz_sport.sys_user_klub_links (id, user_id, klub_id, savez_id, role, primary_link, od_datuma, do_datuma, aktivan, granted_by, granted_at, note) VALUES (4, 6, 174, NULL, 'tajnik', false, NULL, NULL, true, NULL, '2026-04-28 22:20:38.874401+02', NULL);
--
-- Data for Name: sys_user_permissions; Type: TABLE DATA; Schema: pgz_sport; Owner: rinet
--
--
-- Data for Name: user_klub_links; Type: TABLE DATA; Schema: pgz_sport; Owner: rinet
--
--
-- Data for Name: user_roles; Type: TABLE DATA; Schema: pgz_sport; Owner: rinet
--
INSERT INTO pgz_sport.user_roles (id, user_id, role_id, scope_type, scope_id, granted_by, granted_at, expires_at, active) VALUES (1, 1, 1, 'global', NULL, 1, '2026-04-28 19:45:29.033006+02', NULL, true);
--
-- Data for Name: user_sessions; Type: TABLE DATA; Schema: pgz_sport; Owner: rinet
--
INSERT INTO pgz_sport.user_sessions (id, user_id, token_hash, device_info, ip_address, created_at, expires_at, revoked) VALUES (1, 1, '8028fc0086d422e283835cf6a25927bf82d9e7c40cd78bb1002f9f17ee63376c', NULL, NULL, '2026-04-28 19:59:05.356182+02', '2026-05-28 19:59:05.347181+02', false);
INSERT INTO pgz_sport.user_sessions (id, user_id, token_hash, device_info, ip_address, created_at, expires_at, revoked) VALUES (2, 1, '1ad362058d122e2e2bb835f3582b00d171307176ec06dbe111cedead6d000bc2', NULL, NULL, '2026-04-28 20:06:03.802726+02', '2026-05-28 20:06:03.792923+02', false);
INSERT INTO pgz_sport.user_sessions (id, user_id, token_hash, device_info, ip_address, created_at, expires_at, revoked) VALUES (3, 1, 'bb66527853b5e67b0210593ad38b5425f36878cf180bde609eca8879167822ff', NULL, NULL, '2026-04-28 20:06:31.889351+02', '2026-05-28 20:06:31.88142+02', false);
INSERT INTO pgz_sport.user_sessions (id, user_id, token_hash, device_info, ip_address, created_at, expires_at, revoked) VALUES (4, 1, 'b9dde5175bf4586342650c3c7c77999e3e5700618044d63e1eba20eb87231344', NULL, NULL, '2026-04-28 20:07:02.022031+02', '2026-05-28 20:07:02.013891+02', false);
--
-- Name: audit_events_id_seq; Type: SEQUENCE SET; Schema: pgz_sport; Owner: rinet
--
SELECT pg_catalog.setval('pgz_sport.audit_events_id_seq', 6, true);
--
-- Name: audit_log_id_seq; Type: SEQUENCE SET; Schema: pgz_sport; Owner: rinet
--
SELECT pg_catalog.setval('pgz_sport.audit_log_id_seq', 1, true);
--
-- Name: roles_id_seq; Type: SEQUENCE SET; Schema: pgz_sport; Owner: rinet
--
SELECT pg_catalog.setval('pgz_sport.roles_id_seq', 7, true);
--
-- Name: sys_audit_id_seq; Type: SEQUENCE SET; Schema: pgz_sport; Owner: rinet
--
SELECT pg_catalog.setval('pgz_sport.sys_audit_id_seq', 46, true);
--
-- Name: sys_permissions_id_seq; Type: SEQUENCE SET; Schema: pgz_sport; Owner: rinet
--
SELECT pg_catalog.setval('pgz_sport.sys_permissions_id_seq', 54, true);
--
-- Name: sys_sessions_id_seq; Type: SEQUENCE SET; Schema: pgz_sport; Owner: rinet
--
SELECT pg_catalog.setval('pgz_sport.sys_sessions_id_seq', 1, false);
--
-- Name: sys_user_klub_links_id_seq; Type: SEQUENCE SET; Schema: pgz_sport; Owner: rinet
--
SELECT pg_catalog.setval('pgz_sport.sys_user_klub_links_id_seq', 4, true);
--
-- Name: sys_users_id_seq; Type: SEQUENCE SET; Schema: pgz_sport; Owner: rinet
--
SELECT pg_catalog.setval('pgz_sport.sys_users_id_seq', 9, true);
--
-- Name: user_klub_links_id_seq; Type: SEQUENCE SET; Schema: pgz_sport; Owner: rinet
--
SELECT pg_catalog.setval('pgz_sport.user_klub_links_id_seq', 1, false);
--
-- Name: user_roles_id_seq; Type: SEQUENCE SET; Schema: pgz_sport; Owner: rinet
--
SELECT pg_catalog.setval('pgz_sport.user_roles_id_seq', 1, true);
--
-- Name: user_sessions_id_seq; Type: SEQUENCE SET; Schema: pgz_sport; Owner: rinet
--
SELECT pg_catalog.setval('pgz_sport.user_sessions_id_seq', 4, true);
--
-- Name: users_id_seq; Type: SEQUENCE SET; Schema: pgz_sport; Owner: rinet
--
SELECT pg_catalog.setval('pgz_sport.users_id_seq', 1, true);
--
-- PostgreSQL database dump complete
--
\unrestrict h6bd7kGvxEavN2pokB3ndj68pJKRaJXQanRfq1xgOELkeOAc9Wagkc4WNCfcjsu
File diff suppressed because it is too large Load Diff