recon_gen.common.tree.date_view
The date-view tree primitive (D5).
A DateView is the single source of truth for a subjective view-window — the analyst-facing “look at the latest day,” “show me the last 30 days,” “today’s statement.” It bundles the owned AsOfFrame (D1; the anchor) with the view’s own definition (empty-behavior + the required-coverage contract). Promoted from the AP.1 spike’s BalanceDateView (tests/unit/test_ap1_view_primitive.py).
Why this exists — the C1 release-blocker shape: a subjective view today is split across THREE independently-authored encodings — the analysis- param default (RollingDate), the dataset-param default (StaticValues sentinel), and the App2 binding. Each is authored in a different place, and they can disagree (that disagreement IS C1: QS reads “yesterday off wall-clock,” App2 reads “latest day,” the dataset KPI summary lands at a day with no rows, the KPI tile reads 0). The DateView inverts the derivation: ONE typed object is the source of truth; every renderer binding derives from it. AR.2 wires those emissions onto this primitive; AR.1 lands the primitive itself.
What is intentionally NOT here (deferred to AR.2):
DateTimeParam.default emission for QS analysis param defaults.
Dataset StaticValues emission for QS dataset param defaults.
ParameterDateTimePicker control emission for the picker widget.
App2 date_from / date_to binding emission.
AR.1 is the authoring abstraction — what app authors construct. AR.2 adds the wired emissions that make the derivation inversion concrete.
Classes
|
A typed view over a date range / single date, owning its own definition (anchor, span, empty-behavior, required-coverage). |
|
How a view resolves when its anchor day has no rows. |
- class recon_gen.common.tree.date_view.DateView(frame, empty_behavior=EmptyBehavior.LATEST_ON_EMPTY)[source]
Bases:
objectA typed view over a date range / single date, owning its own definition (anchor, span, empty-behavior, required-coverage).
The renderer bindings (analysis-param default, dataset-param default, picker widget, App2 binding) all derive from this one object — AR.2’s emission layer. ONE source of truth; the C1 dual-default split becomes unrepresentable.
The frame carries the anchor + window: frame.as_of is the right-edge anchor, frame.window is the typed DateInterval the view queries against (single-day when frame.window.days == 1; rolling N-day when frame.window.days > 1). BD.1 replaced the v1 frame.window_days: int field with frame.window: DateInterval so the “span > 0 means rolling” convention is now a closed-closed days count, not a separate scalar.
Authoring abstraction — not end-user config. App authors construct one of these per surface; the operator never picks one.
- Parameters:
frame (AsOfFrame)
empty_behavior (EmptyBehavior)
- property anchor_day: date
The single date the view points at — frame.as_of. For single-date views this is the only day; for range views this is the right edge.
- emit_qs_analysis_default()[source]
Alias for emit_qs_analysis_default_end() — kept for the single-date case where the “default” is unambiguously the anchor (the AR.2 balance-date wiring’s caller name).
- Return type:
- emit_qs_analysis_default_end()[source]
The QS analysis-param default for the END of a range view (or the single-date case) — a StaticValues literal day, NOT a RollingDate expression. Strict-collapse: the anchor is the owned as_of, baked at deploy.
- Return type:
- emit_qs_analysis_default_start()[source]
The QS analysis-param default for the START of a range view — window_start as StaticValues. AR.4 wires this onto the L1 universal-range start param + the Exec 30-day start param, replacing the per-app RollingDate(addDateTime(-N, …)) expressions.
- Return type:
- emit_qs_dataset_default()[source]
The QS dataset-param default — the SAME literal day as the analysis default. App2 reads this directly; QS receives it via MappedDataSetParameters from the analysis side. Both renderers land on the same day.
For single-date views (Daily Statement) this is unambiguously the anchor. Range views use the start / end variants below; this is kept as an alias of the END for symmetry with
emit_qs_analysis_default.- Return type:
- emit_qs_dataset_default_end()[source]
Phase BM — dataset-param default for the END of a range view (the anchor day). Mirrors
emit_qs_analysis_default_end.- Return type:
- emit_qs_dataset_default_start()[source]
Phase BM — dataset-param default for the START of a range view (
window_start). Mirrorsemit_qs_analysis_default_start; used by L1 + Exec date-pushdown datasets so the BM-shapeDateTimeDatasetParameterfor the start picks up the same 7-day / 30-day window the analysis-level picker shows.- Return type:
- empty_behavior: EmptyBehavior = 1
- is_satisfied_by(available_days)[source]
Does at least one available day fall inside required_coverage? The view’s stated limit, checkable BEFORE render.
- Return type:
bool- Parameters:
available_days (list[date])
- property required_coverage: tuple[date, date]
The date range this view needs data inside to be meaningful. For range views: [window_start, anchor_day]. For single-date views with LATEST_ON_EMPTY: [date.min, anchor] (any prior day will do). For single-date SHOW_EMPTY: [anchor, anchor] (exact-match-or-blank is the contract).
The seed-coverage assertion in AR.3 calls is_satisfied_by(available_days) to make the plant ⟷ query-window contract a test, not developer-memory.
- resolve_day(available_days)[source]
Apply empty_behavior to pick the day this view actually renders.
Returns the anchor_day if it has data, else (for LATEST_ON_EMPTY) the latest day ≤ anchor that does, else None (the view can’t satisfy itself — under SHOW_EMPTY means “render blank for the anchor”; under LATEST_ON_EMPTY means “no data anywhere ≤ anchor”). Range views resolve to their right-edge day the same way.
- Return type:
date|None- Parameters:
available_days (list[date])
- property window_start: date
The look-back’s lower bound — frame.window_start. Equal to anchor_day when the view is single-date (span=0).
- class recon_gen.common.tree.date_view.EmptyBehavior(*values)[source]
Bases:
EnumHow a view resolves when its anchor day has no rows.
Captures the implicit precondition every QS view carries today (audit §5 residual tension): a view “knows” what to do when its declared anchor has no data, but that knowledge lives in developer-memory. Making it explicit on the View object turns the precondition into a property of the type.
- LATEST_ON_EMPTY = 1
If anchor_day has no data, fall back to the latest day with data ≤ anchor. The default for KPI-style “latest statement” views — renders something useful instead of going blank.
- SHOW_EMPTY = 2
Honor anchor_day literally even if it has no rows. The view shows empty. Right for “as-of date is a hard precondition” surfaces where blank IS the correct answer (e.g., a regulator snapshot at an unsettled date).