# 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.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.4.1] - 2026-07-08

<!-- generated by git-cliff -->

## [0.4.0] - Unreleased

### Breaking Changes

- **Proto envelope expanded for guide-aligned output.** `QueryResultItem`
  carries typed gRPC fields plus `timestamp`, `metadata`, and `payload`.
  `timestamp` is the original Drasi event timestamp, `metadata` preserves
  inbound query-result metadata, and `payload` carries either the canonical
  JSON item or rendered body-template output as a protobuf `Struct`.
- **Templating model is body-payload based.** Templates render once per item
  into `QueryResultItem.payload`. Raw typed row state remains in `before` /
  `after`, and render failures fall back to the canonical payload.
- **Public direct constructors are fallible.** `GrpcReaction::new` and
  `GrpcReaction::with_priority_queue_capacity` validate configuration and
  return `anyhow::Result<GrpcReaction>`.
- **`config_version` is `3.0.0`** and the crate version is `0.4.0`.

### Features

- Added throughput-aware **adaptive batching** mode (`batching.mode: "adaptive"`)
  using the shared `AdaptiveBatchConfig`.
- Added optional **Handlebars output templates** via `outputTemplates`
  (`defaultTemplate` + per-query `routes`), with `added`/`updated`/`deleted`
  template specs and gRPC-specific per-template `metadata` extension fields.
- Added `outputFormat` (`canonicalJson` by default, or `proto`) to control
  whether the canonical payload is emitted when no template applies.
- Output templates are **validated at construction** — every body template,
  every per-template metadata value template, and every route key is checked.
- Template route resolution falls back to the **last dotted segment** of the
  wire query id, so a route keyed `my_query` matches a wire id `source.my_query`.
- `metadata` values accept `ConfigValue<String>` via descriptor config, so
  authentication headers can reference environment variables or secrets resolved
  at construction time.
- Endpoint and batching invariants are validated at construction, including
  positive fixed/adaptive batch sizes and adaptive min/max ordering.
- Fixed batching isolates pending batches by `(query_id, metadata)` to avoid data
  misattribution.
- Adaptive batching forwards items to the adaptive batcher immediately, so
  low-volume single-query items flush after the configured wait window.
- **Resumable delivery (at-least-once).** Both fixed and adaptive runners now
  advance a per-query checkpoint driven by successful (acked) delivery: a
  sequence is only checkpointed once the batch containing its terminal item is
  acked, so a result split across batches is never partially advanced. On
  restart the host `ReactionManager` forwarder skips results at or below the
  persisted checkpoint, so the reaction only persists checkpoints and relies on
  the framework for dedup.
- **Recovery policy** is configurable per instance via
  `GrpcReactionBuilder::with_recovery_policy` or the descriptor `recoveryPolicy`
  field (`strict` | `auto_skip_gap`). Under `strict` (default) a sustained
  delivery failure (after the retry/reconnect budget is exhausted) fail-stops the
  reaction (`Error`) so the un-acked batch replays from the query outbox on
  restart; under `auto_skip_gap` the failed batch is skipped and the reaction
  keeps running (favoring uptime).
- New typed builder API (`GrpcReaction::builder(...)`) with
  `with_fixed_batching`, `with_adaptive_batching`, `with_output_templates`,
  `with_output_format`, per-field adaptive setters (`with_min_batch_size`,
  `with_max_batch_size`, `with_window_size`, `with_batch_timeout_ms`), and
  `with_metadata` convenience methods.
- OpenAPI descriptor (`config_version = "3.0.0"`) with named sub-schemas for
  `BatchingConfig`, `OutputFormat`, `OutputTemplates`, `QueryConfig`, and
  `TemplateSpec`, plus `SchemaUiAnnotator` groupings for management UIs.

### Bug Fixes

- **Descriptor batching config now accepts camelCase keys.** The
  `BatchingConfigDto` struct-variant fields (`batchSize`, `batchFlushTimeoutMs`,
  `adaptiveMinBatchSize`, `adaptiveMaxBatchSize`, `adaptiveWindowSize`,
  `adaptiveBatchTimeoutMs`) are now (de)serialized in camelCase, matching the
  runtime `BatchingConfig`, the generated schema, and the documentation.
  Previously `rename_all = "camelCase"` on the enum did not reach the
  struct-variant fields, so camelCase batching parameters supplied through the
  descriptor/server config path were silently dropped to defaults.

### Miscellaneous Tasks

- Refreshed copyright headers to 2026.
- Expanded unit and integration coverage with config validation failures,
  canonical payload assertions, Aggregation-as-UPDATE assertions, route
  resolution, template-validation success and failure cases, standard-context
  assertions, per-template metadata rendering, and `row_signature` / `sequence`
  / timestamp / metadata propagation tests.
- Added focused unit coverage for the JSON→proto helpers, batch-key
  normalization and metadata merging, connection-client construction and
  `ConnectionState`, descriptor DTO conversions and batching resolution,
  adaptive-batcher throughput classification, builder adaptive-mode side-effect
  setters, and `latest_item_timestamp`; plus integration coverage for the
  `proto` output format, multi-item single-RPC ordering, empty-result handling,
  metadata-keyed batch splitting, and end-to-end camelCase batching.

<!-- generated by git-cliff -->

## [0.3.5] - 2026-06-16

### Miscellaneous Tasks

- Updated the following local packages: drasi-lib, drasi-plugin-sdk

<!-- generated by git-cliff -->

## [0.3.4] - 2026-06-11

### Miscellaneous Tasks

- Updated the following local packages: drasi-lib

<!-- generated by git-cliff -->

## [0.3.3] - 2026-06-03

### Miscellaneous Tasks

- Updated the following local packages: drasi-lib, drasi-plugin-sdk

<!-- generated by git-cliff -->

## [0.3.2] - 2026-05-21

### Features

- Secret store plugin system with file, keyring, and Azure Key Vault providers ([#460](https://github.com/drasi-project/drasi-core/issues/460))

### Miscellaneous Tasks

- Normalize Apache-2.0 license headers across all .rs files ([#462](https://github.com/drasi-project/drasi-core/issues/462))

<!-- generated by git-cliff -->

## [0.3.1] - 2026-05-20

### Miscellaneous Tasks

- Updated the following local packages: drasi-lib, drasi-plugin-sdk

<!-- generated by git-cliff -->

## [0.3.0] - 2026-05-12

### Bug Fixes

- Lossless config persistence — preserve ConfigValue envelopes, camelCase keys, and passwords ([#422](https://github.com/drasi-project/drasi-core/issues/422))

### Miscellaneous Tasks

- Release ([#446](https://github.com/drasi-project/drasi-core/issues/446))

<!-- generated by git-cliff -->

## [0.2.13] - 2026-05-11

### Bug Fixes

- Lossless config persistence — preserve ConfigValue envelopes, camelCase keys, and passwords ([#422](https://github.com/drasi-project/drasi-core/issues/422))

<!-- generated by git-cliff -->

## [0.2.12] - 2026-04-28

### Miscellaneous Tasks

- Updated the following local packages: drasi-plugin-sdk

<!-- generated by git-cliff -->

## [0.2.11] - 2026-04-27

### Miscellaneous Tasks

- Updated the following local packages: drasi-plugin-sdk, drasi-lib

<!-- generated by git-cliff -->

## [0.2.8] - 2026-03-16

### Miscellaneous Tasks

- Updated the following local packages: drasi-lib, drasi-plugin-sdk

<!-- generated by git-cliff -->
## [0.2.7] - 2026-03-09

### Miscellaneous Tasks

- Updated the following local packages: drasi-plugin-sdk

<!-- generated by git-cliff -->
## [0.2.6] - 2026-02-26

### Miscellaneous Tasks

- Updated the following local packages: drasi-lib

<!-- generated by git-cliff -->
## [0.2.5] - 2026-02-13

### Miscellaneous Tasks

- Updated the following local packages: drasi-lib

<!-- generated by git-cliff -->
## [0.2.4] - 2026-02-11

### Miscellaneous Tasks

- Updated the following local packages: drasi-lib

<!-- generated by git-cliff -->
## [0.2.3] - 2026-02-10

### Miscellaneous Tasks

- Updated the following local packages: drasi-lib

<!-- generated by git-cliff -->
## [0.2.2] - 2026-02-05

### Miscellaneous Tasks

- Updated the following local packages: drasi-lib

<!-- generated by git-cliff -->
<!-- generated by git-cliff -->
