feat(measure): proxy JSON per il progresso di un task (#37.8, parziale)
GET /measure/api/task-progress/<task_id>: il browser non puo' chiamare /api/measurements/task-progress del backend (niente X-API-Key). Login + stesso controllo di stazione di task_execute() (_recipe_allowed_at_station), poi inoltra a _task_progress() con lo stesso version_id/production_run_id gia' usato da task_list.html. Non tocca task_execute.html: /api/measurements/task-progress risponde con conteggi aggregati per task (quotes/measured/state), non con le quote-per-quota misurate (subtask_id, value, pass_fail, deviation) che `this.measurements` richiede - ripristinarlo avrebbe richiesto inventare valori o uno stato non offerto dal backend. MANCA: mostrato in dettaglio nel rapporto finale. Test Flask della route: riga per il task richiesto, default a "empty" se assente, 403 fuori stazione, propagazione 404, login richiesto. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -565,6 +565,38 @@ def save_measurement():
|
||||
return jsonify(resp), 201
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Route: task progress (#37.8) - browser cannot call the backend directly
|
||||
# (X-API-Key), same as every other /api/* proxy in this file.
|
||||
# ---------------------------------------------------------------------------
|
||||
@measure_bp.route("/api/task-progress/<int:task_id>", methods=["GET"])
|
||||
@login_required
|
||||
@role_required("MeasurementTec")
|
||||
def api_task_progress(task_id: int):
|
||||
"""Proxy: how many quotes of this task are already measured.
|
||||
|
||||
Reuses _task_progress() - same version_id/production_run_id scoping as
|
||||
task_list.html's badges - so this answers with exactly the counts
|
||||
(quotes/measured/state) the backend can give without conflating one
|
||||
cycle with another; it does not, and cannot, say which quotes or with
|
||||
what values (task-progress is an aggregate, not a per-subtask list).
|
||||
"""
|
||||
task_resp = api_client.get(f"/api/tasks/{task_id}")
|
||||
if isinstance(task_resp, dict) and task_resp.get("error"):
|
||||
return jsonify(task_resp), task_resp.get("status_code", 500)
|
||||
|
||||
recipe_id = task_resp.get("recipe_id")
|
||||
if recipe_id and not _recipe_allowed_at_station(recipe_id):
|
||||
abort(403, description=_("Ricetta non assegnata a questa stazione"))
|
||||
|
||||
version_id = task_resp.get("version_id")
|
||||
progress = _task_progress(version_id, _current_run_id())
|
||||
row = progress.get(task_id, {
|
||||
"task_id": task_id, "quotes": 0, "measured": 0, "state": "empty",
|
||||
})
|
||||
return jsonify(row), 200
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Routes: Out-of-tolerance authorisation (point 5)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user