Current section
Files
Jump to
Current section
Files
CHANGELOG.md
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.4.0] - 2026-08-08
### Added
- `AshDyan.Extension` behaviour plus `AshDyan.Extension.Loader` for formal,
composable extensions that register analysis types, data-layer capabilities,
custom aggregates, pipeline hooks, and DSL entities without forking.
- Pipeline hooks via the `AshDyan.Engine.Hook` behaviour: `before_query`,
`after_query`, `before_format`, `after_format` stages, runnable from either
`config :ash_dyan, :hooks` or an extension.
- New optional `AshDyan.Analysis` callbacks with default no-op implementations:
`build_query/2`, `pre_aggregate/2`, `post_aggregate/2`.
- `AshDyan.Engine.format/2` — formats records through the analysis module
(including `pre_aggregate`/`post_aggregate` and presentation post-processing)
and runs pipeline hooks. `Result.format/2` is now deprecated.
- `AshDyan.Analysis.Registry.fetch!/1` — raises on an unknown analysis type.
- New optional `AshDyan.DataLayer` callbacks: `pushdown_aggregate/3`,
`stream/3`, and `paginate/3`.
- Runnable Phoenix + LiveView demo under `examples/ash_dyan_demo/` (in-memory
data layer, seven live charts) with screenshot in `guides/demo_ash_dyan.png`.
### Changed
- `Analysis.Registry`, `DataLayer.for_resource/1`, and aggregate validation now
consult `AshDyan.Extension.Loader.load()` so extension-registered entries are
honored alongside `config :ash_dyan, ...` (config wins on key conflicts).
- `AshDyan.Engine.run_query/3` now runs `after_query` hooks, returns
`{:ok, records}`, and rescues raised errors into `{:error, term}`.
- `AshDyan.DataLayer.Simple.supports?/2` gained a catch-all `false` clause.
## [0.1.0] - 2026-07-10
### Added
- Initial release of AshDyan.
- `dyan` DSL extension for declaring analyzable fields on Ash resources.
- Domain-level `dyan` registry via `AshDyan.Domain`.
- Runtime analysis engine (`AshDyan.run/1,2`) supporting:
- frequency / group-by counts
- numeric aggregates (sum, avg, min, max, count, count_distinct, stddev, variance, median)
- time bucketing
- percentiles
- histograms
- In-memory aggregation bounded by `max_limit`, `max_group_by`, and `query_timeout`.
- Capability check API (`AshDyan.supports?/2`) for data-layer limits.
- Structured errors via `AshDyan.Error` with stable `reason` atoms.
- Chart adapter (`AshDyan.Charts.to_chartjs/1`).
- Documentation guides (`guides/usage.md`, `guides/design.md`).
### Changed
- Removed the shipped Phoenix/Channel/gen_api adapter modules
(`AshDyan.Adapters.*`). AshDyan is now fully standalone — no `plug`
dependency at compile time. Delivery layers are documented as copy-paste
snippets (see README "Building an adapter") rather than versioned APIs.
- `:sum` now rejects `nil` values before reducing (matching every other
aggregate), so a column with a `nil` no longer raises `ArithmeticError`.
- `AshDyan.Engine.apply_filters/2` documents that filters are parsed internally
via `Ash.Filter.parse/2` (not `filter_input`) so the `dyan` whitelist stays
the security boundary.
- `AshDyan.Info.analyzable_field/3` typespec now includes `:histogram`.