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
+10 -2
View File
@@ -53,7 +53,14 @@ function FieldRow({ field, onChange, onToggle, onRemove, allKeys }) {
onKeyDown={(e) => { if (e.key === 'Enter') { e.preventDefault(); commitLabel(); } }}
/>
{labelError && <p className="text-xs text-red-500 mt-0.5">{labelError}</p>}
<p className="text-xs text-gray-400 mt-0.5 font-mono">key: {field.key}</p>
<p className="text-xs text-gray-400 mt-0.5 font-mono">
key: {field.key}
{field.fieldId && (
<span className="ml-2 text-gray-300" title={`Stable field ID: ${field.fieldId}`}>
· id: {field.fieldId.slice(0, 8)}
</span>
)}
</p>
</div>
{/* Type badge */}
@@ -133,7 +140,8 @@ export default function TemplateEditor({ experimentId, onClose }) {
if (!key) { setAddError('Name must contain at least one alphanumeric character'); return; }
if (fields.some((f) => f.key === key)) { setAddError(`A field with key "${key}" already exists`); return; }
setAddError('');
setFields((prev) => [...prev, { key, label: trimmed, type: newType, builtin: false, active: true }]);
const fieldId = crypto.randomUUID();
setFields((prev) => [...prev, { fieldId, key, label: trimmed, type: newType, builtin: false, active: true }]);
setNewLabel('');
setNewType('text');
}