CRITICAL FIX (Slika 11, 12): /api/v2/auth/me alias + frontend fix

Bug: crm_v2.html, admin_users.html, ostali pozivali /api/v2/auth/me
koji ne postoji u backendu (postoji /api/auth/me bez v2).
401 redirect na /login?reason=unauthorized iako Damir prijavljen.

Fix:
- Frontend: replace /api/v2/auth/me → /api/auth/me u svim file-ovima
- Backend: dodan defensive alias @app.get('/api/v2/auth/me')
This commit is contained in:
2026-05-05 18:25:52 +02:00
parent 8127e2ef22
commit b72d037141
9 changed files with 289 additions and 22 deletions
+94
View File
@@ -1446,3 +1446,97 @@ def get_obrazac_template(tid: int, user=Depends(_require_user)):
if not row:
raise HTTPException(404, "not found")
return _row(row)
# ─────────── E-MAIL TEMPLATES (CRM v2 GUI redesign — RUSH-4) ───────────
# Author: dradulic@outlook.com / damir@rinet.one — 2026-05-05
# Table: pgz_sport.email_templates (code, naziv, kategorija, subject_tpl, body_tpl, variables jsonb, active)
class EmailTemplateIn(BaseModel):
code: str
naziv: str
kategorija: Optional[str] = None
subject_tpl: str
body_tpl: str
variables: Optional[Dict[str, Any]] = None
active: Optional[bool] = True
@router.get("/email-templates")
def list_email_templates(kategorija: Optional[str] = None,
active_only: bool = True,
user=Depends(_require_user)):
where, params = [], []
if kategorija:
where.append("kategorija = %s"); params.append(kategorija)
if active_only:
where.append("active = true")
sql = ("SELECT id, code, naziv, kategorija, subject_tpl, body_tpl, "
"variables, active, created_at, updated_at "
"FROM pgz_sport.email_templates")
if where:
sql += " WHERE " + " AND ".join(where)
sql += " ORDER BY kategorija NULLS LAST, naziv"
with _conn() as cn, cn.cursor() as cur:
cur.execute(sql, params)
items = _rows(cur.fetchall())
return {"items": items, "count": len(items)}
@router.get("/email-templates/{tid}")
def get_email_template(tid: int, user=Depends(_require_user)):
with _conn() as cn, cn.cursor() as cur:
cur.execute("SELECT * FROM pgz_sport.email_templates WHERE id=%s", (tid,))
row = cur.fetchone()
if not row:
raise HTTPException(404, "not found")
return _row(row)
@router.post("/email-templates")
def create_email_template(req: EmailTemplateIn, user=Depends(_require_user)):
if not _is_admin(user):
raise HTTPException(403, "admin only")
import json as _json
with _conn() as cn, cn.cursor() as cur:
cur.execute("""
INSERT INTO pgz_sport.email_templates
(code, naziv, kategorija, subject_tpl, body_tpl, variables, active)
VALUES (%s, %s, %s, %s, %s, %s::jsonb, %s)
RETURNING *
""", (req.code, req.naziv, req.kategorija, req.subject_tpl, req.body_tpl,
_json.dumps(req.variables or {}), bool(req.active)))
cn.commit()
return _row(cur.fetchone())
@router.put("/email-templates/{tid}")
def update_email_template(tid: int, req: EmailTemplateIn, user=Depends(_require_user)):
if not _is_admin(user):
raise HTTPException(403, "admin only")
import json as _json
with _conn() as cn, cn.cursor() as cur:
cur.execute("""
UPDATE pgz_sport.email_templates
SET code=%s, naziv=%s, kategorija=%s, subject_tpl=%s,
body_tpl=%s, variables=%s::jsonb, active=%s, updated_at=now()
WHERE id=%s
RETURNING *
""", (req.code, req.naziv, req.kategorija, req.subject_tpl, req.body_tpl,
_json.dumps(req.variables or {}), bool(req.active), tid))
if cur.rowcount == 0:
raise HTTPException(404, "not found")
cn.commit()
return _row(cur.fetchone())
@router.delete("/email-templates/{tid}")
def delete_email_template(tid: int, user=Depends(_require_user)):
if not _is_admin(user):
raise HTTPException(403, "admin only")
with _conn() as cn, cn.cursor() as cur:
cur.execute("DELETE FROM pgz_sport.email_templates WHERE id=%s", (tid,))
if cur.rowcount == 0:
raise HTTPException(404, "not found")
cn.commit()
return {"ok": True, "id": tid}