feat(analysis): attenuation, fermentation curves and brew timings #12

Merged
hermes merged 4 commits from feat/deep-analysis into master 2026-11-09 14:18:45 +10:00
3 changed files with 21 additions and 1 deletions
Showing only changes of commit 6fec78e9e4 - Show all commits
+1 -1
View File
@@ -184,7 +184,7 @@
</div>
<div class="card__body">
<p>
Across {{ stats.trusted_count }} finished brews the attenuation averages
Across {% if stats.suspect_count %}{{ stats.trusted_count }} of {{ stats.count }}{% else %}{{ stats.count }}{% endif %} finished brews the attenuation averages
<strong>{{ stats.consistency.mean }}%</strong>, with a standard
deviation of <strong>{{ stats.consistency.stdev }} percentage
points</strong> and a total range of {{ stats.consistency.spread }}
+3
View File
@@ -208,6 +208,9 @@ def api_run(run_id: str):
summary = run_summary(run, og_override=meta.get("og_points"))
summary["canonical_name"] = meta.get("name") or run.display_name()
summary["tap_number"] = meta.get("tap_number")
# The same flag the list endpoint carries, so a consumer of the detail
# endpoint can tell an impossible run from a good one.
summary["suspect"] = bool(implausible_runs([run]))
return jsonify(summary)
+17
View File
@@ -361,6 +361,23 @@ def test_a_suspect_run_is_not_the_strongest_brew_in_the_history(logged_in, repo)
)
def test_the_run_detail_api_also_flags_a_suspect_run(logged_in, repo):
"""The detail endpoint carries the same flag as the list endpoint.
A consumer of /api/runs/<run_id> must be able to tell an impossible
run from a good one.
"""
_two_runs(repo)
response = logged_in.get("/api/runs/12")
assert response.status_code == 200
assert response.get_json()["suspect"] is True
response = logged_in.get("/api/runs/1")
assert response.status_code == 200
assert response.get_json()["suspect"] is False
def test_the_charts_skip_suspect_runs():
"""The chart script must leave the suspect runs out.