From 424199c1aac8f334aa232a5429e010c19c35bdc1 Mon Sep 17 00:00:00 2001 From: Paul Trowbridge Date: Thu, 17 Sep 2026 14:46:13 -0400 Subject: [PATCH] Name the ordering columns pf_bucket_ord and pf_segment_ord "Bucket" and "Segment" sit too close to the source data -- segment_new is an actual column here -- and a name collision would be worse than a confusing label: an expression named after an existing column shadows or rejects it rather than just reading ambiguously. pf_ prefixed like every other synthesised column, so they sort beside pf_bucket and pf_segment in the column list and read as belonging to the app. The old names are kept in the managed list so they are cleared from configs that still carry them. Without that they would sit in saved layouts forever, ordering by a rule nothing updates -- which is exactly what a stale Segment expression was already doing. Co-Authored-By: Claude Opus 5 (1M context) --- ui/src/views/Forecast.jsx | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/ui/src/views/Forecast.jsx b/ui/src/views/Forecast.jsx index 0d2c1ab..2eb268b 100644 --- a/ui/src/views/Forecast.jsx +++ b/ui/src/views/Forecast.jsx @@ -48,7 +48,18 @@ function cleanLayout(cfg, validCols) { // double quotes, string literals in single, if/else with braces. The ordered // label is emitted as a literal rather than built with concat() — fewer moving // parts, and the mapping is known here anyway. -const ORDER_EXPR_NAMES = { bucket: 'Bucket', segment: 'Segment' } +// pf_ prefixed like every other column the server synthesises, so they sort +// beside pf_bucket and pf_segment in the column list and cannot be mistaken for +// source data. "Bucket" and "Segment" were the first choice and are too close to +// the real thing -- segment_new is an actual column on this source -- and an +// expression named after an existing column would shadow or reject rather than +// merely confuse. +const ORDER_EXPR_NAMES = { bucket: 'pf_bucket_ord', segment: 'pf_segment_ord' } + +// Removed from any config that still carries them. They are no longer managed +// names, so without this they would sit in saved layouts forever, ordering by a +// rule nothing updates. +const LEGACY_ORDER_EXPR_NAMES = ['Bucket', 'Segment'] // ASCII only, and " - " specifically because the source data already reads // "07 - Dec". A middle dot was the first choice and ExprTK rejects it: its string @@ -972,7 +983,7 @@ export default function Forecast({ sources = [], sourceId, versions = [], versio const { table: _t, ...cfg } = await viewer.save() dbgOrder('saved config read', { existing: Object.keys(cfg.expressions || {}) }) const current = cfg.expressions || {} - const managed = Object.values(ORDER_EXPR_NAMES) + const managed = [...Object.values(ORDER_EXPR_NAMES), ...LEGACY_ORDER_EXPR_NAMES] const next = { ...current } for (const name of managed) delete next[name]