ADR-001: Table presentation under chart style.table and style.columns
Status: Proposed
Decision: For type: table, nest table-wide options under style.table and per-column options under style.columns, alongside existing generic chart style keys (background, etc.). Matches option 3: one style umbrella, table-specific namespace nested like Vega mark-specific config.
Rationale: Reuses the chart style concept; avoids a separate top-level format key; keeps table-only keys out of the same flat namespace as generic chrome.
Consequence: Pre-launch breaking move of table presentation into style.table / style.columns; no committed runtime migration layer—update docs and YAML at cutover.
ADR-002: Treat linking as first-class at table/column scope
Status: Proposed
Decision: Support explicit table/column linking and row-scoped URL sourcing under style.columns.<id>.link: value may be a static URL, a template with column placeholders, or a string that resolves to a column ID (per-row href from that column).
Rationale: Matches real table modeling where link destination often comes from a separate URL column.
Consequence: Needs clear handling for missing/invalid URL values and accessible affordances.
ADR-003: Deterministic precedence model
Status: Proposed
Decision: Resolve links and formatting with explicit precedence rules and conflict behavior.
Rationale: Prevents non-deterministic rendering and hidden overrides.
Consequence: Must be documented and covered by targeted unit tests.
Decision: M2 will not ship a generic conditional rules engine. Conditions/looping should be computed in query/data output, while format config only maps values to presentation attributes.
Rationale: Reduces complexity and ambiguity in first pass and keeps behavior deterministic.
Consequence: A rules engine can be introduced later once core table formatting contracts are stable.
ADR-005: Keep data semantics separate from display formatting
Status: Proposed
Decision: Formatter config decorates rendered output and interactions, but does not alter query meaning.
Rationale: Preserves architecture boundary where query layer owns semantic meaning and ordering.
Consequence: Advanced sort/filter display-specific behavior must be explicit if introduced later.
ADR-006: M2 scope boundary
Status: Proposed
Decision: Ship baseline formatting + linking + visual encodings in M2; defer generic conditional rules engine and advanced plugin extensibility.
Rationale: Delivers immediate value while keeping first-pass config predictable and low-complexity.
Consequence: Document deferred rule-engine capabilities for M3+ once core contracts are stable.
ADR-007: Treat in-cell bars/sparklines as formatting-owned visuals
Status: Proposed
Decision: Sparklines and data bars are not standalone chart kinds. They live under style.columns.<id>.visual. The query owns row data shape (series arrays, numeric magnitudes, null policy); the formatter owns drawing and encodings. String options on visual (e.g. series, colors) use column-ID-first resolution when applicable.
Rationale: Matches BI tools’ cell-visual model; keeps chart types and table cell presentation distinct.
Consequence: Existing spark config moves into style.columns.<id>.visual; document required data shape per visual.type in spec and renderer.
ADR-008: Use exact stable column IDs only in M2
Status: Proposed
Decision: M2 column formatting targets exact stable query column IDs (case-sensitive). No label/index selector matching in M2.
Rationale: Rendered labels can change due to auto title-casing and manual renaming; ID-only matching is simple and robust.
Consequence: Convenience selectors may be added later if needed, but are intentionally deferred for first pass simplicity.
ADR-009: Support row-scoped cross-column references for link/style composition
Status: Proposed
Decision: Allow link and style properties to reference another column in the same row using one key per attribute, resolved at compile time: if the string equals a known column ID, read per-row values from that column; otherwise treat as a literal (with validation).
Rationale: Avoids parallel *FromColumn keys; still supports text + URL column and style helper columns without a rules engine.
Consequence: Validation must handle missing/invalid referenced values safely (graceful skip + warning), and preserve deterministic rendering; document collision rules (ID vs literal).
ADR-010: Query-side templating (including Jinja) is the supported logic layer in M2
Status: Proposed
Decision: Conditional logic for table formatting must be expressed in query/data output (including Jinja-generated SQL helpers). Formatter config is mapping-only in M2.
Rationale: Keeps formatter config simple, deterministic, and safe while preserving flexibility through query composition.
Consequence: Implementation/docs must include guidance and examples for unified keys (textColor, link, …) fed by derived query columns.
ADR-011: Column-ID-first resolution for every applicable string field
Status: Proposed
Decision: Under style.columns.<id>, any scalar string field that semantically can vary per row uses one rule: if the string equals a known query column ID, read per row from that column; otherwise treat as a literal (with validation). Exceptions: header.title is literal-only; style.table.* is literals/enums except row-scoping keys like rowBackgroundColor; generic chart style keys are not column-ID-first; booleans/enums/nested value spec objects follow their own schemas.
Rationale: One mental model, minimal syntax, no *FromColumn proliferation.
Consequence: Compiler must document collision behavior when a literal equals a column ID; tests for style, link, visual, and string adornments on value formatting.
ADR-012: Duplicate YAML keys are compile errors (global)
Status: Proposed
Decision: Any dashboard/face YAML load used by the compiler must reject duplicate keys in a mapping — error, not silent override.
Consequence: Centralize YAML loading or add a cheap post-parse duplicate check; one focused change if the parse path is already unified.
ADR-013: Table value formatting mirrors Vega-Lite
Status: Proposed
Decision: style.columns.<id>.value number/date formatting uses the same field names and semantics as Vega-Lite format / formatType (and related options) so charts and tables share one mental model. (VL’s format is a field name inside value/axis specs, not the old top-level chart key.)
Rationale: Aligns with existing axis/label formatting in the product; avoids inventing a parallel i18n mini-language in YAML.
Consequence: Implement or reuse Python formatting for SVG tables/charts to match that surface (dedicated task).