Add brewing section, plan chat, roaster learning, API tokens, Swagger docs, and full backup
Test and deploy / test-and-deploy (push) Successful in 1m6s
Test and deploy / test-and-deploy (push) Successful in 1m6s
Brewing: - roasted_beans + brews tables; /beans (bean management with LLM URL prefill) and /brews (silhouette brewer picker across immersion/ percolation/espresso, recipe fields, auto ratio, 0-10 rating, tasting notes); bean remaining weight derived from logged brew doses - Green inventory lot form also prefills from a product URL Navigation/UX: - Side nav is now generated from one definition in nav.js, grouped Roasting / Brewing / account, consistent on every page LLM: - 'Ask the LLM' chat drawer on the planner (stateless /api/plan-chat) grounded in the plan, computed ledger, learned pace, and a new roaster-behavior profile aggregated from uploaded .alogs (/api/roaster-profile: TP lag, phase RoR, median milestone temps) - The profile also feeds roast reviews and the planner curve's fallback milestone temps API platform: - User-generated bearer tokens (rpt_…) with account-page management; token requests skip CSRF; hand-authored OpenAPI 3 spec at /api/openapi.json rendered by self-hosted Swagger UI at /api-docs - Full-database backup export/import (admin) + per-user data export Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Fable 5
parent
5efaeb63c9
commit
38c7d01e03
@@ -59,7 +59,7 @@ function rorSegments(curve) {
|
||||
|
||||
/** Deterministic, model-free digest of the parsed roast (+ optional plan targets). Also stored
|
||||
* alongside the model's text so the UI can show the same numbers the model was judged on. */
|
||||
export function buildRoastFacts(parsed, plan) {
|
||||
export function buildRoastFacts(parsed, plan, roasterProfile = null) {
|
||||
const curve = parsed.curve ?? [];
|
||||
const milestone = (key) => parsed.milestones?.find((m) => m.key === key) ?? null;
|
||||
const yellow = milestone("yellow");
|
||||
@@ -94,6 +94,11 @@ export function buildRoastFacts(parsed, plan) {
|
||||
rorSegments: rorSegments(curve),
|
||||
parserWarnings: parsed.warnings ?? [],
|
||||
planTargets: null,
|
||||
// How this user's machine typically behaves, learned from their previously uploaded
|
||||
// roasts — lets the review distinguish "your roaster always lags like this" from a
|
||||
// one-off anomaly.
|
||||
typicalRoasterBehavior:
|
||||
roasterProfile && roasterProfile.n > 0 ? roasterProfile : null,
|
||||
};
|
||||
|
||||
if (plan) {
|
||||
@@ -122,12 +127,12 @@ export function buildRoastFacts(parsed, plan) {
|
||||
* @param {string|null} preferredModel admin-configured "provider:id", empty/null for auto
|
||||
* @returns {Promise<object>} evaluation object (schema above + `facts`)
|
||||
*/
|
||||
export async function evaluateRoast(parsed, plan = null, preferredModel = null) {
|
||||
export async function evaluateRoast(parsed, plan = null, preferredModel = null, roasterProfile = null) {
|
||||
const modelRuntime = await getModelRuntime();
|
||||
const model = await pickModel(preferredModel);
|
||||
if (!model) throw noModelError();
|
||||
|
||||
const facts = buildRoastFacts(parsed, plan);
|
||||
const facts = buildRoastFacts(parsed, plan, roasterProfile);
|
||||
|
||||
const resourceLoader = new DefaultResourceLoader({
|
||||
cwd: process.cwd(),
|
||||
|
||||
Reference in New Issue
Block a user