# Changelog
All notable changes to `technitium-rs` are documented in this file.
## [v0.3.0] — 2026-03-19
### Breaking Changes
- **`ttl` fields changed from `u32` to `Ttl` newtype** — `Record`, `AddRecord`, and `UpdateRecord` now use `Ttl(u32)` instead of a raw `u32`. Existing code that sets TTL values must wrap them: `ttl: Ttl(3600)`.
- **`AddRecord` and `UpdateRecord` no longer implement `Default`** — these structs now require explicit construction. Use the new `RecordBuilder` API instead (see below).
- **Removed `request_multipart` method** from the internal client (was `#[expect(dead_code)]`). Only affects downstream code that was using `pub(crate)` internals.
- **TLS feature flags** — reqwest is now compiled with `default-features = false`. TLS backend is selected via cargo features: `default-tls` (enabled by default), `native-tls`, or `rustls`. If you were relying on reqwest's default feature set beyond TLS, you may need to enable features explicitly.
### New Features
- **`ZoneClient`** — a zone-scoped handle created via `Client::zone("example.com")` or `Client::zone_for_domain("sub.example.com")` that binds a zone name for all operations, removing the need to pass the zone on every call.
- **`RecordBuilder`** — fluent builder for constructing `AddRecord` values: `RecordBuilder::new("example.com", RecordType::A).ip("1.2.3.4").ttl(3600).build()`.
- **`Ttl` newtype** — wraps TTL values with `Display`, `From<u32>`, and `From<Duration>` conversions.
- **`Client::request_unit`** — internal helper for POST requests that return no meaningful data.
- **`NameListResponse` / `NameEntry`** — shared internal response types for zone listing endpoints.
### Migration Notes
```rust
// Before (v0.2)
let record = AddRecord { ttl: 3600, ..Default::default() };
// After (v0.3) — option A: direct construction
let record = AddRecord { ttl: Ttl(3600), domain: "example.com".into(), /* ... */ };
// After (v0.3) — option B: builder
let record = RecordBuilder::new("example.com", RecordType::A)
.ip("1.2.3.4")
.ttl(3600)
.build();
```
## [v0.2.0] — 2026-03-19
### Breaking Changes
- **`Error::Config` changed from tuple variant to struct variant** — `Error::Config(String)` is now `Error::Config { reason: String }`. Match patterns and construction sites must be updated.
- **`Error::Server` gains `path` and `params` fields** — error messages now include the API endpoint and (non-sensitive) request parameters for easier debugging. Code matching on `Error::Server { message, status_code }` must add `..` or the new fields.
- **IP address fields changed from `String` to `IpAddr`** — `AddRecord::ip_address`, `UpdateRecord::ip_address`, and `UpdateRecord::old_ip_address` are now `Option<IpAddr>` (from `std::net`). Callers must parse IP strings before assignment.
### New Features
- **`Client::connect` convenience constructor** — one-call connect + authenticate + auto-reauth: `Client::connect("http://localhost:5380", "admin", "admin").await?`.
- **`list_user_zones`** — lists only user-created zones, filtering out internal zones (localhost, reverse-lookup).
- **Richer error context** — `Error::Server` now carries `status_code`, `path`, and `params` for all API failures. `RequestParams` type filters sensitive fields automatically.
- **`ApiResponse` captures HTTP metadata** — `http_status`, `path`, and `params` are attached before conversion to `Error`, giving full request context in error messages.
### Migration Notes
```rust
// Before (v0.1)
Err(Error::Config(msg)) => { /* ... */ }
record.ip_address = Some("1.2.3.4".to_string());
// After (v0.2)
Err(Error::Config { reason }) => { /* ... */ }
record.ip_address = Some("1.2.3.4".parse().unwrap());
```
## [v0.1.1] — 2026-03-18
### Improvements
- **Documentation** — added `/// # Examples` doc-blocks with runnable code samples to all public API methods across every module (admin, allowed, apps, auth, blocked, cache, dashboard, DHCP, DNS client, logs, records, settings, zones).
### CI
- CI jobs are now interruptable (except the publish stage).
## [v0.1.0] — 2026-03-18
Initial release of `technitium-rs`.
### Features
- **Typed async client** for the [Technitium DNS Server](https://technitium.com/dns/) HTTP API, built on reqwest + tokio.
- **Full API coverage** — zones, records, allowed/blocked lists, DHCP scopes, DNS client queries, logs, dashboard stats, settings, apps, admin users, and authentication.
- **`Client::builder`** — configurable client with base URL, credentials, token auth, rate limiting, retry policies, and timeouts.
- **Automatic retry with jitter** — configurable retry count, base delay, and exponential backoff with randomized jitter for transient/rate-limit errors.
- **Rate limiter** — optional requests-per-second throttle to avoid overwhelming the server.
- **Auto re-authentication** — transparently refreshes expired tokens when `auto_reauth` is enabled.
- **Structured error types** — `Error` enum covers server errors, authentication failures, 2FA requirements, deserialization issues, network errors, and configuration problems.
- **GitLab CI pipeline** — lint, test, and publish stages targeting `rust:1.85.0`.
[v0.3.0]: https://git.internal.northhosted.com/joe/technitium-rs/-/compare/v0.2.0...v0.3.0
[v0.2.0]: https://git.internal.northhosted.com/joe/technitium-rs/-/compare/v0.1.1...v0.2.0
[v0.1.1]: https://git.internal.northhosted.com/joe/technitium-rs/-/compare/v0.1.0...v0.1.1
[v0.1.0]: https://git.internal.northhosted.com/joe/technitium-rs/-/tags/v0.1.0