Files
roast_command_center/shared/fields.js
T
snowspeeder eda3d8e77f
Test and deploy / test-and-deploy (push) Successful in 1m23s
Add explicit per-plan gauge temperature offset
2026-09-07 07:39:33 -04:00

76 lines
2.7 KiB
JavaScript

// Browser-safe. The allowlist of every scalar worksheet field, and a blank plan factory.
export const FIELD_IDS = [
"0.1", "0.2", "0.3", "0.4",
"1.1", "1.2", "1.3", "1.4", "1.5", "1.6", "1.7",
"2.1", "2.3", "2.4", "2.5",
"3.1", "3.2",
"4.1", "4.2", "4.3", "4.4",
"5.1", "5.2", "5.3", "5.4", "5.5", "5.6",
"6.4",
];
export function blankPlan() {
const fields = {};
for (const id of FIELD_IDS) fields[id] = "";
fields["1.6"] = "0";
fields["2.1"] = "single";
return {
schemaVersion: 1,
sourceUrl: "",
temperatureOffsetF: "",
fields,
blendComponents: [
{ cultivar: "", group: "", process: "", sharePct: "", fcAnchor: "" },
{ cultivar: "", group: "", process: "", sharePct: "", fcAnchor: "" },
],
preheat: { tempC: "", minutes: "", fanPct: "", drumPct: "" },
temps: {
charge: { time: "0:00", tempC: "", tempF: "" },
tp: { time: "", tempC: "", tempF: "" },
yellow: { time: "", tempC: "", tempF: "" },
fc: { time: "", tempC: "", tempF: "" },
drop: { time: "", tempC: "", tempF: "" },
},
ror: {
tpToYellow: { value: "", ok: false, note: "" },
yellowToFc: { value: "", ok: false, note: "" },
fcToDrop: { value: "", ok: false, note: "" },
},
actuators: [
{ time: "0:00", heatPct: "", fanPct: "", expectedBt: "", why: "" },
{ time: "", heatPct: "", fanPct: "", expectedBt: "", why: "" },
{ time: "", heatPct: "", fanPct: "", expectedBt: "", why: "" },
],
planActual: {
charge: { planTime: "0:00", planBt: "", actualTime: "0:00", actualBt: "", ror: "", note: "" },
tp: { planTime: "", planBt: "", actualTime: "", actualBt: "", ror: "", note: "" },
yellow: { planTime: "", planBt: "", actualTime: "", actualBt: "", ror: "", note: "" },
fc: { planTime: "", planBt: "", actualTime: "", actualBt: "", ror: "", note: "" },
drop: { planTime: "", planBt: "", actualTime: "", actualBt: "", ror: "", note: "" },
},
afterRoast: {
greenIn: "", out: "", weightLossPct: "", vsTarget: "", actualDtrPct: "",
colour: "", restedDays: "", brewRatio: "", method: "",
cupNotes: "", cupNotesLine2: "", oneChange: "", disproof: "",
},
sanityOverride: { drying: null, maillard: null, dtr: null, ceiling: null },
reference: null,
prefill: null,
inventory: { lotId: "", lotLabel: "", consumed: null },
};
}
/** Keep only known FIELD_IDS, coerce every value to a string. */
export function sanitizeFieldPatch(patch) {
const out = {};
if (!patch || typeof patch !== "object") return out;
for (const id of FIELD_IDS) {
if (Object.prototype.hasOwnProperty.call(patch, id) && patch[id] !== null && patch[id] !== undefined) {
out[id] = String(patch[id]);
}
}
return out;
}