id: temporal_period_stats
name: Period Stats
description: >
  Compute statistics per calendar time period. Groups rows by a truncated
  timestamp (e.g., month, year) and computes aggregations on value columns.
version: 1.0.0
category: aggregate
type: table-to-table
default_implementation: duckdb

inputs:
  - name: table
    type: table
    format: parquet
    description: Input table with a timestamp column
    required: true

requires: {}

outputs:
  - name: result
    type: table
    format: parquet
    description: Table with one row per period containing aggregated statistics

params:
  time_column:
    type: string
    description: Name of the timestamp column
    required: true
  period:
    type: string
    enum: [second, minute, hour, day, week, month, quarter, year]
    description: Calendar period to group by
    required: true
  value_columns:
    type: array
    items:
      type: string
    description: Columns to aggregate
    required: true
  aggregations:
    type: object
    description: >
      Map of output_name -> SQL aggregate expression
      (e.g., {"avg_temp": "AVG(temp)", "max_temp": "MAX(temp)"}).
      If omitted, computes AVG for each value column.

# backends: audited 2026-08-14 (defect 50). A key means a runtime that DISPATCHES this op —
# folia-engine `dispatch_op` (products/sdk/folia-engine/src/lib.rs), a `registerOp`/OP_TABLE
# entry in packages/compute, `_BUILTIN_OP_MAP` in folia/compute.py, or a backend manifest
# (folia/backends/*/backend.yaml).
backends:
  rust-wasm:
    op: temporal_period_stats
    dispatch: packages/compute/src/ops/wasm-bridge.ts registerOp
  js:
    function: temporal_period_stats
    dispatch: packages/compute/src/ops/wasm-bridge.ts
  python:
    function: temporal.ops.period_stats
    dispatch: folia/compute.py _BUILTIN_OP_MAP

display_hints:
  chart:
    renderer: observable-plot
    chartType: bar
    xAxis: { field: period }
  table:
    renderer: tanstack-table
