diff --git a/pf_spec.md b/pf_spec.md index b3a276b..b36e929 100644 --- a/pf_spec.md +++ b/pf_spec.md @@ -237,8 +237,7 @@ Source registration, col_meta configuration, SQL generation, version creation, a } ``` -- `date_from` / `date_to` — optional when `filters` constrain the result sufficiently; if omitted the date range clause is skipped -- `date_col` — which date column to apply the range to; defaults to the source's primary `role = 'date'` column; can be any `role = 'date'` or `role = 'filter'` column with a date type +- `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 when inserting (not to filter columns). Examples: `"1 year"`, `"6 months"`, `"2 years 3 months"`. Defaults to `"0 days"`. - `filters` — zero or more additional filter conditions. Each has: - `col` — must be `role = 'filter'` or `role = 'date'` in col_meta @@ -423,24 +422,25 @@ A dedicated view for constructing the baseline for the selected version. The bas **Add Segment form:** - **Description** — free text label stored as the log `note`, shown in the segments list -- **Date range** — date_from / date_to, applied to the selected date column (defaults to the primary `role = 'date'` column, but can be any `role = 'filter'` column with a date type) -- **Date offset** — years + months spinners; shifts loaded dates into the forecast period -- **Additional filters** — zero or more filter conditions, each specifying: - - Column — any `role = 'filter'` column +- **Date offset** — years + months spinners; shifts the primary `role = 'date'` column forward on insert +- **Filters** — one or more filter conditions that define what rows to pull. There is no separate "date range" section — period selection is just a filter like any other: + - Column — any `role = 'date'` or `role = 'filter'` column - Operator — `=`, `!=`, `IN`, `NOT IN`, `BETWEEN`, `IS NULL`, `IS NOT NULL` - - Value(s) — text input; for `IN`/`NOT IN` a comma-separated list; for `BETWEEN` two inputs -- **Preview** — once dates and offset are set, shows source months → projected months (same as current baseline modal) -- **Load Segment** — submits the segment; appends rows, does not clear existing baseline rows + - Value(s) — for `BETWEEN`: two date/text inputs; for `IN`/`NOT IN`: comma-separated list; for `=`/`!=`: single input; omitted for `IS NULL`/`IS NOT NULL` + - At least one filter is required to load a segment +- **Timeline preview** — rendered when any filter condition is a `BETWEEN` or `=` on a `role = 'date'` column. Shows a horizontal bar (number-line style) for the source period and, if offset > 0, a second bar below for the projected period. Each bar shows start date on the left, end date on the right, duration in the centre. The two bars share the same visual width so the shift is immediately apparent. For non-date filters (e.g. `season IN (...)`) no timeline is shown. +- **Note** — optional free text +- **Load Segment** — submits; appends rows, does not clear existing baseline rows **Example — three-segment baseline:** -| # | Description | Date col | Range | Filters | Offset | -|---|-------------|----------|-------|---------|--------| -| 1 | All orders taken 6/1/25–3/31/26 | order_date | 6/1/25–3/31/26 | — | 0 | -| 2 | All open/unshipped orders | order_date | (none — omit date filter) | status IN (OPEN, PENDING) | 0 | -| 3 | Prior year book-and-ship 4/1/25–5/31/25 | order_date | 4/1/25–5/31/25 | ship_date BETWEEN 4/1/25 AND 5/31/25 | 0 | +| # | Description | Filters | Offset | +|---|-------------|---------|--------| +| 1 | All orders taken 6/1/25–3/31/26 | `order_date BETWEEN 2025-06-01 AND 2026-03-31` | 0 | +| 2 | All open/unshipped orders | `status IN (OPEN, PENDING)` | 0 | +| 3 | Prior year book-and-ship 4/1/25–5/31/25 | `order_date BETWEEN 2025-04-01 AND 2025-05-31`, `ship_date BETWEEN 2025-04-01 AND 2025-05-31` | 0 | -Note: segment 2 omits the date range entirely — date_from/date_to are optional when additional filters are present. The SQL omits the date BETWEEN clause if no dates are provided. +Note: segment 2 has no date filter — any filter combination is valid as long as at least one filter is present. ### Forecast View