Files
BFLOWS e217f15e5a feat: endpoint pratiche rendicontazione (lato beneficiario)
- 4 nuove tabelle: remission_practice, remission_invoice, remission_ula_employee, remission_document
  con cascade delete e FK
- 13 endpoint /api/remission-practices/*:
  GET /mine (lista pratiche user + applications CONTRACT_SIGNED ready_to_start)
  POST /start (avvia pratica da application_id, richiede schema PUBLISHED)
  GET /{id}, PUT /{id} (regime IVA + note)
  POST/DELETE /{id}/invoices
  POST/DELETE /{id}/ula-employees
  PUT/DELETE /{id}/documents/{doc_code}
  GET /{id}/gate-check (valida gate rules contro pratica, ritorna totali + checks)
  POST /{id}/submit (gate-check obbligatorio, status DRAFT -> SUBMITTED)
- 1 endpoint debug /api/debug/impersonate (sandbox-only, genera JWT per utente
  - necessario perche' /v1/user/login del BE Spring esclude ROLE_BENEFICIARY)
- Gate check calcola: totali per categoria, grand_total, max_remission = min(cap_pct*erogato, cap_abs),
  remission_due = min(grand_total, max_remission), applica iva_ordinario_imponibile_only
2026-04-18 09:51:06 +02:00

68 lines
2.2 KiB
Python

"""
Endpoint di debug SOLO per sandbox. Permette a un superadmin di impersonare
un utente (tipicamente un beneficiario) per testare i flussi senza SPID.
Non deve essere mai abilitato in produzione.
"""
from datetime import datetime, timedelta, timezone
from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel
from sqlalchemy.orm import Session
from sqlalchemy import text
from jose import jwt
from ..db import get_db
from ..config import get_settings
from ..auth import AuthUser, require_superadmin
from ..schemas import ApiResponse
router = APIRouter(prefix="/api/debug", tags=["debug"])
settings = get_settings()
class ImpersonateRequest(BaseModel):
email: str
@router.post("/impersonate", response_model=ApiResponse)
def impersonate(body: ImpersonateRequest,
db: Session = Depends(get_db),
admin: AuthUser = Depends(require_superadmin)):
"""
Genera un token JWT valido per l'email indicata. Solo sandbox dev,
richiede ruolo superadmin per chiamarlo.
"""
row = db.execute(text("""
SELECT u.id, u.email, u.first_name, u.last_name, u.hub_id,
r.role_type
FROM gepafin_schema.gepafin_user u
JOIN gepafin_schema.role r ON r.id = u.role_id
WHERE u.email = :email AND u.is_deleted = false
"""), {"email": body.email}).mappings().first()
if not row:
raise HTTPException(status_code=404, detail=f"Utente {body.email} non trovato")
# Genero token con lo stesso formato del BE Spring
exp = datetime.now(timezone.utc) + timedelta(hours=8)
payload = {
"sub": f"{row['email']}:{row['id']}:{row['hub_id']}",
"userId": row["id"],
"auth": row["role_type"],
"exp": int(exp.timestamp()),
}
token = jwt.encode(payload, settings.jwt_secret, algorithm=settings.jwt_algorithm)
return ApiResponse(
message=f"Token generato per {body.email}",
data={
"token": token,
"user": {
"id": row["id"],
"email": row["email"],
"firstName": row["first_name"],
"lastName": row["last_name"],
"role": {"roleType": row["role_type"]}
}
}
)