Move After-the-Roast onto actual roasts; add Artisan-importable updated .alog download
Test and deploy / test-and-deploy (push) Successful in 56s

One system: post-roast observations (weights, colour, DTR, cup notes,
'one change next batch', disproof) now live on the uploaded roast
(actual_roasts.after, migration 011), edited on the roast detail view
with weights/DTR prefilled from the .alog itself. The planner's screen
section is removed (the print worksheet keeps its hand-fill copy), and
the lot 'last refine' suggestion reads the note from both the new home
and legacy plans, newest wins.

Every roast now downloads two ways: the untouched original .alog, and
an updated supplemental copy with the app's data written back as valid
Artisan fields (weight, beans, roastingnotes incl. the LLM review,
cuppingnotes incl. linked cupping score/flavors) — serialized as a
Python literal so Artisan's ast.literal_eval re-imports it.

Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
Shane Maynard
2026-08-09 08:35:11 -04:00
co-authored by Claude Fable 5
parent 9b6ea9880e
commit 4a3d192c2c
12 changed files with 395 additions and 161 deletions
-114
View File
@@ -67,7 +67,6 @@
<a href="#sec-bean">Bean</a>
<a href="#sec-machine">Machine</a>
<a href="#sec-roastlog">Log</a>
<a href="#sec-after">After</a>
</nav>
<div class="header-actions header-tools">
@@ -1173,119 +1172,6 @@
</div>
</section>
<section class="panel-card phase-later" id="sec-after">
<div class="panel-head">
<h2>After the Roast</h2>
<span class="phase-chip">after cupping</span>
</div>
<div class="panel-body">
<details class="why-panel" data-why="sec-after">
<summary>One change per batch — arithmetic, not patience</summary>
<p>
Move two variables and there are four possible
explanations for what the cup does; move three and there
are eight, and you can't separate them without more
batches than you have coffee for. This worksheet makes
single-variable experiments cheap: every number has one
owner.
</p>
<p>
Weight loss is the honest instrument — (green roasted) ÷
green × 100 rolls total time, development, and drop
temperature into one number your scale can measure. Then
match the cup to a symptom: papery or thin → first crack
+0:30. Savory, florals gone → first crack 0:30. Sharp
acidity with no fruit → development +0:15 (a DTR under 12%
confirms it). Flat and dull → development 0:15. Flat with
no clear defect → fix the RoR shape, not the times. Write
the winner into "One change next batch" — and next time
you roast this coffee, carry it into ± Refine (1.6). That
handoff is how the plan learns.
</p>
</details>
<div class="field-grid">
<label class="field"
><span class="field-label">Green in</span>
<div class="unit-input">
<input class="field-input" name="afterRoast.greenIn" /><span
class="unit"
>g</span
>
</div></label
>
<label class="field"
><span class="field-label">Out</span>
<div class="unit-input">
<input class="field-input" name="afterRoast.out" /><span
class="unit"
>g</span
>
</div></label
>
<label class="field"
><span class="field-label">Weight loss</span>
<div class="unit-input">
<input
class="field-input"
name="afterRoast.weightLossPct"
/><span class="unit">%</span>
</div></label
>
<label class="field"
><span class="field-label">Actual DTR</span>
<div class="unit-input">
<input
class="field-input"
name="afterRoast.actualDtrPct"
/><span class="unit">%</span>
</div></label
>
</div>
<div class="field-grid">
<label class="field"
><span class="field-label">Colour WB/GR</span
><input class="field-input" name="afterRoast.colour"
/></label>
<label class="field"
><span class="field-label">Rested</span>
<div class="unit-input">
<input
class="field-input"
name="afterRoast.restedDays"
/><span class="unit">days</span>
</div></label
>
<label class="field"
><span class="field-label">Brew ratio</span
><input class="field-input" name="afterRoast.brewRatio"
/></label>
<label class="field"
><span class="field-label">Method</span
><input class="field-input" name="afterRoast.method"
/></label>
</div>
<label class="field"
><span class="field-label">Cup notes</span
><input class="field-input" name="afterRoast.cupNotes"
/></label>
<div class="field-grid">
<label class="field accent"
><span class="field-label">One change next batch</span
><input class="field-input" name="afterRoast.oneChange"
/></label>
<label class="field"
><span class="field-label">What would prove it wrong</span
><input class="field-input" name="afterRoast.disproof"
/></label>
</div>
<div class="cupping-link">
<button type="button" class="ghost-btn" id="btn-open-cupping">
Open cupping session
</button>
<span class="field-note" id="cupping-link-note"></span>
</div>
</div>
</section>
</div>
<aside class="dock" aria-label="Live plan feedback">