pf_app/routes
Paul Trowbridge d983e2b1df Carry the pivot filter as a scope, operators and all
Refusing anything but == was safe and useless: a view bounded to
sseas_e <= 2027 is an ordinary way to scope a forecast, and it has no slice
form at all, a slice being {col: value}. The filter now travels beside the
slices as [col, op, value] triples and is ANDed onto every unit -- not folded
into the slices, since it applies to all of them equally and under
apply_mode 'each' would just repeat itself in every statement.

Operators are Perspective's, since that is where they come from, and the list
is a whitelist: anything outside it is refused rather than ignored, because a
scope silently dropped is a write wider than the panel that authorised it.
The scope goes into the log's params too, so the audit trail records what
bounded the write and not only what was clicked.

The panel prints it above the selection as "within sseas_e <= 2027". It
scopes every figure below it and every row the operation writes while
appearing in none of the slices, so without it the panel showed a selection
wider than the one it was acting on -- which is exactly what made the
ledger's 956,485.13 look plausible against a cell of 921,225.71.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-18 08:46:23 -04:00
..
auth.js Put the app behind a login 2026-09-14 22:20:25 -04:00
log.js Close the write-only surface left behind by the ordinals 2026-09-17 22:51:34 -04:00
operations.js Carry the pivot filter as a scope, operators and all 2026-09-18 08:46:23 -04:00
sources.js Keep master data for a dim_group instead of re-deriving it from the source 2026-09-17 00:19:39 -04:00
tables.js Expose pf_note/pf_op in forecast data; fix tables list duplicates 2026-04-28 19:51:45 -04:00
versions.js Put the fallback display names on the version 2026-09-17 23:47:17 -04:00