Stop a segment edit from wiping its annotations
PUT /versions/:id/baseline/:logid deletes the log row and inserts a fresh one from the stored template, so every field the form does not send comes back null. That took the label and the bucket with it, and the tag besides -- the segment form has no tag input at all, so a tag could not survive an edit made for any other reason. The route now hands back what it was not given, reading the row it is about to replace. `??` rather than `||`: an empty string is the form clearing a field deliberately, undefined is the form not carrying it. The load templates gained a tag token to receive it. Stored templates are per-source and were generated before any of this existed, which is the other half of why labels vanished -- source 14's had no label column to write to. Regenerated. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
3162759f93
commit
2306315a17
@ -8,7 +8,7 @@
|
||||
// Tokens baked in at generation time: column names, source schema.table
|
||||
// Tokens substituted at request time: {{fc_table}}, {{where_clause}}, {{exclude_clause}},
|
||||
// {{version_id}}, {{logid}}, {{pf_user}}, {{note}},
|
||||
// {{label}}, {{bucket}},
|
||||
// {{label}}, {{bucket}}, {{tag}},
|
||||
// {{params}}, {{slice}}, {{date_from}}, {{date_to}},
|
||||
// {{value_incr}}, {{units_incr}}, {{set_clause}}, {{scale_factor}}
|
||||
|
||||
@ -303,9 +303,9 @@ GROUP BY
|
||||
return `
|
||||
WITH
|
||||
ilog AS (
|
||||
INSERT INTO pf.log (version_id, pf_user, operation, slice, params, note, label, bucket)
|
||||
INSERT INTO pf.log (version_id, pf_user, operation, slice, params, note, label, bucket, tag)
|
||||
VALUES ({{version_id}}, '{{pf_user}}', 'baseline', NULL, '{{params}}'::jsonb, '{{note}}',
|
||||
NULLIF('{{label}}', ''), NULLIF('{{bucket}}', ''))
|
||||
NULLIF('{{label}}', ''), NULLIF('{{bucket}}', ''), NULLIF('{{tag}}', ''))
|
||||
RETURNING id
|
||||
)
|
||||
,ins AS (
|
||||
@ -324,9 +324,9 @@ SELECT count(*) AS rows_affected FROM ins`.trim();
|
||||
return `
|
||||
WITH
|
||||
ilog AS (
|
||||
INSERT INTO pf.log (version_id, pf_user, operation, slice, params, note, label, bucket)
|
||||
INSERT INTO pf.log (version_id, pf_user, operation, slice, params, note, label, bucket, tag)
|
||||
VALUES ({{version_id}}, '{{pf_user}}', 'reference', NULL, '{{params}}'::jsonb, '{{note}}',
|
||||
NULLIF('{{label}}', ''), NULLIF('{{bucket}}', ''))
|
||||
NULLIF('{{label}}', ''), NULLIF('{{bucket}}', ''), NULLIF('{{tag}}', ''))
|
||||
RETURNING id
|
||||
)
|
||||
,ins AS (
|
||||
|
||||
@ -409,7 +409,7 @@ module.exports = function(pool) {
|
||||
|
||||
// load baseline rows from source table — additive, no delete
|
||||
router.post('/versions/:id/baseline', async (req, res) => {
|
||||
const { where_clause, date_offset, note, filters, raw_where, label, bucket } = req.body;
|
||||
const { where_clause, date_offset, note, filters, raw_where, label, bucket, tag } = req.body;
|
||||
const pf_user = sessionUser(req);
|
||||
const dateOffset = date_offset || '0 days';
|
||||
if (!await assertInterval(dateOffset, res)) return;
|
||||
@ -429,6 +429,7 @@ module.exports = function(pool) {
|
||||
note: esc(note || ''),
|
||||
label: esc(label || ''),
|
||||
bucket: esc(bucket || ''),
|
||||
tag: esc(tag || ''),
|
||||
params: esc(paramsJson),
|
||||
filter_clause: filterClause,
|
||||
date_offset: esc(dateOffset)
|
||||
@ -448,7 +449,7 @@ module.exports = function(pool) {
|
||||
router.put('/versions/:id/baseline/:logid', async (req, res) => {
|
||||
const versionId = parseInt(req.params.id);
|
||||
const logid = parseInt(req.params.logid);
|
||||
const { where_clause, date_offset, note, filters, raw_where, label, bucket } = req.body;
|
||||
const { where_clause, date_offset, note, filters, raw_where, label, bucket, tag } = req.body;
|
||||
const pf_user = sessionUser(req);
|
||||
const dateOffset = date_offset || '0 days';
|
||||
if (!await assertInterval(dateOffset, res)) return;
|
||||
@ -487,13 +488,21 @@ module.exports = function(pool) {
|
||||
date_offset: dateOffset,
|
||||
...(raw_where ? { raw_where } : (filters ? { filters } : {}))
|
||||
});
|
||||
// This route deletes the log row and inserts a fresh one, so every
|
||||
// annotation on it has to be handed back or it is lost. `??`, not `||`:
|
||||
// an empty string is the form clearing a field on purpose, undefined is
|
||||
// the form not carrying it at all -- the segment form has no tag input,
|
||||
// so tag is always the latter and must survive an edit made for any
|
||||
// other reason.
|
||||
const keep = (sent, prior) => esc(sent ?? prior ?? '');
|
||||
const sql = applyTokens(ctx.sql, {
|
||||
fc_table: ctx.table,
|
||||
version_id: ctx.version.id,
|
||||
pf_user: esc(pf_user || ''),
|
||||
note: esc(note || ''),
|
||||
label: esc(label || ''),
|
||||
bucket: esc(bucket || ''),
|
||||
label: keep(label, oldLog.label),
|
||||
bucket: keep(bucket, oldLog.bucket),
|
||||
tag: keep(tag, oldLog.tag),
|
||||
params: esc(paramsJson),
|
||||
filter_clause: filterClause,
|
||||
date_offset: esc(dateOffset)
|
||||
@ -558,7 +567,7 @@ module.exports = function(pool) {
|
||||
|
||||
// load reference rows from source table (additive — does not clear prior reference rows)
|
||||
router.post('/versions/:id/reference', async (req, res) => {
|
||||
const { where_clause, date_offset, note, filters, raw_where, label, bucket } = req.body;
|
||||
const { where_clause, date_offset, note, filters, raw_where, label, bucket, tag } = req.body;
|
||||
const pf_user = sessionUser(req);
|
||||
const dateOffset = date_offset || '0 days';
|
||||
const filterClause = (raw_where || where_clause || '').trim() || 'TRUE';
|
||||
@ -577,6 +586,7 @@ module.exports = function(pool) {
|
||||
note: esc(note || ''),
|
||||
label: esc(label || ''),
|
||||
bucket: esc(bucket || ''),
|
||||
tag: esc(tag || ''),
|
||||
params: esc(paramsJson),
|
||||
filter_clause: filterClause,
|
||||
date_offset: esc(dateOffset)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user