47 lines
6.7 KiB
Markdown
47 lines
6.7 KiB
Markdown
# Project review — 2026-09-05
|
||
|
||
Reviewed planner calculations, temperature display, generated output, model prompts, product-page fetching, account/ownership checks, inventory transactions, server-file access, dependency advisories, service-worker asset handling, and deployment configuration.
|
||
|
||
## Changes and evidence
|
||
|
||
| Finding | Correction | Verification |
|
||
| --- | --- | --- |
|
||
| Machine pace and uploaded-roast medians silently changed plans. | Planning math, curve defaults and plan-chat context no longer consume machine profiles. Machines retain descriptive history and upload organization. | Ledger/report tests; route test verifies chat receives no machine profiles. |
|
||
| Old Hottop defaults appeared to be portable targets. | Removed machine-band UI/help and replaced curve defaults with explicitly illustrative references. User-entered temperatures take precedence. Preheat has separate fields. | Report tests and Chromium interaction check. |
|
||
| Light development modifiers could produce 1:03 while failing the app's own DTR check. | Disclosed 1:15 suggestion floor for light plans, explicit development override, actionable warnings. This floor is a planning heuristic, not a universal minimum. | Regression covers original 1:38 − 0:30 − 0:05 example and manual override. |
|
||
| Milestone connections could imply increasing late RoR. | Shape-preserving cubic interpolation; default drop gain depends on development duration and is lower per minute than Maillard. Inconsistent manual entries remain visible and are flagged. | Numerical no-overshoot checks, phase-rate checks, explicit inconsistent-target case. |
|
||
| Field-help imports lacked build-version markers and could remain stale after deployment. | Added the same asset-version markers used by the app shell. | Asset stamping and Docker startup checks. |
|
||
| Unit conversion wrote text into entire milestone rows and deleted their controls. | Limit caption updates to table/SVG labels. | Chromium test enters FC in °F, switches to °C and back, and checks values and all six temperature inputs. |
|
||
| Duration parsing accepted invalid seconds and overflow; negative ledger totals could produce impossible plans. | Reject invalid/unsafe durations; flag nonpositive milestones and implausible density units without silently changing density. | Parser and ledger regressions. |
|
||
| Printing reused a dense legacy worksheet; there was no standalone report download. | Shared report renderer, preview, print and downloadable HTML with inline CSS/SVG. All report temperatures use °F and mass uses g. | Escaping tests, browser download/print tests; sample PDF visually checked and measured at two Letter pages. Long notes/schedules can add pages. |
|
||
| HTTPS product fetches could reach private services, including via redirects; deadline ended before body reading. | Public IP validation for all DNS answers, pinned socket lookup, per-redirect checks, deadline through response streaming, bounded body. Removed Browserless fallback because it bypassed those protections. | Literal/private/mapped IP, mixed DNS, redirect, stalled-body and authenticated-route tests. |
|
||
| Any account could read the operator's server roast library; read calls followed symlinks. | Admin-only library routes, exact basenames, no-follow file opens, regular-file and size checks. Personal uploads retain existing ownership checks. | Admin/nonadmin route tests and traversal/symlink regressions. |
|
||
| Locked production dependencies had reported vulnerabilities. | Updated Pi SDK to 0.85.1 and refreshed affected transitive packages, including undici, brace-expansion and qs. Declared Node >=22.19; Docker uses Node 24. | Production dependency audit reports zero known vulnerabilities; startup and app suite check compatibility. |
|
||
|
||
## Interpretation and limits
|
||
|
||
The existing cultivar worksheet is a starting framework, not a validated physical model. A light or fruity cup cannot be guaranteed from duration, DTR or a turning-point reading. Prompts and report text now make that distinction. Phase averages cannot prove that an instantaneous trace has no crash or flick.
|
||
|
||
References checked:
|
||
|
||
- [Scott Rao — Coffee Roasting Fundamentals](https://www.scottrao.com/blog/2020/3/29/coffee-roasting-fundamentals): absolute probe readings do not transfer directly; duration and DTR alone do not establish quality.
|
||
- [Sweet Maria's — First Crack FAQ](https://library.sweetmarias.com/first-crack-faq-what-is-first-crack-what-is-second-crack/): audible first crack and temperature context for the illustrative reference.
|
||
- [Kaleido Standard Roasting Guide](https://www.kaleido-coffee.com/news/kaleido-standard-roasting-guide): distinguishes preheat SV from BT and uses a 750 g M10 reference batch. Its settings are not applied automatically by this planner.
|
||
|
||
No historical roast files or measured temperatures were rewritten. Legacy profile endpoints remain for compatibility/descriptive history, but do not drive plans. This review does not independently validate every claim in the historical cultivar tables or Academy narration. External storefronts that block direct requests may now require manual entry. Model-output quality still depends on the configured provider; automated tests isolate model calls rather than spending production inference credits.
|
||
|
||
## Reproduce checks
|
||
|
||
- `npm test`: unit/API/security/persistence tests and Docker startup with migrations. The browser case is opt-in.
|
||
- `npx playwright install chromium && npm run test:browser`: real Chromium form, unit-toggle, preview, download and print regressions.
|
||
- `npm audit --omit=dev`: production dependency advisories.
|
||
- Push `master`, then verify the matching Gitea Actions run succeeds. The pipeline owns deployment; do not redeploy manually afterward.
|
||
|
||
## Print and plan-library follow-up
|
||
|
||
Removed the Planner's Machine Plan section and moved editable Plan vs Actual observations to individual finished roasts. Observations retain imported readings as their fallback and do not rewrite uploaded telemetry. Ownership checks and backup/restore include the new observations field.
|
||
|
||
The Plans navigation now opens a searchable, filterable table with 25 results per page, backed by server pagination. Selecting a plan loads that exact ID; leaving through Your Plans first flushes pending edits. Finished-roast lists also have search, filters and pagination, and plan attachment supports searching the library.
|
||
|
||
A forced page break caused a footer-only page when warning text pushed the report beyond its first page. Reports now flow naturally, with a compact print layout and grouped record headings. Chromium tests count actual PDF pages for the warning-rich report, downloaded HTML, 110% scaling and A4; additional browser cases cover switching plans without losing edits and saving finished-roast observations.
|