fix(URGENT): SPA fallback serves sport2.html + 9 routers __future__ position

BUGS FIXED:
1. _serve_spa_fallback() returned index.html instead of sport2.html
   → User clicked /analitika /sufinanciranje etc and got wrong UI (DABI title)
   → Should serve sport2.html (PGZ SPORT - Platforma) with Analiza/Mreza/Link tabs

2. 9 router files had "from __future__" NOT at top of file
   → SyntaxError on import → routers SKIPPED → intermittent API failures
   → Affected: ocr.py, ocr_router.py, putni_nalozi.py, obrasci_router.py,
     clan_panel_router.py, audit_seal_router.py, erp_full_router.py,
     notif_router.py, seal.py

ROOT CAUSE:
Prior dehardcode batch (Master Zakon #1 sweep) inserted env-loading
imports BEFORE "from __future__ import annotations" — Python parser
requires __future__ FIRST.

FIX:
- _serve_spa_fallback() candidates list: sport2.html first
- Moved __future__ to top (preserving shebang + encoding + comments) in all 9

VERIFIED:
- 0 failed routers (was 7+)
- Analiza API: 10/10 success ~60-87ms
- Summary API: 5/5 success ~40ms
- sport.rinet.one/ → PGZ SPORT - Platforma (Analiza+Mreza tabs)
- All 9 SPA fallback routes serve sport2.html

Damir uploaded screenshot showing Analiza tab working (2,049 igraca,
82 klubova) but described as intermittent — root cause was router fails
causing some API endpoints to be missing/unreliable. Fixed.
This commit is contained in:
Damir Radulic
2026-05-18 15:45:22 +02:00
parent 386af1c5ed
commit 2e022a7dcc
10 changed files with 17 additions and 11 deletions
+1 -1
View File
@@ -1,4 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from __future__ import annotations
from dotenv import load_dotenv from dotenv import load_dotenv
load_dotenv('/opt/rinet-gpu/.env.master') load_dotenv('/opt/rinet-gpu/.env.master')
# auto-added by patch_scrapers_with_dotenv.sh # auto-added by patch_scrapers_with_dotenv.sh
@@ -37,7 +38,6 @@ list_seals(action=None, ref_type=None, ref_id=None, limit=50) -> list[dict]
The module is import-safe even on hosts without web3 installed; the LIVE branch The module is import-safe even on hosts without web3 installed; the LIVE branch
just becomes a no-op. just becomes a no-op.
""" """
from __future__ import annotations
import os import os
import json import json
+1 -1
View File
@@ -1,4 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from __future__ import annotations
from dotenv import load_dotenv from dotenv import load_dotenv
load_dotenv('/opt/rinet-gpu/.env.master') load_dotenv('/opt/rinet-gpu/.env.master')
# auto-added by patch_scrapers_with_dotenv.sh # auto-added by patch_scrapers_with_dotenv.sh
@@ -8,7 +9,6 @@ load_dotenv('/opt/rinet-gpu/.env.master')
# Description: /api/erp/ocr/upload + /parse — Tesseract OCR + DeepSeek V3 LLM extraction # Description: /api/erp/ocr/upload + /parse — Tesseract OCR + DeepSeek V3 LLM extraction
# Persists into pgz_sport.invoice_uploads, then offers structured invoice parse. # Persists into pgz_sport.invoice_uploads, then offers structured invoice parse.
from __future__ import annotations
import os import os
import re import re
+1 -1
View File
@@ -1,4 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from __future__ import annotations
from dotenv import load_dotenv from dotenv import load_dotenv
load_dotenv('/opt/rinet-gpu/.env.master') load_dotenv('/opt/rinet-gpu/.env.master')
# auto-added by patch_scrapers_with_dotenv.sh # auto-added by patch_scrapers_with_dotenv.sh
@@ -8,7 +9,6 @@ import os
# Date: 2026-05-04 # Date: 2026-05-04
# Description: CRUD putnih naloga + obračun dnevnica (HR pravilnik 2025). # Description: CRUD putnih naloga + obračun dnevnica (HR pravilnik 2025).
from __future__ import annotations
import json import json
from datetime import datetime, date, timedelta from datetime import datetime, date, timedelta
+8 -2
View File
@@ -3169,8 +3169,14 @@ _MISSING_TABS = ["sufinanciranje", "trezor", "dashboard", "analitika", "pravila"
def _serve_spa_fallback(): def _serve_spa_fallback():
import os import os
from fastapi.responses import FileResponse, HTMLResponse from fastapi.responses import FileResponse, HTMLResponse
candidates = ["/opt/pgz-sport/sport.html", "/opt/pgz-sport/static/index.html", # sport.rinet.one main UI is sport2.html (has Analiza, Mreza, Link Analiza tabs)
"/opt/pgz-sport/index.html"] candidates = [
"/opt/pgz-sport/static/sport2.html",
"/opt/pgz-sport/sport2.html",
"/opt/pgz-sport/sport.html",
"/opt/pgz-sport/static/index.html",
"/opt/pgz-sport/index.html",
]
for c in candidates: for c in candidates:
if os.path.exists(c): if os.path.exists(c):
return FileResponse(c) return FileResponse(c)
+1 -1
View File
@@ -1,3 +1,4 @@
from __future__ import annotations
from dotenv import load_dotenv from dotenv import load_dotenv
load_dotenv('/opt/rinet-gpu/.env.master') load_dotenv('/opt/rinet-gpu/.env.master')
# auto-added by patch_scrapers_with_dotenv.sh # auto-added by patch_scrapers_with_dotenv.sh
@@ -43,7 +44,6 @@ audit_log() — shared helper for other routers (cc2/4/5/6)
payload={'changed':['email']}, user_id=u['id'], user_email=u['email']) payload={'changed':['email']}, user_id=u['id'], user_email=u['email'])
Fail-soft: never raises, only writes to stderr on error. Fail-soft: never raises, only writes to stderr on error.
""" """
from __future__ import annotations
import sys, os, json, traceback import sys, os, json, traceback
from datetime import date, datetime from datetime import date, datetime
from typing import Any, Optional from typing import Any, Optional
+1 -1
View File
@@ -1,4 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from __future__ import annotations
from dotenv import load_dotenv from dotenv import load_dotenv
load_dotenv('/opt/rinet-gpu/.env.master') load_dotenv('/opt/rinet-gpu/.env.master')
# auto-added by patch_scrapers_with_dotenv.sh # auto-added by patch_scrapers_with_dotenv.sh
@@ -17,7 +18,6 @@ Endpointi (montirani na /api/crm):
POST /clanovi/{id}/avatar → upload slike POST /clanovi/{id}/avatar → upload slike
GET /clanovi/search?q=... → quick search za panel GET /clanovi/search?q=... → quick search za panel
""" """
from __future__ import annotations
import os import os
import io import io
+1 -1
View File
@@ -1,4 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from __future__ import annotations
from dotenv import load_dotenv from dotenv import load_dotenv
load_dotenv('/opt/rinet-gpu/.env.master') load_dotenv('/opt/rinet-gpu/.env.master')
# auto-added by patch_scrapers_with_dotenv.sh # auto-added by patch_scrapers_with_dotenv.sh
@@ -17,7 +18,6 @@ load_dotenv('/opt/rinet-gpu/.env.master')
# + approved_at/paid_at na prijelazima (Agent 2). # + approved_at/paid_at na prijelazima (Agent 2).
# Mount: /api/v2/erp/* # Mount: /api/v2/erp/*
# ═══════════════════════════════════════════════════════════════════ # ═══════════════════════════════════════════════════════════════════
from __future__ import annotations
import csv import csv
import hashlib import hashlib
+1 -1
View File
@@ -1,4 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from __future__ import annotations
from dotenv import load_dotenv from dotenv import load_dotenv
load_dotenv('/opt/rinet-gpu/.env.master') load_dotenv('/opt/rinet-gpu/.env.master')
# auto-added by patch_scrapers_with_dotenv.sh # auto-added by patch_scrapers_with_dotenv.sh
@@ -16,7 +17,6 @@ load_dotenv('/opt/rinet-gpu/.env.master')
# POST /api/v2/notif/mark-all-read # POST /api/v2/notif/mark-all-read
# DELETE /api/v2/notif/{id} # DELETE /api/v2/notif/{id}
# ============================================================================== # ==============================================================================
from __future__ import annotations
import os import os
from typing import Optional, List, Dict, Any from typing import Optional, List, Dict, Any
+1 -1
View File
@@ -1,4 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from __future__ import annotations
from dotenv import load_dotenv from dotenv import load_dotenv
load_dotenv('/opt/rinet-gpu/.env.master') load_dotenv('/opt/rinet-gpu/.env.master')
# auto-added by patch_scrapers_with_dotenv.sh # auto-added by patch_scrapers_with_dotenv.sh
@@ -24,7 +25,6 @@ Endpointi (montirani na /api/crm):
POST /forms/submissions/{id}/reject POST /forms/submissions/{id}/reject
POST /forms/{code_or_id}/submit → kompatibilni shortcut: kreiraj+submit u jednom POST POST /forms/{code_or_id}/submit → kompatibilni shortcut: kreiraj+submit u jednom POST
""" """
from __future__ import annotations
import json import json
import hashlib import hashlib
+1 -1
View File
@@ -1,4 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from __future__ import annotations
from dotenv import load_dotenv from dotenv import load_dotenv
load_dotenv('/opt/rinet-gpu/.env.master') load_dotenv('/opt/rinet-gpu/.env.master')
# auto-added by patch_scrapers_with_dotenv.sh # auto-added by patch_scrapers_with_dotenv.sh
@@ -15,7 +16,6 @@ load_dotenv('/opt/rinet-gpu/.env.master')
# degrade gracefully if pytesseract / pdf2image are not # degrade gracefully if pytesseract / pdf2image are not
# installed (returns ocr_status='ocr_unavailable'). # installed (returns ocr_status='ocr_unavailable').
from __future__ import annotations
import os import os
import re import re