From 8d7fa9a12a3895d2d734478bf24133e731d5b3dd Mon Sep 17 00:00:00 2001 From: Adriano Date: Sun, 11 Oct 2026 18:08:18 +0000 Subject: [PATCH] Statistica: pannello esiti, note, campi e allegati dei task per sessione, proxy e traduzioni (#58) Co-Authored-By: Claude Sonnet 5.5 Claude-Session: https://claude.ai/code/session_01NABedeMX43pyXZbDNUgA5B --- .../flask_app/blueprints/statistics.py | 30 ++++- .../templates/statistics/dashboard.html | 114 +++++++++++++++++- .../flask_app/tests/test_statistics.py | 37 ++++++ .../translations/en/LC_MESSAGES/messages.po | 30 +++++ .../translations/it/LC_MESSAGES/messages.po | 30 +++++ 5 files changed, 239 insertions(+), 2 deletions(-) diff --git a/src/frontend/flask_app/blueprints/statistics.py b/src/frontend/flask_app/blueprints/statistics.py index 178716a..e2611d0 100644 --- a/src/frontend/flask_app/blueprints/statistics.py +++ b/src/frontend/flask_app/blueprints/statistics.py @@ -1,12 +1,13 @@ """Metrologist blueprint - SPC statistics dashboard and API proxies.""" import requests as http_requests -from flask import Blueprint, jsonify, render_template, request, session +from flask import Blueprint, abort, jsonify, render_template, request, session from flask_babel import gettext as _ from blueprints.auth import login_required, role_required from config import Config from services.api_client import api_client +from services.file_proxy import proxy_file # #58: allegati dei task statistics_bp = Blueprint("statistics", __name__) @@ -148,6 +149,33 @@ def api_runs(): return jsonify(resp) +@statistics_bp.route("/api/runs//task-results") +@login_required +@role_required("Metrologist") +def api_run_task_results(run_id: int): + """Proxy: esiti, note, campi e allegati dei task di una sessione (#58).""" + resp = api_client.get(f"/api/statistics/runs/{run_id}/task-results") + + if isinstance(resp, dict) and resp.get("error"): + error_body = {"error": True, "detail": resp.get("detail", "")} + if resp.get("session_expired"): + error_body["session_expired"] = True + return jsonify(error_body), resp.get("status_code", 500) + + return jsonify(resp) + + +@statistics_bp.route("/api/files/") +@login_required +@role_required("Metrologist") +def api_task_result_file(file_path: str): + """Proxy: allegati dei task (#58). Solo task_results/, mai altri file.""" + # #58: il Metrologist non deve poter leggere altro dell'upload dir (es. statistics/). + if not file_path.startswith("task_results/") or ".." in file_path.split("/"): + abort(404) + return proxy_file(file_path) + + # ============================================================================ # PROXY REPORT PDF → FastAPI # ============================================================================ diff --git a/src/frontend/flask_app/templates/statistics/dashboard.html b/src/frontend/flask_app/templates/statistics/dashboard.html index 4b4400c..d08d32f 100644 --- a/src/frontend/flask_app/templates/statistics/dashboard.html +++ b/src/frontend/flask_app/templates/statistics/dashboard.html @@ -129,6 +129,74 @@ + +
+

{{ _("Esiti dei task della sessione") }}

+

{{ _("Caricamento...") }}

+

+ +
+