Fix baseline request body in spec — unified filters array
Removes the redundant date_from/date_to/date_col fields from the request
body. Period selection is now expressed as a filter condition in the
filters array like any other condition. SQL pattern updated to match
(single {{filter_clause}} token instead of date_range + filter split).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
f0c51096ff
commit
7e9ea456b6
25
pf_spec.md
25
pf_spec.md
@ -223,26 +223,23 @@ Source registration, col_meta configuration, SQL generation, version creation, a
|
|||||||
**Baseline load request body:**
|
**Baseline load request body:**
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"date_from": "2024-01-01",
|
|
||||||
"date_to": "2024-12-31",
|
|
||||||
"date_col": "order_date",
|
|
||||||
"date_offset": "1 year",
|
"date_offset": "1 year",
|
||||||
"filters": [
|
"filters": [
|
||||||
{ "col": "order_status", "op": "IN", "values": ["OPEN", "PENDING"] },
|
{ "col": "order_date", "op": "BETWEEN", "values": ["2024-01-01", "2024-12-31"] },
|
||||||
{ "col": "ship_date", "op": "BETWEEN", "values": ["2025-04-01", "2025-05-31"] }
|
{ "col": "order_status", "op": "IN", "values": ["OPEN", "PENDING"] }
|
||||||
],
|
],
|
||||||
"pf_user": "admin",
|
"pf_user": "admin",
|
||||||
"note": "Open orders regardless of order date",
|
"note": "FY2024 actuals + open orders projected to FY2025",
|
||||||
"replay": false
|
"replay": false
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- `date_from` / `date_to` / `date_col` — removed; period selection is expressed as a filter condition in the `filters` array like any other condition
|
- `date_offset` — PostgreSQL interval string applied to the primary `role = 'date'` column at insert time. Examples: `"1 year"`, `"6 months"`, `"2 years 3 months"`. Defaults to `"0 days"`. Applied to the stored date value only — filter columns are never shifted.
|
||||||
- `date_offset` — PostgreSQL interval string applied to the primary `role = 'date'` column when inserting (not to filter columns). Examples: `"1 year"`, `"6 months"`, `"2 years 3 months"`. Defaults to `"0 days"`.
|
- `filters` — one or more filter conditions defining what rows to pull from the source table. Period selection (date range, season, fiscal year, etc.) is expressed here as a regular filter — there is no separate date range parameter. Each condition has:
|
||||||
- `filters` — zero or more additional filter conditions. Each has:
|
- `col` — must be `role = 'date'` or `role = 'filter'` in col_meta
|
||||||
- `col` — must be `role = 'filter'` or `role = 'date'` in col_meta
|
|
||||||
- `op` — one of `=`, `!=`, `IN`, `NOT IN`, `BETWEEN`, `IS NULL`, `IS NOT NULL`
|
- `op` — one of `=`, `!=`, `IN`, `NOT IN`, `BETWEEN`, `IS NULL`, `IS NOT NULL`
|
||||||
- `values` — array of strings; two elements for `BETWEEN`, multiple for `IN`/`NOT IN`, omitted for `IS NULL`/`IS NOT NULL`
|
- `values` — array of strings; two elements for `BETWEEN`; multiple for `IN`/`NOT IN`; omitted for `IS NULL`/`IS NOT NULL`
|
||||||
|
- At least one filter is required.
|
||||||
- Baseline loads are **additive** — existing `iter = 'baseline'` rows are not touched. Each load is its own log entry and is independently undoable.
|
- Baseline loads are **additive** — existing `iter = 'baseline'` rows are not touched. Each load is its own log entry and is independently undoable.
|
||||||
|
|
||||||
`replay` controls behavior when incremental rows exist (applies to Clear + reload, not individual segments):
|
`replay` controls behavior when incremental rows exist (applies to Clear + reload, not individual segments):
|
||||||
@ -504,7 +501,6 @@ SELECT
|
|||||||
FROM
|
FROM
|
||||||
{schema}.{tname}
|
{schema}.{tname}
|
||||||
WHERE
|
WHERE
|
||||||
{{date_range_clause}}
|
|
||||||
{{filter_clause}}
|
{{filter_clause}}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -512,10 +508,7 @@ Baseline loads are **additive** — no DELETE before INSERT. Each segment append
|
|||||||
|
|
||||||
Token details:
|
Token details:
|
||||||
- `{{date_offset}}` — PostgreSQL interval string (e.g. `1 year`); defaults to `0 days`; applied only to the primary `role = 'date'` column on insert
|
- `{{date_offset}}` — PostgreSQL interval string (e.g. `1 year`); defaults to `0 days`; applied only to the primary `role = 'date'` column on insert
|
||||||
- `{{date_range_clause}}` — built from `date_from`/`date_to`/`date_col` by the route; omitted entirely (replaced with `TRUE`) if no dates provided
|
- `{{filter_clause}}` — one or more `AND` conditions built from the `filters` array at request time (not baked into stored SQL since conditions vary per segment). Each condition is validated against col_meta (column must be `role = 'date'` or `role = 'filter'`). Supported operators: `=`, `!=`, `IN`, `NOT IN`, `BETWEEN`, `IS NULL`, `IS NOT NULL`.
|
||||||
- `{{filter_clause}}` — zero or more `AND` conditions built from the `filters` array; each validated against col_meta (column must be `role = 'filter'` or `role = 'date'`); operators: `=`, `!=`, `IN`, `NOT IN`, `BETWEEN`, `IS NULL`, `IS NOT NULL`
|
|
||||||
|
|
||||||
Both clauses are built at request time (not baked into stored SQL) since they vary per segment load.
|
|
||||||
|
|
||||||
### Clear Baseline
|
### Clear Baseline
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user