feat(template): stable fieldId per field — custom_fields keyed by UUID, not label slug

This commit is contained in:
Experiments DB Dev
2026-04-15 14:01:14 -04:00
parent 1305e53f96
commit b7374777d3
5 changed files with 84 additions and 38 deletions
+18 -14
View File
@@ -1,25 +1,29 @@
/**
* The default daily-record template applied to every new experiment
* (and returned as a fallback when an experiment's template is empty).
* The default daily-record template applied to every new experiment.
*
* `builtin: true` — value lives in the named column of daily_statuses
* `builtin: false` — value lives in daily_statuses.custom_fields JSON
* `active: false` — field is hidden (not deleted; data preserved)
* Builtin fields have FIXED fieldIds so they are stable across all experiments
* and can never be confused with user-created fields, even if a user creates a
* custom field with the same label.
*
* `fieldId` — stable UUID used as the storage key; never changes even if
* the field is renamed, reordered, or temporarily removed
* `key` — human-readable slug (display only, not used for storage)
* `builtin` — true: value stored in the dedicated column of daily_statuses
* false: value stored in daily_statuses.custom_fields[fieldId]
* `active` — false: field is hidden (data preserved)
*/
const DEFAULT_TEMPLATE = [
{ key: 'experiment_description', label: 'Experiment Description', type: 'textarea', builtin: true, active: true },
{ key: 'vitals', label: 'Vitals', type: 'text', builtin: true, active: true },
{ key: 'treatment', label: 'Treatment', type: 'text', builtin: true, active: true },
{ key: 'notes', label: 'Notes', type: 'textarea', builtin: true, active: true },
{ fieldId: '00000000-0000-0000-0000-000000000001', key: 'experiment_description', label: 'Experiment Description', type: 'textarea', builtin: true, active: true },
{ fieldId: '00000000-0000-0000-0000-000000000002', key: 'vitals', label: 'Vitals', type: 'text', builtin: true, active: true },
{ fieldId: '00000000-0000-0000-0000-000000000003', key: 'treatment', label: 'Treatment', type: 'text', builtin: true, active: true },
{ fieldId: '00000000-0000-0000-0000-000000000004', key: 'notes', label: 'Notes', type: 'textarea', builtin: true, active: true },
];
/**
* Resolve the effective template for an experiment.
* If the stored template is empty (new experiment), return the default.
*/
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
function resolveTemplate(stored) {
if (!Array.isArray(stored) || stored.length === 0) return DEFAULT_TEMPLATE;
return stored;
}
module.exports = { DEFAULT_TEMPLATE, resolveTemplate };
module.exports = { DEFAULT_TEMPLATE, resolveTemplate, UUID_RE };