diff --git a/CHANGELOG.md b/CHANGELOG.md index d7f5ddbc..9cfb8f59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,61 @@ All notable changes to the Firefly Framework for Rust. +## v26.6.26 — 2026-06-16 + +A correctness release. Every one of the **74 per-crate `README.md`** files was +audited against that crate's *actual* shipped public API (43 confirmed fixes +across 28 crates), and the audit surfaced a real framework bug: the per-crate +`VERSION` constant was a hardcoded literal frozen at `"26.6.24"` instead of +tracking the crate version. + +### Fixed + +- **`VERSION` no longer drifts from the crate version.** Every crate's + `pub const VERSION` was a hardcoded `"26.6.24"` string that nothing kept in + sync with the workspace version — so `firefly_kernel::VERSION`, the actuator + `/actuator/version` payload, and the startup banner all reported a stale + release number, and the `version_matches_crate_version` guard tests only + passed while the workspace happened to sit at `26.6.24`. All 52 hardcoded + constants now derive from `env!("CARGO_PKG_VERSION")` (the re-exporting + crates already chained to `firefly_kernel::VERSION`), so `VERSION` is now + always exactly the crate version and can never drift again. The `cli` + `FRAMEWORK_VERSION` constant got the same treatment, and the handful of + unit/integration tests that asserted `VERSION == "26.6.24"` against a frozen + literal now assert against `env!("CARGO_PKG_VERSION")`, so the guard holds for + every release instead of only when the workspace happened to sit at that + number. (The CLI's `render_for` / SBOM-parser fixtures keep their literal + sample versions — that string is arbitrary test data, not the build version.) + +- **Phantom / incomplete public-surface docs.** Documented APIs now match the + source: `admin`'s `AdminDeps` gained its `environment` field; `openapi`'s + `RouteDef` (4 missing fields: `request_schema` / `response_schema` / + `query_schema` / `pageable`), `Parameter::{query,header}`, `Builder::{add_schema, + add_schema_descriptors, from_inventory, docs_router}`, and the `DocsConfig` + struct are now listed; `orchestration`'s `CompensationPolicy` (now all six + variants incl. `GroupedParallel`) and `SagaError` (all four variants); + `starter-web`'s `WebStack::{set_security, set_exception_advice}`; `testkit`'s + `BuiltSlice::web_client`; `idp`'s `Error` enum + `change_password` signature; + `security`, `webhooks`, `kernel`, `transactional`, `plugins` surface fixes. +- **Wrong signatures / variant names.** The `notifications-*` READMEs used the + wire spellings `EmailStatus::SENT` / `FAILED`; the Rust variants are `Sent` / + `Failed` (`#[serde(rename = "SENT")]` only affects the JSON). `plugins` showed + a `Vec>` annotation that does not type-check against the real + `Extension = Arc`. `notifications-twilio`, + `session-redis` parameter names corrected. +- **Wrong facts.** `admin`: the bean graph **does** ship dependency `edges` + (one per autowired dependency), not "nodes-only". `backoffice`: the middleware + order includes `TraceContext` (`Problem → TraceContext → Correlation → + Idempotency → BackOffice`). `resilience`, `starter-core`, `eda-kafka`, + `session-postgres`, `session-mongodb`, `container` (a `warm`→`form` typo) fixes. +- **Stale version pins.** Crate-README dependency examples that still pinned the + long-stale `26.6.7` now use the self-maintaining minor pin `version = "26.6"` + (the convention `firefly` / `testkit` / `webhooks` already used); example + `VERSION` outputs updated to the release version. +- **`firefly-cache` doc comment.** Removed the stale "once the Redis adapter + ships in the next minor" note — `firefly-cache-redis` (`RedisAdapter`) has + shipped and is a published workspace member. + ## v26.6.25 — 2026-06-16 A correctness-and-hygiene release: the workspace is `rustfmt`-clean again and diff --git a/Cargo.lock b/Cargo.lock index 961ff350..e700c2e1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1436,7 +1436,7 @@ checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" [[package]] name = "firefly" -version = "26.6.25" +version = "26.6.26" dependencies = [ "axum", "firefly-actuator", @@ -1480,7 +1480,7 @@ dependencies = [ [[package]] name = "firefly-actuator" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "axum", @@ -1497,7 +1497,7 @@ dependencies = [ [[package]] name = "firefly-admin" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "axum", @@ -1526,7 +1526,7 @@ dependencies = [ [[package]] name = "firefly-aop" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "inventory", @@ -1536,7 +1536,7 @@ dependencies = [ [[package]] name = "firefly-backoffice" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "axum", @@ -1555,7 +1555,7 @@ dependencies = [ [[package]] name = "firefly-cache" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "firefly-observability", @@ -1567,7 +1567,7 @@ dependencies = [ [[package]] name = "firefly-cache-postgres" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "chrono", @@ -1579,7 +1579,7 @@ dependencies = [ [[package]] name = "firefly-cache-redis" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "firefly-cache", @@ -1591,7 +1591,7 @@ dependencies = [ [[package]] name = "firefly-callbacks" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "axum", @@ -1617,7 +1617,7 @@ dependencies = [ [[package]] name = "firefly-cli" -version = "26.6.25" +version = "26.6.26" dependencies = [ "axum", "chrono", @@ -1638,7 +1638,7 @@ dependencies = [ [[package]] name = "firefly-client" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-stream", "axum", @@ -1660,7 +1660,7 @@ dependencies = [ [[package]] name = "firefly-config" -version = "26.6.25" +version = "26.6.26" dependencies = [ "axum", "regex", @@ -1675,7 +1675,7 @@ dependencies = [ [[package]] name = "firefly-config-server" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "axum", @@ -1691,7 +1691,7 @@ dependencies = [ [[package]] name = "firefly-container" -version = "26.6.25" +version = "26.6.26" dependencies = [ "futures", "inventory", @@ -1702,7 +1702,7 @@ dependencies = [ [[package]] name = "firefly-cqrs" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "chrono", @@ -1725,7 +1725,7 @@ dependencies = [ [[package]] name = "firefly-data" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-stream", "async-trait", @@ -1742,7 +1742,7 @@ dependencies = [ [[package]] name = "firefly-data-mongodb" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-stream", "async-trait", @@ -1760,7 +1760,7 @@ dependencies = [ [[package]] name = "firefly-data-sqlx" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-stream", "async-trait", @@ -1782,7 +1782,7 @@ dependencies = [ [[package]] name = "firefly-ecm" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "chrono", @@ -1798,7 +1798,7 @@ dependencies = [ [[package]] name = "firefly-ecm-esignature-adobe-sign" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "axum", @@ -1815,7 +1815,7 @@ dependencies = [ [[package]] name = "firefly-ecm-esignature-docusign" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "axum", @@ -1832,7 +1832,7 @@ dependencies = [ [[package]] name = "firefly-ecm-esignature-logalty" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "axum", @@ -1849,7 +1849,7 @@ dependencies = [ [[package]] name = "firefly-ecm-storage-aws" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "axum", @@ -1869,7 +1869,7 @@ dependencies = [ [[package]] name = "firefly-ecm-storage-azure" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "axum", @@ -1889,7 +1889,7 @@ dependencies = [ [[package]] name = "firefly-eda" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "base64", @@ -1911,7 +1911,7 @@ dependencies = [ [[package]] name = "firefly-eda-kafka" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "firefly-eda", @@ -1926,7 +1926,7 @@ dependencies = [ [[package]] name = "firefly-eda-postgres" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "chrono", @@ -1944,7 +1944,7 @@ dependencies = [ [[package]] name = "firefly-eda-rabbitmq" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "firefly-eda", @@ -1959,7 +1959,7 @@ dependencies = [ [[package]] name = "firefly-eda-redis" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "firefly-eda", @@ -1975,7 +1975,7 @@ dependencies = [ [[package]] name = "firefly-eventsourcing" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "base64", @@ -1993,7 +1993,7 @@ dependencies = [ [[package]] name = "firefly-i18n" -version = "26.6.25" +version = "26.6.26" dependencies = [ "axum", "http", @@ -2008,7 +2008,7 @@ dependencies = [ [[package]] name = "firefly-idp" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "axum", @@ -2024,7 +2024,7 @@ dependencies = [ [[package]] name = "firefly-idp-aws-cognito" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "axum", @@ -2045,7 +2045,7 @@ dependencies = [ [[package]] name = "firefly-idp-azure-ad" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "axum", @@ -2062,7 +2062,7 @@ dependencies = [ [[package]] name = "firefly-idp-internal-db" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "axum", @@ -2084,7 +2084,7 @@ dependencies = [ [[package]] name = "firefly-idp-keycloak" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "axum", @@ -2101,7 +2101,7 @@ dependencies = [ [[package]] name = "firefly-integration-tests" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "axum", @@ -2136,7 +2136,7 @@ dependencies = [ [[package]] name = "firefly-kernel" -version = "26.6.25" +version = "26.6.26" dependencies = [ "chrono", "serde", @@ -2148,7 +2148,7 @@ dependencies = [ [[package]] name = "firefly-lifecycle" -version = "26.6.25" +version = "26.6.26" dependencies = [ "thiserror 1.0.69", "tokio", @@ -2157,7 +2157,7 @@ dependencies = [ [[package]] name = "firefly-macros" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "axum", @@ -2179,7 +2179,7 @@ dependencies = [ [[package]] name = "firefly-migrations" -version = "26.6.25" +version = "26.6.26" dependencies = [ "chrono", "hex", @@ -2192,7 +2192,7 @@ dependencies = [ [[package]] name = "firefly-notifications" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "chrono", @@ -2207,7 +2207,7 @@ dependencies = [ [[package]] name = "firefly-notifications-firebase" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "axum", @@ -2223,7 +2223,7 @@ dependencies = [ [[package]] name = "firefly-notifications-resend" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "axum", @@ -2240,7 +2240,7 @@ dependencies = [ [[package]] name = "firefly-notifications-sendgrid" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "axum", @@ -2257,7 +2257,7 @@ dependencies = [ [[package]] name = "firefly-notifications-smtp" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "base64", @@ -2274,7 +2274,7 @@ dependencies = [ [[package]] name = "firefly-notifications-twilio" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "axum", @@ -2290,7 +2290,7 @@ dependencies = [ [[package]] name = "firefly-observability" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "chrono", @@ -2314,7 +2314,7 @@ dependencies = [ [[package]] name = "firefly-openapi" -version = "26.6.25" +version = "26.6.26" dependencies = [ "axum", "chrono", @@ -2330,7 +2330,7 @@ dependencies = [ [[package]] name = "firefly-orchestration" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "axum", @@ -2354,7 +2354,7 @@ dependencies = [ [[package]] name = "firefly-plugins" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "chrono", @@ -2364,7 +2364,7 @@ dependencies = [ [[package]] name = "firefly-reactive" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-stream", "firefly-kernel", @@ -2376,7 +2376,7 @@ dependencies = [ [[package]] name = "firefly-resilience" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "firefly-config", @@ -2388,7 +2388,7 @@ dependencies = [ [[package]] name = "firefly-rule-engine" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "axum", @@ -2408,7 +2408,7 @@ dependencies = [ [[package]] name = "firefly-sample-lumen" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "axum", @@ -2425,7 +2425,7 @@ dependencies = [ [[package]] name = "firefly-sample-lumen-ledger-core" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "chrono", @@ -2440,7 +2440,7 @@ dependencies = [ [[package]] name = "firefly-sample-lumen-ledger-interfaces" -version = "26.6.25" +version = "26.6.26" dependencies = [ "chrono", "firefly", @@ -2451,7 +2451,7 @@ dependencies = [ [[package]] name = "firefly-sample-lumen-ledger-models" -version = "26.6.25" +version = "26.6.26" dependencies = [ "chrono", "firefly", @@ -2464,7 +2464,7 @@ dependencies = [ [[package]] name = "firefly-sample-lumen-ledger-sdk" -version = "26.6.25" +version = "26.6.26" dependencies = [ "firefly-client", "firefly-sample-lumen-ledger-interfaces", @@ -2476,7 +2476,7 @@ dependencies = [ [[package]] name = "firefly-sample-lumen-ledger-web" -version = "26.6.25" +version = "26.6.26" dependencies = [ "axum", "firefly", @@ -2494,7 +2494,7 @@ dependencies = [ [[package]] name = "firefly-sample-macro-quickstart" -version = "26.6.25" +version = "26.6.26" dependencies = [ "axum", "firefly", @@ -2507,7 +2507,7 @@ dependencies = [ [[package]] name = "firefly-sample-orders" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "axum", @@ -2530,7 +2530,7 @@ dependencies = [ [[package]] name = "firefly-sample-reactive-banking" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-stream", "async-trait", @@ -2570,7 +2570,7 @@ dependencies = [ [[package]] name = "firefly-scheduling" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "chrono", @@ -2591,7 +2591,7 @@ dependencies = [ [[package]] name = "firefly-security" -version = "26.6.25" +version = "26.6.26" dependencies = [ "argon2", "async-trait", @@ -2617,7 +2617,7 @@ dependencies = [ [[package]] name = "firefly-session" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "axum", @@ -2642,7 +2642,7 @@ dependencies = [ [[package]] name = "firefly-session-mongodb" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "firefly-session", @@ -2655,7 +2655,7 @@ dependencies = [ [[package]] name = "firefly-session-postgres" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "firefly-session", @@ -2667,7 +2667,7 @@ dependencies = [ [[package]] name = "firefly-session-redis" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "firefly-session", @@ -2679,7 +2679,7 @@ dependencies = [ [[package]] name = "firefly-shell" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "futures", @@ -2689,7 +2689,7 @@ dependencies = [ [[package]] name = "firefly-spike-linkspike-core" -version = "26.6.25" +version = "26.6.26" dependencies = [ "axum", "firefly", @@ -2697,7 +2697,7 @@ dependencies = [ [[package]] name = "firefly-spike-linkspike-web" -version = "26.6.25" +version = "26.6.26" dependencies = [ "axum", "firefly", @@ -2709,7 +2709,7 @@ dependencies = [ [[package]] name = "firefly-sse" -version = "26.6.25" +version = "26.6.26" dependencies = [ "axum", "bytes", @@ -2725,7 +2725,7 @@ dependencies = [ [[package]] name = "firefly-starter-application" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "firefly-cqrs", @@ -2739,7 +2739,7 @@ dependencies = [ [[package]] name = "firefly-starter-core" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "axum", @@ -2765,7 +2765,7 @@ dependencies = [ [[package]] name = "firefly-starter-data" -version = "26.6.25" +version = "26.6.26" dependencies = [ "axum", "firefly-cqrs", @@ -2778,7 +2778,7 @@ dependencies = [ [[package]] name = "firefly-starter-domain" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "firefly-eventsourcing", @@ -2790,7 +2790,7 @@ dependencies = [ [[package]] name = "firefly-starter-experience" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "axum", @@ -2811,7 +2811,7 @@ dependencies = [ [[package]] name = "firefly-starter-web" -version = "26.6.25" +version = "26.6.26" dependencies = [ "axum", "firefly-kernel", @@ -2826,7 +2826,7 @@ dependencies = [ [[package]] name = "firefly-testkit" -version = "26.6.25" +version = "26.6.26" dependencies = [ "axum", "base64", @@ -2845,7 +2845,7 @@ dependencies = [ [[package]] name = "firefly-transactional" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "inventory", @@ -2856,7 +2856,7 @@ dependencies = [ [[package]] name = "firefly-utils" -version = "26.6.25" +version = "26.6.26" dependencies = [ "aes-gcm", "base64", @@ -2872,7 +2872,7 @@ dependencies = [ [[package]] name = "firefly-validators" -version = "26.6.25" +version = "26.6.26" dependencies = [ "chrono", "firefly-kernel", @@ -2883,7 +2883,7 @@ dependencies = [ [[package]] name = "firefly-web" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "axum", @@ -2922,7 +2922,7 @@ dependencies = [ [[package]] name = "firefly-webhooks" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "axum", @@ -2950,7 +2950,7 @@ dependencies = [ [[package]] name = "firefly-websocket" -version = "26.6.25" +version = "26.6.26" dependencies = [ "async-trait", "axum", diff --git a/Cargo.toml b/Cargo.toml index d8fe31eb..0f49d915 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -90,7 +90,7 @@ members = [ ] [workspace.package] -version = "26.6.25" +version = "26.6.26" edition = "2021" license = "Apache-2.0" repository = "https://github.com/fireflyframework/fireflyframework-rust" @@ -99,80 +99,80 @@ rust-version = "1.88" [workspace.dependencies] # ---- internal crates ---- -firefly-reactive = { path = "crates/reactive", version = "26.6.25" } -firefly-kernel = { path = "crates/kernel", version = "26.6.25" } -firefly-utils = { path = "crates/utils", version = "26.6.25" } -firefly-validators = { path = "crates/validators", version = "26.6.25" } -firefly-web = { path = "crates/web", version = "26.6.25" } -firefly-config = { path = "crates/config", version = "26.6.25" } -firefly-i18n = { path = "crates/i18n", version = "26.6.25" } -firefly-cache = { path = "crates/cache", version = "26.6.25" } -firefly-observability = { path = "crates/observability", version = "26.6.25" } -firefly-data = { path = "crates/data", version = "26.6.25" } -firefly-cqrs = { path = "crates/cqrs", version = "26.6.25" } -firefly-eda = { path = "crates/eda", version = "26.6.25" } -firefly-eventsourcing = { path = "crates/eventsourcing", version = "26.6.25" } -firefly-orchestration = { path = "crates/orchestration", version = "26.6.25" } -firefly-rule-engine = { path = "crates/rule-engine", version = "26.6.25" } -firefly-plugins = { path = "crates/plugins", version = "26.6.25" } -firefly-lifecycle = { path = "crates/lifecycle", version = "26.6.25" } -firefly-actuator = { path = "crates/actuator", version = "26.6.25" } -firefly-scheduling = { path = "crates/scheduling", version = "26.6.25" } -firefly-resilience = { path = "crates/resilience", version = "26.6.25" } -firefly-security = { path = "crates/security", version = "26.6.25" } -firefly-migrations = { path = "crates/migrations", version = "26.6.25" } -firefly-openapi = { path = "crates/openapi", version = "26.6.25" } -firefly-sse = { path = "crates/sse", version = "26.6.25" } -firefly-transactional = { path = "crates/transactional", version = "26.6.25" } -firefly-testkit = { path = "crates/testkit", version = "26.6.25" } -firefly-client = { path = "crates/client", version = "26.6.25" } -firefly-config-server = { path = "crates/config-server", version = "26.6.25" } -firefly-idp = { path = "crates/idp", version = "26.6.25" } -firefly-idp-internal-db = { path = "crates/idp-internal-db", version = "26.6.25" } -firefly-idp-keycloak = { path = "crates/idp-keycloak", version = "26.6.25" } -firefly-idp-azure-ad = { path = "crates/idp-azure-ad", version = "26.6.25" } -firefly-idp-aws-cognito = { path = "crates/idp-aws-cognito", version = "26.6.25" } -firefly-ecm = { path = "crates/ecm", version = "26.6.25" } -firefly-ecm-storage-aws = { path = "crates/ecm-storage-aws", version = "26.6.25" } -firefly-ecm-storage-azure = { path = "crates/ecm-storage-azure", version = "26.6.25" } -firefly-ecm-esignature-docusign = { path = "crates/ecm-esignature-docusign", version = "26.6.25" } -firefly-ecm-esignature-adobe-sign = { path = "crates/ecm-esignature-adobe-sign", version = "26.6.25" } -firefly-ecm-esignature-logalty = { path = "crates/ecm-esignature-logalty", version = "26.6.25" } -firefly-notifications = { path = "crates/notifications", version = "26.6.25" } -firefly-notifications-sendgrid = { path = "crates/notifications-sendgrid", version = "26.6.25" } -firefly-notifications-resend = { path = "crates/notifications-resend", version = "26.6.25" } -firefly-notifications-twilio = { path = "crates/notifications-twilio", version = "26.6.25" } -firefly-notifications-firebase = { path = "crates/notifications-firebase", version = "26.6.25" } -firefly-callbacks = { path = "crates/callbacks", version = "26.6.25" } -firefly-webhooks = { path = "crates/webhooks", version = "26.6.25" } -firefly-starter-core = { path = "crates/starter-core", version = "26.6.25" } -firefly-starter-application = { path = "crates/starter-application", version = "26.6.25" } -firefly-starter-domain = { path = "crates/starter-domain", version = "26.6.25" } -firefly-starter-data = { path = "crates/starter-data", version = "26.6.25" } -firefly-backoffice = { path = "crates/backoffice", version = "26.6.25" } -firefly-admin = { path = "crates/admin", version = "26.6.25" } -firefly-aop = { path = "crates/aop", version = "26.6.25" } -firefly-cli = { path = "crates/cli", version = "26.6.25" } -firefly-container = { path = "crates/container", version = "26.6.25" } -firefly-session = { path = "crates/session", version = "26.6.25" } -firefly-shell = { path = "crates/shell", version = "26.6.25" } -firefly-websocket = { path = "crates/websocket", version = "26.6.25" } -firefly-notifications-smtp = { path = "crates/notifications-smtp", version = "26.6.25" } -firefly-cache-redis = { path = "crates/cache-redis", version = "26.6.25" } -firefly-eda-kafka = { path = "crates/eda-kafka", version = "26.6.25" } -firefly-eda-rabbitmq = { path = "crates/eda-rabbitmq", version = "26.6.25" } -firefly-eda-postgres = { path = "crates/eda-postgres", version = "26.6.25" } -firefly-eda-redis = { path = "crates/eda-redis", version = "26.6.25" } -firefly-cache-postgres = { path = "crates/cache-postgres", version = "26.6.25" } -firefly-starter-web = { path = "crates/starter-web", version = "26.6.25" } -firefly = { path = "crates/firefly", version = "26.6.25" } -firefly-macros = { path = "crates/macros", version = "26.6.25" } -firefly-data-sqlx = { path = "crates/data-sqlx", version = "26.6.25" } -firefly-data-mongodb = { path = "crates/data-mongodb", version = "26.6.25" } -firefly-session-redis = { path = "crates/session-redis", version = "26.6.25" } -firefly-session-postgres = { path = "crates/session-postgres", version = "26.6.25" } -firefly-session-mongodb = { path = "crates/session-mongodb", version = "26.6.25" } -firefly-starter-experience = { path = "crates/starter-experience", version = "26.6.25" } +firefly-reactive = { path = "crates/reactive", version = "26.6.26" } +firefly-kernel = { path = "crates/kernel", version = "26.6.26" } +firefly-utils = { path = "crates/utils", version = "26.6.26" } +firefly-validators = { path = "crates/validators", version = "26.6.26" } +firefly-web = { path = "crates/web", version = "26.6.26" } +firefly-config = { path = "crates/config", version = "26.6.26" } +firefly-i18n = { path = "crates/i18n", version = "26.6.26" } +firefly-cache = { path = "crates/cache", version = "26.6.26" } +firefly-observability = { path = "crates/observability", version = "26.6.26" } +firefly-data = { path = "crates/data", version = "26.6.26" } +firefly-cqrs = { path = "crates/cqrs", version = "26.6.26" } +firefly-eda = { path = "crates/eda", version = "26.6.26" } +firefly-eventsourcing = { path = "crates/eventsourcing", version = "26.6.26" } +firefly-orchestration = { path = "crates/orchestration", version = "26.6.26" } +firefly-rule-engine = { path = "crates/rule-engine", version = "26.6.26" } +firefly-plugins = { path = "crates/plugins", version = "26.6.26" } +firefly-lifecycle = { path = "crates/lifecycle", version = "26.6.26" } +firefly-actuator = { path = "crates/actuator", version = "26.6.26" } +firefly-scheduling = { path = "crates/scheduling", version = "26.6.26" } +firefly-resilience = { path = "crates/resilience", version = "26.6.26" } +firefly-security = { path = "crates/security", version = "26.6.26" } +firefly-migrations = { path = "crates/migrations", version = "26.6.26" } +firefly-openapi = { path = "crates/openapi", version = "26.6.26" } +firefly-sse = { path = "crates/sse", version = "26.6.26" } +firefly-transactional = { path = "crates/transactional", version = "26.6.26" } +firefly-testkit = { path = "crates/testkit", version = "26.6.26" } +firefly-client = { path = "crates/client", version = "26.6.26" } +firefly-config-server = { path = "crates/config-server", version = "26.6.26" } +firefly-idp = { path = "crates/idp", version = "26.6.26" } +firefly-idp-internal-db = { path = "crates/idp-internal-db", version = "26.6.26" } +firefly-idp-keycloak = { path = "crates/idp-keycloak", version = "26.6.26" } +firefly-idp-azure-ad = { path = "crates/idp-azure-ad", version = "26.6.26" } +firefly-idp-aws-cognito = { path = "crates/idp-aws-cognito", version = "26.6.26" } +firefly-ecm = { path = "crates/ecm", version = "26.6.26" } +firefly-ecm-storage-aws = { path = "crates/ecm-storage-aws", version = "26.6.26" } +firefly-ecm-storage-azure = { path = "crates/ecm-storage-azure", version = "26.6.26" } +firefly-ecm-esignature-docusign = { path = "crates/ecm-esignature-docusign", version = "26.6.26" } +firefly-ecm-esignature-adobe-sign = { path = "crates/ecm-esignature-adobe-sign", version = "26.6.26" } +firefly-ecm-esignature-logalty = { path = "crates/ecm-esignature-logalty", version = "26.6.26" } +firefly-notifications = { path = "crates/notifications", version = "26.6.26" } +firefly-notifications-sendgrid = { path = "crates/notifications-sendgrid", version = "26.6.26" } +firefly-notifications-resend = { path = "crates/notifications-resend", version = "26.6.26" } +firefly-notifications-twilio = { path = "crates/notifications-twilio", version = "26.6.26" } +firefly-notifications-firebase = { path = "crates/notifications-firebase", version = "26.6.26" } +firefly-callbacks = { path = "crates/callbacks", version = "26.6.26" } +firefly-webhooks = { path = "crates/webhooks", version = "26.6.26" } +firefly-starter-core = { path = "crates/starter-core", version = "26.6.26" } +firefly-starter-application = { path = "crates/starter-application", version = "26.6.26" } +firefly-starter-domain = { path = "crates/starter-domain", version = "26.6.26" } +firefly-starter-data = { path = "crates/starter-data", version = "26.6.26" } +firefly-backoffice = { path = "crates/backoffice", version = "26.6.26" } +firefly-admin = { path = "crates/admin", version = "26.6.26" } +firefly-aop = { path = "crates/aop", version = "26.6.26" } +firefly-cli = { path = "crates/cli", version = "26.6.26" } +firefly-container = { path = "crates/container", version = "26.6.26" } +firefly-session = { path = "crates/session", version = "26.6.26" } +firefly-shell = { path = "crates/shell", version = "26.6.26" } +firefly-websocket = { path = "crates/websocket", version = "26.6.26" } +firefly-notifications-smtp = { path = "crates/notifications-smtp", version = "26.6.26" } +firefly-cache-redis = { path = "crates/cache-redis", version = "26.6.26" } +firefly-eda-kafka = { path = "crates/eda-kafka", version = "26.6.26" } +firefly-eda-rabbitmq = { path = "crates/eda-rabbitmq", version = "26.6.26" } +firefly-eda-postgres = { path = "crates/eda-postgres", version = "26.6.26" } +firefly-eda-redis = { path = "crates/eda-redis", version = "26.6.26" } +firefly-cache-postgres = { path = "crates/cache-postgres", version = "26.6.26" } +firefly-starter-web = { path = "crates/starter-web", version = "26.6.26" } +firefly = { path = "crates/firefly", version = "26.6.26" } +firefly-macros = { path = "crates/macros", version = "26.6.26" } +firefly-data-sqlx = { path = "crates/data-sqlx", version = "26.6.26" } +firefly-data-mongodb = { path = "crates/data-mongodb", version = "26.6.26" } +firefly-session-redis = { path = "crates/session-redis", version = "26.6.26" } +firefly-session-postgres = { path = "crates/session-postgres", version = "26.6.26" } +firefly-session-mongodb = { path = "crates/session-mongodb", version = "26.6.26" } +firefly-starter-experience = { path = "crates/starter-experience", version = "26.6.26" } # ---- async runtime + web ---- tokio = { version = "1", features = ["rt-multi-thread", "macros", "sync", "time", "signal", "io-util", "net", "fs"] } diff --git a/crates/actuator/README.md b/crates/actuator/README.md index 7745d269..b921a42b 100644 --- a/crates/actuator/README.md +++ b/crates/actuator/README.md @@ -15,7 +15,7 @@ as an axum `Router`: | `GET /actuator/env` | `{activeProfiles, propertySources}` when an `EnvSource` is wired; else a flat redacted env view | | `GET /actuator/tasks` | `{"count": N}` alive tokio tasks; `?dump=true` returns a runtime report | | `GET /actuator/threaddump`| `{threads:[…]}` — the tokio runtime worker/task snapshot | -| `GET /actuator/version` | `{"firefly":"26.6.7","app":"orders","appVersion":"…","rust":"…"}` | +| `GET /actuator/version` | `{"firefly":"26.6.26","app":"orders","appVersion":"…","rust":"…"}` | Bind these on a separate admin port (e.g. `:8081`) so they never leak onto the public network. diff --git a/crates/actuator/src/lib.rs b/crates/actuator/src/lib.rs index 088044b7..288ba29b 100644 --- a/crates/actuator/src/lib.rs +++ b/crates/actuator/src/lib.rs @@ -31,7 +31,7 @@ //! | `GET /actuator/env/{toMatch}` | One property's value across the ordered sources (when an [`EnvSource`] is wired)| //! | `GET /actuator/tasks` | `{"count": N}` alive tokio tasks; `?dump=true` returns a runtime report | //! | `GET /actuator/threaddump` | Spring `{threads:[…]}` — the tokio runtime worker/task snapshot (Rust analog) | -//! | `GET /actuator/version` | `{"firefly":"26.6.24","app":"orders","appVersion":"…","rust":"…"}` | +//! | `GET /actuator/version` | `{"firefly":"26.6.26","app":"orders","appVersion":"…","rust":"…"}` | //! | `GET/POST /actuator/loggers[/{n}]` | Runtime log levels over a `tracing_subscriber` reload handle | //! | `GET /actuator/scheduledtasks` | Tasks grouped by trigger (cron / fixedDelay / fixedRate) | //! | `GET/POST /actuator/caches[…]` | Configured caches + `POST /{name}/evict` | @@ -127,7 +127,7 @@ pub use threaddump::{thread_dump, StackFrame, ThreadInfo}; /// Released framework version. Calendar-versioned (`YY.M.PATCH`), the /// Rust port's counterpart of the Go `kernel.Version` constant. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); #[cfg(test)] mod tests { diff --git a/crates/admin/README.md b/crates/admin/README.md index d8348796..3ce12807 100644 --- a/crates/admin/README.md +++ b/crates/admin/README.md @@ -59,9 +59,10 @@ The crate adapts the dashboard idiom to idiomatic Rust: `AdminDeps::container` — when wired it reports each registered bean's name/type/scope/stereotype/primary plus its `initialized` flag and resolution count, sourced from `Container::beans()` / `bean_stats()`. - Reflection-only fields (constructor `dependencies`/dependency-graph `edges`, - `conditions`, `creation_time_ms`, lifecycle methods) have no zero-cost Rust - analogue and carry empty/`null` defaults, so the bean graph is nodes-only. + Reflection-only fields (constructor `dependencies`, `conditions`, + `creation_time_ms`, lifecycle methods) have no zero-cost Rust + analogue and carry empty/`null` defaults. Dependency-graph `edges` **are** + included — one directed edge per autowired dependency between beans. The `runtime` view reports tokio task/worker counts + process RSS via `sysinfo`. @@ -97,6 +98,7 @@ pub struct AdminDeps { pub instances: Option>,// Some ⇒ server mode pub container: Option>, // firefly-container, drives the Beans view pub views: Vec>, + pub environment: Option,// firefly-config env/config view } impl AdminDeps { pub fn new(app_name, app_version, health, metrics, traces, logs) -> Self; } diff --git a/crates/admin/src/lib.rs b/crates/admin/src/lib.rs index 9c2b9072..00eee281 100644 --- a/crates/admin/src/lib.rs +++ b/crates/admin/src/lib.rs @@ -127,7 +127,7 @@ pub use view::{AdminView, AdminViewRegistry}; /// Released framework version. Calendar-versioned (`YY.M.PATCH`), the Rust /// port's counterpart of the Go `kernel.Version` constant. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); #[cfg(test)] mod tests { diff --git a/crates/aop/src/lib.rs b/crates/aop/src/lib.rs index 1bad94a0..0e7f41d8 100644 --- a/crates/aop/src/lib.rs +++ b/crates/aop/src/lib.rs @@ -129,4 +129,4 @@ pub use async_trait::async_trait; pub use inventory; /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/crates/backoffice/README.md b/crates/backoffice/README.md index 16dac24d..de720580 100644 --- a/crates/backoffice/README.md +++ b/crates/backoffice/README.md @@ -46,7 +46,7 @@ impl BackOffice { `apply_middleware_chain()` returns the core chain composed with the back-office middleware as the innermost layer — apply it once and every handler gets problem rendering, correlation, idempotency, AND -the back-office guard. The execution order is `Problem → Correlation → +the back-office guard. The execution order is `Problem → TraceContext → Correlation → Idempotency → BackOffice → router`. `BackOffice` dereferences to `Application` (which dereferences to diff --git a/crates/cache-postgres/src/lib.rs b/crates/cache-postgres/src/lib.rs index f871c877..c38fef19 100644 --- a/crates/cache-postgres/src/lib.rs +++ b/crates/cache-postgres/src/lib.rs @@ -98,7 +98,7 @@ use firefly_cache::{Adapter, CacheError, CacheStats}; use tokio_postgres::{Client, NoTls}; /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); /// The cache table name, matching pyfly's `pyfly_cache_entries` under the /// Rust framework's `firefly_` prefix. diff --git a/crates/cache-redis/src/lib.rs b/crates/cache-redis/src/lib.rs index 4e9862bb..b3c58c04 100644 --- a/crates/cache-redis/src/lib.rs +++ b/crates/cache-redis/src/lib.rs @@ -72,7 +72,7 @@ use redis::aio::MultiplexedConnection; use redis::{AsyncCommands, Client, ExistenceCheck, SetExpiry, SetOptions}; /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); /// Fixed `COUNT` hint for cursor-driven `SCAN` loops. This is a per-round /// batch-size suggestion to Redis, independent of any caller-supplied total diff --git a/crates/cache/src/lib.rs b/crates/cache/src/lib.rs index 1624a9a3..e8592573 100644 --- a/crates/cache/src/lib.rs +++ b/crates/cache/src/lib.rs @@ -19,8 +19,8 @@ //! plus a typed wrapper ([`Typed`]) with `get_or_set` memoisation. Every //! consumer (CQRS query cache, idempotency middleware, custom service code) //! talks to the same [`Adapter`] regardless of whether it is running an -//! in-process map during local dev or — once the Redis adapter ships in the -//! next minor — a Redis cluster in production. +//! in-process map during local dev or a Redis cluster in production (via the +//! `firefly-cache-redis` `RedisAdapter`). //! //! [`Typed`] also offers the declarative-cache conveniences pyfly exposes //! as decorators: [`get_or_set`](Typed::get_or_set) (`@cacheable`), @@ -79,4 +79,4 @@ pub use noop::NoOpAdapter; pub use typed::Typed; /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/crates/callbacks/src/lib.rs b/crates/callbacks/src/lib.rs index cc2671c5..0be33798 100644 --- a/crates/callbacks/src/lib.rs +++ b/crates/callbacks/src/lib.rs @@ -116,4 +116,4 @@ pub use crate::sdk::CallbacksClient; pub use crate::web::handler; /// The released framework version stamp shared by every Firefly crate. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/crates/cli/src/diagnostics.rs b/crates/cli/src/diagnostics.rs index 6047fb08..9c17ad0a 100644 --- a/crates/cli/src/diagnostics.rs +++ b/crates/cli/src/diagnostics.rs @@ -61,7 +61,7 @@ pub struct DoctorReport { } /// The framework version this CLI was built from. -pub const FRAMEWORK_VERSION: &str = "26.6.24"; +pub const FRAMEWORK_VERSION: &str = env!("CARGO_PKG_VERSION"); /// Run a ` --version` and return its first trimmed output line, or `None` /// when the tool is missing or errors. diff --git a/crates/cli/src/lib.rs b/crates/cli/src/lib.rs index 063a5c45..6df84eff 100644 --- a/crates/cli/src/lib.rs +++ b/crates/cli/src/lib.rs @@ -73,4 +73,4 @@ pub use error::CliError; /// Framework version stamp (kept for backward compatibility with the prior /// placeholder crate; equals the workspace version). -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/crates/config-server/src/lib.rs b/crates/config-server/src/lib.rs index c387fb59..f062c0ac 100644 --- a/crates/config-server/src/lib.rs +++ b/crates/config-server/src/lib.rs @@ -103,7 +103,7 @@ pub use backend::{ pub use server::ConfigServer; /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); /// Errors surfaced by a [`Store`] lookup. /// diff --git a/crates/container/README.md b/crates/container/README.md index 7006a9c6..e4b7e755 100644 --- a/crates/container/README.md +++ b/crates/container/README.md @@ -78,7 +78,7 @@ is a valid registry key. | `beans()` / `bean_stats()` / `bean_count()` | Bean introspection for the admin `/beans` view | | `destroy()` | Run `#[pre_destroy]` hooks in reverse order, evict singletons | | `BeanDescriptor` / `BeanStats` / `RouteDescriptor` | Introspection + route-metadata records | -| `resolve_named_erased(name)` | Type-erased warm of a named singleton (eager init) | +| `resolve_named_erased(name)` | Type-erased form of a named singleton (eager init) | ## Design notes diff --git a/crates/container/src/lib.rs b/crates/container/src/lib.rs index a129e7c7..6297987b 100644 --- a/crates/container/src/lib.rs +++ b/crates/container/src/lib.rs @@ -111,7 +111,7 @@ pub use value::resolve_value; pub use inventory; /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); /// Type-erased boxed `Arc` — a sized fat pointer wrapped in `Box` /// so resolution can return `Arc` for both sized and `?Sized` (trait-object) diff --git a/crates/cqrs/src/lib.rs b/crates/cqrs/src/lib.rs index b4c98615..8b9d646f 100644 --- a/crates/cqrs/src/lib.rs +++ b/crates/cqrs/src/lib.rs @@ -218,4 +218,4 @@ pub use validation::{ /// The released framework version. Calendar-versioned (`YY.M.PATCH`) /// expressed as valid semver — the Go port's `26.05.01` corresponds to /// `26.6.24` in the June 2026 release window. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/crates/data-mongodb/README.md b/crates/data-mongodb/README.md index 75570f9f..1feeb828 100644 --- a/crates/data-mongodb/README.md +++ b/crates/data-mongodb/README.md @@ -176,7 +176,7 @@ FIREFLY_TEST_MONGODB_URL=mongodb://localhost:27017 \ Enable the `actuator` feature for a database health component: ```toml -firefly-data-mongodb = { version = "26.6.7", features = ["actuator"] } +firefly-data-mongodb = { version = "26.6", features = ["actuator"] } ``` `MongoHealthIndicator` implements `firefly_actuator::HealthIndicator`: it diff --git a/crates/data-mongodb/src/lib.rs b/crates/data-mongodb/src/lib.rs index daef7e62..99f9196e 100644 --- a/crates/data-mongodb/src/lib.rs +++ b/crates/data-mongodb/src/lib.rs @@ -128,4 +128,4 @@ pub use repository::{Audited, MongoRepository}; pub use observe::MongoHealthIndicator; /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/crates/data-sqlx/README.md b/crates/data-sqlx/README.md index 94635ae9..8e8569dc 100644 --- a/crates/data-sqlx/README.md +++ b/crates/data-sqlx/README.md @@ -165,7 +165,7 @@ Enable the `actuator` feature to get a database health component and per-query metrics: ```toml -firefly-data-sqlx = { version = "26.6.7", features = ["actuator"] } +firefly-data-sqlx = { version = "26.6", features = ["actuator"] } ``` - `SqlxHealthIndicator` implements `firefly_actuator::HealthIndicator`: it @@ -184,7 +184,7 @@ All three backends are enabled by default. Disable the ones you do not need for a smaller build, e.g. a SQLite-only repository: ```toml -firefly-data-sqlx = { version = "26.6.7", default-features = false, features = ["sqlite"] } +firefly-data-sqlx = { version = "26.6", default-features = false, features = ["sqlite"] } ``` The `actuator` feature (off by default) adds the health/metrics integration diff --git a/crates/data-sqlx/src/lib.rs b/crates/data-sqlx/src/lib.rs index 05891767..4220f37d 100644 --- a/crates/data-sqlx/src/lib.rs +++ b/crates/data-sqlx/src/lib.rs @@ -159,4 +159,4 @@ pub use observe::{ }; /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/crates/data/src/lib.rs b/crates/data/src/lib.rs index f973a616..c5cedb5e 100644 --- a/crates/data/src/lib.rs +++ b/crates/data/src/lib.rs @@ -158,4 +158,4 @@ pub use soft_delete::{SoftDelete, SoftDeletePolicy, DEFAULT_DELETED_AT_COLUMN}; pub use specification::Specification; /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/crates/ecm-esignature-adobe-sign/src/lib.rs b/crates/ecm-esignature-adobe-sign/src/lib.rs index 1384cbe3..15c3bf05 100644 --- a/crates/ecm-esignature-adobe-sign/src/lib.rs +++ b/crates/ecm-esignature-adobe-sign/src/lib.rs @@ -71,7 +71,7 @@ use firefly_ecm::{ use serde_json::json; /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); /// Maps an Adobe Sign agreement / participant `status` string onto the /// framework's [`SignatureStatus`], porting pyfly's `_map_status` table. diff --git a/crates/ecm-esignature-docusign/src/lib.rs b/crates/ecm-esignature-docusign/src/lib.rs index 856fc548..09576a8e 100644 --- a/crates/ecm-esignature-docusign/src/lib.rs +++ b/crates/ecm-esignature-docusign/src/lib.rs @@ -71,7 +71,7 @@ use firefly_ecm::{ use serde_json::json; /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); /// Maps a DocuSign envelope `status` string onto the framework's /// [`SignatureStatus`], porting pyfly's `_map_status` table. DocuSign's diff --git a/crates/ecm-esignature-logalty/src/lib.rs b/crates/ecm-esignature-logalty/src/lib.rs index f3602087..7ea7abf9 100644 --- a/crates/ecm-esignature-logalty/src/lib.rs +++ b/crates/ecm-esignature-logalty/src/lib.rs @@ -70,7 +70,7 @@ use firefly_ecm::{ use serde_json::json; /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); /// Maps a Logalty `status` string onto the framework's [`SignatureStatus`], /// porting pyfly's `_map_status` table. `DRAFT`/`SENT`/`PENDING` are still in diff --git a/crates/ecm-storage-aws/src/lib.rs b/crates/ecm-storage-aws/src/lib.rs index f4c843a6..3bc010d9 100644 --- a/crates/ecm-storage-aws/src/lib.rs +++ b/crates/ecm-storage-aws/src/lib.rs @@ -666,7 +666,7 @@ impl ContentStore for S3Store { } /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); #[cfg(test)] mod tests { diff --git a/crates/ecm-storage-azure/src/lib.rs b/crates/ecm-storage-azure/src/lib.rs index 794b90ae..ac67b6d7 100644 --- a/crates/ecm-storage-azure/src/lib.rs +++ b/crates/ecm-storage-azure/src/lib.rs @@ -683,7 +683,7 @@ impl ContentStore for BlobStore { } /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); #[cfg(test)] mod tests { diff --git a/crates/ecm/src/lib.rs b/crates/ecm/src/lib.rs index 56592e7a..8e668755 100644 --- a/crates/ecm/src/lib.rs +++ b/crates/ecm/src/lib.rs @@ -91,4 +91,4 @@ pub use ports::{ pub use service::Service; /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/crates/eda-kafka/README.md b/crates/eda-kafka/README.md index d9ca398d..29c5fd64 100644 --- a/crates/eda-kafka/README.md +++ b/crates/eda-kafka/README.md @@ -42,7 +42,7 @@ Publisher::close(&*broker).await?; | Kafka record field | Source | |--------------------|--------| -| value | canonical `Event` JSON (`id`/`type`/`source`/`topic`/`correlationId`/`time`/`headers`/`payload`) | +| value | canonical `Event` JSON (`id`/`type`/`source`/`topic`/`correlationId`/`time`/`headers`/`payload`/`key`) | | key | `Event.correlation_id`, falling back to `Event.id` | | topic | `Event.topic` | | headers | every `Event` header copied as a UTF-8 Kafka header | diff --git a/crates/eda-kafka/src/lib.rs b/crates/eda-kafka/src/lib.rs index b3bbce10..41b8ab25 100644 --- a/crates/eda-kafka/src/lib.rs +++ b/crates/eda-kafka/src/lib.rs @@ -111,4 +111,4 @@ pub use broker::{new_kafka_broker, KafkaBroker}; pub use config::KafkaConfig; /// The released framework version, shared across all Firefly crates. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/crates/eda-postgres/src/lib.rs b/crates/eda-postgres/src/lib.rs index 2388a3b3..a6a164ba 100644 --- a/crates/eda-postgres/src/lib.rs +++ b/crates/eda-postgres/src/lib.rs @@ -91,4 +91,4 @@ pub use broker::{PostgresBroker, PostgresConfig}; pub use sql::{group_lock_key, normalise_dsn, quote_ident, IdentError}; /// The released framework version, shared across all Firefly crates. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/crates/eda-rabbitmq/src/lib.rs b/crates/eda-rabbitmq/src/lib.rs index 3df04b5b..f56b1cbb 100644 --- a/crates/eda-rabbitmq/src/lib.rs +++ b/crates/eda-rabbitmq/src/lib.rs @@ -95,4 +95,4 @@ pub use config::{DeclarationPlan, ExchangeDeclaration, QueueDeclaration, RabbitM pub use dispatch::{dispatch, pattern_matches, Ack, Subscription}; /// Framework version stamp, shared across all Firefly crates. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/crates/eda-redis/src/lib.rs b/crates/eda-redis/src/lib.rs index 9eda8790..66113bc7 100644 --- a/crates/eda-redis/src/lib.rs +++ b/crates/eda-redis/src/lib.rs @@ -83,4 +83,4 @@ pub use broker::{new_redis_broker, RedisStreamsBroker}; pub use config::RedisConfig; /// The released framework version, shared across all Firefly crates. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/crates/eda/src/lib.rs b/crates/eda/src/lib.rs index 63c9402a..2553d441 100644 --- a/crates/eda/src/lib.rs +++ b/crates/eda/src/lib.rs @@ -173,4 +173,4 @@ pub use serializer::{ }; /// The released framework version, shared across all Firefly crates. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/crates/eventsourcing/src/lib.rs b/crates/eventsourcing/src/lib.rs index b4bb1af8..03821793 100644 --- a/crates/eventsourcing/src/lib.rs +++ b/crates/eventsourcing/src/lib.rs @@ -92,4 +92,4 @@ pub use sql_store::{parse_occurred_at, SqlEventStore, DDL}; pub use upcaster::{EventUpcaster, NoOpUpcaster}; /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/crates/i18n/src/lib.rs b/crates/i18n/src/lib.rs index 72fd623a..35589c6b 100644 --- a/crates/i18n/src/lib.rs +++ b/crates/i18n/src/lib.rs @@ -88,7 +88,7 @@ use thiserror::Error; use tower::{Layer, Service}; /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); /// Errors produced when bulk-loading messages from serialized maps. #[derive(Debug, Error)] diff --git a/crates/idp/README.md b/crates/idp/README.md index 11830520..608f2bb0 100644 --- a/crates/idp/README.md +++ b/crates/idp/README.md @@ -58,7 +58,14 @@ pub trait Adapter: Send + Sync { fn name(&self) -> &str; } -pub enum Error { InvalidCredentials, UserNotFound, Provider(String) } +pub enum Error { + InvalidCredentials, + UserNotFound, + MfaRequired(MfaChallenge), + NotSupported(String), + UnsupportedByProvider { provider: String, operation: String, reason: String }, + Provider(String), +} ``` `User` and `Token` serialize with stable JSON field names and @@ -128,7 +135,7 @@ pub trait Adapter: Send + Sync { async fn introspect(&self, access_token: &str) -> Result; async fn find_by_username(&self, username: &str) -> Result; async fn list_users(&self, limit: usize) -> Result>; - async fn change_password(&self, user_id: &str, old: &str, new: &str) -> Result; + async fn change_password(&self, user_id: &str, old_password: &str, new_password: &str) -> Result; async fn reset_password(&self, user_id: &str) -> Result; async fn register_user(&self, user: User, password: &str) -> Result; async fn get_user_info(&self, access_token: &str) -> Result; @@ -200,7 +207,7 @@ fn mount(idp: Arc) -> axum::Router { | `GET /idp/admin/roles` | `list_roles` | Error mapping: `InvalidCredentials`/`MfaRequired` → `401`, `UserNotFound` -→ `404`, `NotSupported` → `501`, `Provider` → `500`; each error body is +→ `404`, `NotSupported`/`UnsupportedByProvider` → `501`, `Provider` → `500`; each error body is `{"error": ""}`. The controller is tested end-to-end (no sockets, `tower::ServiceExt::oneshot`) against the internal-db adapter in `firefly-idp-internal-db`'s `web_controller_test`. diff --git a/crates/kernel/README.md b/crates/kernel/README.md index 8fc07d21..d8cbc4cc 100644 --- a/crates/kernel/README.md +++ b/crates/kernel/README.md @@ -81,7 +81,7 @@ pub struct FireflyError { pub status: u16, pub detail: String, pub fields: BTreeMap, - pub cause: Option>, + pub cause: Option>, } ``` @@ -110,9 +110,10 @@ are exported for cross-crate agreement. ### Version -`firefly_kernel::VERSION` is the released framework version -(`"26.6.7"` at the time of writing — CalVer expressed as valid semver) -— embedded in the actuator `/version` payload and the startup banner. +`firefly_kernel::VERSION` is the released framework version — CalVer +expressed as valid semver (`"26.6.26"` at the time of writing). It is +`env!("CARGO_PKG_VERSION")`, so it always tracks the crate version and can +never drift — embedded in the actuator `/version` payload and the startup banner. ## Domain building blocks and structured context diff --git a/crates/kernel/src/lib.rs b/crates/kernel/src/lib.rs index fa094e89..8d55638c 100644 --- a/crates/kernel/src/lib.rs +++ b/crates/kernel/src/lib.rs @@ -98,4 +98,4 @@ pub use problem::{ /// expressed as valid semver — the Go port's `26.05.01` corresponds to /// `26.6.24` in the June 2026 release window. Embedded in the actuator /// `/version` payload and the startup banner. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/crates/kernel/tests/kernel_test.rs b/crates/kernel/tests/kernel_test.rs index 8cb50b4e..fd23d198 100644 --- a/crates/kernel/tests/kernel_test.rs +++ b/crates/kernel/tests/kernel_test.rs @@ -513,7 +513,7 @@ fn header_names_match_go() { #[test] fn version_is_stamped() { - assert_eq!(VERSION, "26.6.24"); + assert_eq!(VERSION, env!("CARGO_PKG_VERSION")); } #[test] diff --git a/crates/migrations/src/lib.rs b/crates/migrations/src/lib.rs index d6bd0548..39851eb6 100644 --- a/crates/migrations/src/lib.rs +++ b/crates/migrations/src/lib.rs @@ -118,4 +118,4 @@ pub use runner::{inspect, run, Status}; pub use source::{DirSource, EmbeddedSource, SliceSource, Source}; /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/crates/notifications-firebase/README.md b/crates/notifications-firebase/README.md index 58803048..6937a7d7 100644 --- a/crates/notifications-firebase/README.md +++ b/crates/notifications-firebase/README.md @@ -82,7 +82,7 @@ below. | `NotificationResult` | The send outcome (`id`, `provider`, `status`, `provider_id`, `error`). | | `DeliveryStatus` | Delivery-state enum (`QUEUED`/`SENT`/`DELIVERED`/`BOUNCED`/`FAILED`/`SUPPRESSED`). | | `FirebaseError` | `Transport(..)` and `Token(..)`. | -| `VERSION` | Framework version stamp (`"26.6.7"`). | +| `VERSION` | Framework version stamp (`env!("CARGO_PKG_VERSION")`, e.g. `"26.6.26"`). | ## Access-token source (no JWT/OAuth here) diff --git a/crates/notifications-firebase/src/lib.rs b/crates/notifications-firebase/src/lib.rs index 799ff505..900181db 100644 --- a/crates/notifications-firebase/src/lib.rs +++ b/crates/notifications-firebase/src/lib.rs @@ -93,7 +93,7 @@ pub use provider::{ }; /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); /// Config carries the wiring needed by the adapter. /// diff --git a/crates/notifications-resend/README.md b/crates/notifications-resend/README.md index 5ae2e09e..4568aeb3 100644 --- a/crates/notifications-resend/README.md +++ b/crates/notifications-resend/README.md @@ -80,9 +80,9 @@ adapters and are ignored here. * `cc`/`bcc` are added only when non-empty; `text`/`html` only when present. * Attachments carry `{ filename, content }` (base64) — Resend takes no `type` field, unlike SendGrid. -* A 2xx response → `EmailStatus::SENT` with the response JSON's `id` as +* A 2xx response → `EmailStatus::Sent` with the response JSON's `id` as `provider_id`. Any other status (or a transport error) → - `EmailStatus::FAILED` carrying `http {status}: {body}`; the rich `send` never + `EmailStatus::Failed` carrying `http {status}: {body}`; the rich `send` never returns an `Err`. The `Channel::send` envelope wrapper maps a `FAILED` result to `NotificationError::Delivery`. diff --git a/crates/notifications-sendgrid/README.md b/crates/notifications-sendgrid/README.md index 0bc1c612..a83ef250 100644 --- a/crates/notifications-sendgrid/README.md +++ b/crates/notifications-sendgrid/README.md @@ -100,9 +100,9 @@ dispatcher.register(Arc::new(Channel::new(Config { * `template_id` enables provider-native Dynamic Templates with `personalizations[0].dynamic_template_data`. * Attachments are base64-encoded as `{ filename, type, content }`. -* A 2xx response → `EmailStatus::SENT` with the `X-Message-Id` header as +* A 2xx response → `EmailStatus::Sent` with the `X-Message-Id` header as `provider_id`. Any other status (or a transport error) → - `EmailStatus::FAILED` carrying `http {status}: {body}`; the rich `send` never + `EmailStatus::Failed` carrying `http {status}: {body}`; the rich `send` never returns an `Err`. The `Channel::send` envelope wrapper maps a `FAILED` result to `NotificationError::Delivery`. diff --git a/crates/notifications-smtp/README.md b/crates/notifications-smtp/README.md index bca5013a..c752e0fe 100644 --- a/crates/notifications-smtp/README.md +++ b/crates/notifications-smtp/README.md @@ -29,7 +29,7 @@ let msg = EmailMessage { body_html: Some("

Hello

".into()), ..EmailMessage::default() }; -let result = provider.send(msg).await; // NotificationResult { status: SENT | FAILED, .. } +let result = provider.send(msg).await; // NotificationResult { status: Sent | Failed, .. } ``` ## Behavior @@ -49,7 +49,7 @@ let result = provider.send(msg).await; // NotificationResult { status: SENT | FA * STARTTLS is used when `use_tls` is set; credentials are attached only when both username and password are present. * Any failure (bad address, connection error, server rejection) is folded into - `EmailStatus::FAILED` carrying the error text — `send` never returns an + `EmailStatus::Failed` carrying the error text — `send` never returns an `Err`. ## Public surface @@ -60,7 +60,7 @@ let result = provider.send(msg).await; // NotificationResult { status: SENT | FA | `SmtpConfig` | `{ host, port, username?, password?, use_tls }`; defaults to port 587 with STARTTLS on. `from_config(get)` parses flat config keys. | | `build_message(&EmailMessage)` | The pure message-builder. Returns the exact `lettre::Message` the provider would transmit — used by the structure tests. | | `EmailMessage` / `Attachment` | Rich e-mail message model. | -| `EmailStatus` | `QUEUED` / `SENT` / `DELIVERED` / `BOUNCED` / `FAILED` / `SUPPRESSED`. | +| `EmailStatus` | `Queued` / `Sent` / `Delivered` / `Bounced` / `Failed` / `Suppressed`. | | `NotificationResult` | `{ id, provider, status, provider_id?, error? }`. | | `EmailProvider` | The async delivery port. | | `BuildError` | Errors from `build_message` (invalid address/header, assembly). | diff --git a/crates/notifications-smtp/src/lib.rs b/crates/notifications-smtp/src/lib.rs index 4b4097cc..a5c19615 100644 --- a/crates/notifications-smtp/src/lib.rs +++ b/crates/notifications-smtp/src/lib.rs @@ -87,7 +87,7 @@ use thiserror::Error; pub use email::{Attachment, EmailMessage, EmailProvider, EmailStatus, NotificationResult}; /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); /// The stable provider name used as the `provider` field of results. pub const PROVIDER_NAME: &str = "smtp"; diff --git a/crates/notifications-twilio/README.md b/crates/notifications-twilio/README.md index 0ed8dbaa..81d4e058 100644 --- a/crates/notifications-twilio/README.md +++ b/crates/notifications-twilio/README.md @@ -76,7 +76,7 @@ unused by the SMS channel. | --- | --- | | `Config` | Typed wiring for the adapter (account SID, auth token, sender number, …). | | `Channel` | `firefly_notifications::Channel` adapter; `Channel::new(cfg)` / `Channel::with_base_url(cfg, base)` construct it, `config()` exposes the wiring, `provider()` returns the underlying `TwilioSmsProvider`, `kind()` routes `Kind::SMS`, `name()` is `"notificationstwilio"`. | -| `TwilioSmsProvider` | The rich provider. `new(account_sid, auth_token)` constructs it; `with_from_number(..)` sets a default sender; `with_base_url(..)` / `with_http_client(..)` are wiring seams (the base URL defaults to the real Twilio host). Adds `fetch_status(sid)`. | +| `TwilioSmsProvider` | The rich provider. `new(account_sid, auth_token)` constructs it; `with_from_number(..)` sets a default sender; `with_base_url(..)` / `with_http_client(..)` are wiring seams (the base URL defaults to the real Twilio host). Adds `fetch_status(message_sid)`. | | `SmsProvider` | The async port (`name`, `send(SmsMessage) -> Result`), object-safe behind `Arc`/`Box`. | | `SmsMessage` | The outbound SMS message (`id` defaults to a UUID v4, optional `sender`). `new(to, body)` + `with_sender(..)`. | | `MessageStatus` | The delivery state returned by `fetch_status` (`sid`, raw `status`, `error_code?`, `error_message?`). | @@ -105,7 +105,7 @@ unused by the SMS channel. ### Status fetch -`TwilioSmsProvider::fetch_status(sid)` performs a `GET` against +`TwilioSmsProvider::fetch_status(message_sid)` performs a `GET` against `{base}/2010-04-01/Accounts/{sid}/Messages/{message_sid}.json` with basic auth and parses the `status`, `error_code`, and `error_message` fields into a `MessageStatus`. This is how callers poll for `delivered` / `failed` / diff --git a/crates/notifications-twilio/src/lib.rs b/crates/notifications-twilio/src/lib.rs index 496a768b..2a6bf33d 100644 --- a/crates/notifications-twilio/src/lib.rs +++ b/crates/notifications-twilio/src/lib.rs @@ -210,7 +210,7 @@ impl notifications::Channel for Channel { } /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); // Compile-time port assertion — the analog of Go's // `var _ notifications.Channel = (*Channel)(nil)`. @@ -358,6 +358,6 @@ mod tests { #[test] fn version_stamp() { - assert_eq!(VERSION, "26.6.24"); + assert_eq!(VERSION, env!("CARGO_PKG_VERSION")); } } diff --git a/crates/notifications/src/lib.rs b/crates/notifications/src/lib.rs index e49f7ac6..6ffc78bc 100644 --- a/crates/notifications/src/lib.rs +++ b/crates/notifications/src/lib.rs @@ -91,7 +91,7 @@ use chrono::{DateTime, TimeZone, Utc}; use serde::{Deserialize, Serialize}; /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); /// Errors produced by the notification port. #[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)] diff --git a/crates/openapi/README.md b/crates/openapi/README.md index a338df6e..4c65db42 100644 --- a/crates/openapi/README.md +++ b/crates/openapi/README.md @@ -78,11 +78,19 @@ pub struct RouteDef { pub response: Option, // sample of the success response, or None pub status: u16, // success status code; 0 defaults to 200/201 pub deprecated: bool, // renders deprecated:true; omitted when false + pub request_schema: Option, // named component schema for the body ($ref) + pub response_schema: Option, // named component schema for the response ($ref) + pub query_schema: Option, // a #[derive(Schema)] type whose fields expand to query params + pub pageable: bool, // injects page/size/sort params (Spring Pageable) } pub enum ParameterIn { Path, Query, Header, Cookie } pub struct Parameter { pub name: String, pub location: ParameterIn, pub required: bool, pub schema: Value } -impl Parameter { pub fn path(name: impl Into) -> Self; } // required in:path string +impl Parameter { + pub fn path(name: impl Into) -> Self; // required in:path string + pub fn query(name: impl Into, required: bool, schema: Value) -> Self; + pub fn header(name: impl Into, required: bool, schema: Value) -> Self; +} pub struct Tag { pub name: String, pub description: String } @@ -94,11 +102,23 @@ impl Builder { pub fn add_route(self, d: &firefly_container::RouteDescriptor) -> Self; // one #[rest_controller] route pub fn add_route_descriptors<'a, I>(self, ds: I) -> Self where I: IntoIterator; pub fn from_routes<'a, I>(self, ds: I) -> Self where I: IntoIterator; // alias + pub fn add_schema(self, name: impl Into, schema: Value) -> Self; // register one component schema + pub fn add_schema_descriptors<'a, I>(self, ds: I) -> Self where I: IntoIterator; + pub fn from_inventory(self) -> Self; // pull every #[rest_controller] route + #[derive(Schema)] type from the link-time registry pub fn build(&self) -> Document; pub fn json(&self) -> String; // the exact /openapi.json bytes pub fn router(&self) -> axum::Router; // serves /openapi.json + /openapi/ui + /redoc + pub fn docs_router(&self, cfg: &DocsConfig) -> axum::Router; // Swagger-UI + ReDoc + spec, mounted by FireflyApplication } +// Configures where docs_router serves each artifact (all paths have defaults). +pub struct DocsConfig { + pub spec_path: String, // default `/v3/api-docs` (Swagger/ReDoc point here) + pub spec_aliases: Vec, // default `["/openapi.json"]` + pub swagger_ui_path: String, // default `/swagger-ui` (also `{path}.html`) + pub redoc_path: String, // default `/redoc` +} // impl Default + pub struct Document { /* serializable OAS 3.1 root, incl. top-level tags */ } pub struct Operation { /* operationId, tags, parameters, deprecated, ... */ } pub enum OpenApiError { Serialize(serde_json::Error) } diff --git a/crates/openapi/src/lib.rs b/crates/openapi/src/lib.rs index e0fc0e1f..08bcbe94 100644 --- a/crates/openapi/src/lib.rs +++ b/crates/openapi/src/lib.rs @@ -132,7 +132,7 @@ use serde::{Deserialize, Serialize}; use serde_json::{json, Map, Value}; /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); /// Errors produced by the OpenAPI generator. #[derive(Debug, thiserror::Error)] diff --git a/crates/orchestration/README.md b/crates/orchestration/README.md index 22340ced..acc330d3 100644 --- a/crates/orchestration/README.md +++ b/crates/orchestration/README.md @@ -129,10 +129,10 @@ impl Saga { pub async fn run_cancellable(&self, token: &CancellationToken) -> Result; pub async fn run_with_context(&self, ctx: &StepContext) -> Result; } -pub enum CompensationPolicy { BestEffort, StopOnError } +pub enum CompensationPolicy { BestEffort, StopOnError, RetryWithBackoff, CircuitBreaker, BestEffortParallel, GroupedParallel } pub enum SagaStatus { Completed, Compensated, Failed } pub struct Outcome { saga, status, steps_executed, steps_rolled, error, started_at, finished_at } -pub enum SagaError { Step, Compensation, Cancelled } // SagaError::is_compensation_error +pub enum SagaError { Step, Compensation, Cancelled, Definition } // SagaError::is_compensation_error pub struct SagaFailure; // .outcome() / .error() / .into_parts() pub struct Node; // Node::new(name, run).depends_on(["a", "b"]) diff --git a/crates/orchestration/src/lib.rs b/crates/orchestration/src/lib.rs index 54763a87..3081f943 100644 --- a/crates/orchestration/src/lib.rs +++ b/crates/orchestration/src/lib.rs @@ -200,7 +200,7 @@ pub use web::{router, OrchestrationApi}; use std::future::Future; /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); /// Boxed error returned by step / node / participant callbacks — the Rust /// analogue of Go's `error` interface value. @@ -227,7 +227,7 @@ mod tests { #[test] fn version_stamp() { - assert_eq!(VERSION, "26.6.24"); + assert_eq!(VERSION, env!("CARGO_PKG_VERSION")); } #[test] diff --git a/crates/plugins/README.md b/crates/plugins/README.md index 0ca6bab3..60ef3dd7 100644 --- a/crates/plugins/README.md +++ b/crates/plugins/README.md @@ -138,7 +138,7 @@ contributed to them. Each point is keyed by an id carrying the interface's let point = extension_point::(); reg.register_extension_point("formatters", point).await; reg.register("formatters", Arc::new(JsonFormatter)).await?; // validated -let all: Vec> = reg.get("formatters").await; // priority-sorted +let all = reg.get("formatters").await; // priority-sorted let top = reg.get_extension("formatters").await?; // highest priority let typed = reg.get_as::("formatters").await; // downcast helper ``` diff --git a/crates/plugins/src/lib.rs b/crates/plugins/src/lib.rs index 37d0fc00..d05e0126 100644 --- a/crates/plugins/src/lib.rs +++ b/crates/plugins/src/lib.rs @@ -89,7 +89,7 @@ pub use extension::{extension_point, ExtensionPoint, ExtensionRegistry}; pub use manager::{PluginDescriptor, PluginManager}; /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); /// Boxed error type returned by plugin lifecycle hooks. /// diff --git a/crates/resilience/README.md b/crates/resilience/README.md index e31c3bcb..ac29f438 100644 --- a/crates/resilience/README.md +++ b/crates/resilience/README.md @@ -245,8 +245,7 @@ let chain = Chain::new() ### ResilienceRegistry -`ResilienceRegistry` materialises named breakers / limiters / bulkheads / -time-limiters from `firefly.resilience.*` configuration keys, consuming +`ResilienceRegistry` materialises named breakers / limiters / bulkheads / time-limiters / **retries** from `firefly.resilience.*` configuration keys, consuming the flat dot-keyed map that `firefly-config` sources produce: ```yaml diff --git a/crates/resilience/src/lib.rs b/crates/resilience/src/lib.rs index 6a55fe85..f0bf445d 100644 --- a/crates/resilience/src/lib.rs +++ b/crates/resilience/src/lib.rs @@ -106,7 +106,7 @@ pub use retry::{retry, JitterFn, Retry, RetryConfig, DEFAULT_MAX_ATTEMPTS}; pub use timeout::Timeout; /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); #[cfg(test)] mod tests { diff --git a/crates/rule-engine/src/lib.rs b/crates/rule-engine/src/lib.rs index b09bb45a..ecbc7d86 100644 --- a/crates/rule-engine/src/lib.rs +++ b/crates/rule-engine/src/lib.rs @@ -142,4 +142,4 @@ pub use crate::web::{ }; /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/crates/scheduling/src/lib.rs b/crates/scheduling/src/lib.rs index dd54e82d..f4faedf5 100644 --- a/crates/scheduling/src/lib.rs +++ b/crates/scheduling/src/lib.rs @@ -128,4 +128,4 @@ pub use scheduler::{ }; /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/crates/security/README.md b/crates/security/README.md index 531ece4a..8cb1f0af 100644 --- a/crates/security/README.md +++ b/crates/security/README.md @@ -77,6 +77,8 @@ pub struct Authentication { impl Authentication { pub fn has_role(&self, role: &str) -> bool; pub fn has_any_role(&self, roles: &[&str]) -> bool; + pub fn has_authority(&self, authority: &str) -> bool; + pub fn has_any_authority(&self, authorities: &[&str]) -> bool; pub fn anonymous() -> Self; } diff --git a/crates/security/src/lib.rs b/crates/security/src/lib.rs index 64558311..84ddafd4 100644 --- a/crates/security/src/lib.rs +++ b/crates/security/src/lib.rs @@ -180,4 +180,4 @@ pub use session_auth::{ }; /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/crates/session-mongodb/README.md b/crates/session-mongodb/README.md index b2ecf9c4..4b8b37c6 100644 --- a/crates/session-mongodb/README.md +++ b/crates/session-mongodb/README.md @@ -24,7 +24,7 @@ use firefly_session_mongodb::MongoSessionRegistry; // Connect from a URI (uses the URI's default database, else `firefly`, // and the `firefly_sessions` collection): let registry = MongoSessionRegistry::connect("mongodb://localhost:27017").await?; -registry.init().await?; // create the unique `session_id` + `principal` indexes +registry.init().await?; // create the unique `session_id` index and the `principal` index // …or build it over a Collection you already own (DI): // let registry = MongoSessionRegistry::from_collection(collection); diff --git a/crates/session-mongodb/src/lib.rs b/crates/session-mongodb/src/lib.rs index 1043b135..ac5684d6 100644 --- a/crates/session-mongodb/src/lib.rs +++ b/crates/session-mongodb/src/lib.rs @@ -69,7 +69,7 @@ const FIELD_PRINCIPAL: &str = "principal"; const FIELD_CREATED_AT: &str = "created_at"; /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); /// A MongoDB-backed [`SessionRegistry`]. /// diff --git a/crates/session-postgres/README.md b/crates/session-postgres/README.md index 71db1821..877e2ad0 100644 --- a/crates/session-postgres/README.md +++ b/crates/session-postgres/README.md @@ -103,8 +103,7 @@ assert_eq!(registry.count("alice").await, 1); The `SessionRegistry` trait methods are **infallible by contract**, so a per-operation Postgres failure is logged via `tracing` and swallowed — the -concurrency cap simply isn't enforced for that one login. Only the constructors -and `init()` return a `RegistryError` (connection / table-name / DDL failures). +concurrency cap simply isn't enforced for that one login. Only the `connect`, `connect_with_table`, `from_client_with_table` constructors and `init()` return a `RegistryError` (connection / table-name / DDL failures). ## Testing diff --git a/crates/session-postgres/src/lib.rs b/crates/session-postgres/src/lib.rs index 93eda679..f5110125 100644 --- a/crates/session-postgres/src/lib.rs +++ b/crates/session-postgres/src/lib.rs @@ -109,7 +109,7 @@ use tokio::sync::Mutex; use tokio_postgres::{Client, NoTls}; /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); /// The session-registry table name — pyfly's `pyfly_session_registry` under the /// Rust framework's `firefly_` prefix. diff --git a/crates/session-redis/README.md b/crates/session-redis/README.md index 06195905..e425bcc4 100644 --- a/crates/session-redis/README.md +++ b/crates/session-redis/README.md @@ -85,7 +85,7 @@ assert_eq!(registry.count("alice").await, 1); | `connect(url)` | Connect from a `redis://` URL, default prefix + 24h TTL. | | `connect_with(url, prefix, ttl_secs)` | Connect with a custom key prefix and sliding TTL. | | `from_connection(conn)` | Wrap an existing `MultiplexedConnection` (DI). | -| `from_connection_with(conn, prefix, ttl)` | Wrap an existing connection with custom prefix + TTL. | +| `from_connection_with(conn, prefix, ttl_secs)` | Wrap an existing connection with custom prefix + TTL. | The `SessionRegistry` trait methods are **infallible by contract** (the controller can't surface an error mid-login), so a per-operation Redis failure diff --git a/crates/session-redis/src/lib.rs b/crates/session-redis/src/lib.rs index 764e96ea..efee09bc 100644 --- a/crates/session-redis/src/lib.rs +++ b/crates/session-redis/src/lib.rs @@ -97,7 +97,7 @@ use redis::{AsyncCommands, Client}; use tokio::sync::Mutex; /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); /// The default key prefix for a principal's session sorted set — pyfly's /// `pyfly:session:user:` under the Rust framework's `firefly:` namespace. The diff --git a/crates/session/src/lib.rs b/crates/session/src/lib.rs index 3ddcb28e..32d0837c 100644 --- a/crates/session/src/lib.rs +++ b/crates/session/src/lib.rs @@ -81,4 +81,4 @@ pub use store::{ }; /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/crates/shell/src/lib.rs b/crates/shell/src/lib.rs index 3326c965..db122abe 100644 --- a/crates/shell/src/lib.rs +++ b/crates/shell/src/lib.rs @@ -84,4 +84,4 @@ pub use runner::{ApplicationArguments, ApplicationRunner, CommandLineRunner, Run pub use shell::{ShellRunner, StdShell}; /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/crates/sse/src/lib.rs b/crates/sse/src/lib.rs index 68a62568..7b94ed00 100644 --- a/crates/sse/src/lib.rs +++ b/crates/sse/src/lib.rs @@ -90,7 +90,7 @@ pub use writer::{last_event_id, SseError, SseResponse, SseWriter, LAST_EVENT_ID_ /// Released framework version. Calendar-versioned (`YY.M.PATCH`), the /// Rust port's counterpart of the Go `kernel.Version` constant. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); #[cfg(test)] mod tests { diff --git a/crates/starter-core/README.md b/crates/starter-core/README.md index 23e76f0a..ba18014f 100644 --- a/crates/starter-core/README.md +++ b/crates/starter-core/README.md @@ -58,6 +58,7 @@ CorsLayer (cors) — CORS edge (preflight + simple) ProblemLayer (always) — panic → 500 RFC7807 SecurityHeadersLayer (security_headers) — decorate every response CorrelationLayer (always) — X-Correlation-Id +TraceContextLayer (always) — W3C Trace Context validation + propagation MetricsLayer (request_metrics) — http_server_requests_* (order -100) HttpExchangesLayer (http_exchanges) — record into the recorder (order -90) RequestLogLayer (request_log) — one access-log event (order +200) diff --git a/crates/starter-web/README.md b/crates/starter-web/README.md index ba9b34cd..5a8843d3 100644 --- a/crates/starter-web/README.md +++ b/crates/starter-web/README.md @@ -44,11 +44,14 @@ admin-dashboard accessors, … — is available directly on the web value. pub struct WebStack { pub core: Core, // Deref/DerefMut target pub security: Option, // optional filter chain + pub exception_advice: Option, // optional global exception handlers } impl WebStack { pub fn new(cfg: CoreConfig) -> Self; // batteries on pub fn with_security(self, chain: FilterChain) -> Self; + pub fn set_security(&mut self, chain: FilterChain); // in-place; for a FilterChain discovered as a DI bean + pub fn set_exception_advice(&mut self, registry: firefly_web::ExceptionHandlerRegistry); // @ControllerAdvice handlers from DI pub fn apply_middleware(&self, router: Router) -> Router; // ... plus everything on Core via Deref } diff --git a/crates/testkit/README.md b/crates/testkit/README.md index 5bfb94b8..050762ac 100644 --- a/crates/testkit/README.md +++ b/crates/testkit/README.md @@ -155,6 +155,9 @@ impl BuiltSlice { pub fn get(&self) -> Arc; pub fn get_named(&self, name: &str) -> Arc; pub fn container(&self) -> Arc; + // `web` feature — the @WebMvcTest analog: mount a resolved #[derive(Controller)] + // bean over its sliced collaborators and drive it through a TestClient. + pub fn web_client axum::Router>(&self, routes: F) -> TestClient; } ``` diff --git a/crates/testkit/src/lib.rs b/crates/testkit/src/lib.rs index 647ba9ec..96a2ae36 100644 --- a/crates/testkit/src/lib.rs +++ b/crates/testkit/src/lib.rs @@ -83,4 +83,4 @@ pub use client::{TestClient, TestResponse}; pub use slice::{BuiltSlice, Slice}; /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/crates/transactional/README.md b/crates/transactional/README.md index fbea224f..04c9d9fb 100644 --- a/crates/transactional/README.md +++ b/crates/transactional/README.md @@ -84,7 +84,7 @@ pub fn exec<'a>(ctx: &TxContext<'a>, db: &'a dyn Executor) -> Conn<'a>; impl TxContext<'_> { pub const fn root() -> Self; - pub fn tx(&self) -> Option<&dyn Transaction>; + pub fn tx(&self) -> Option<&'a dyn Transaction>; pub fn in_transaction(&self) -> bool; } ``` diff --git a/crates/transactional/src/lib.rs b/crates/transactional/src/lib.rs index fa7e86f2..b5822445 100644 --- a/crates/transactional/src/lib.rs +++ b/crates/transactional/src/lib.rs @@ -123,7 +123,7 @@ pub use inventory; /// The released framework version. Calendar-versioned (`YY.M.PATCH`) /// expressed as valid semver — the Go port's `26.05.01` corresponds to /// `26.6.24` in the June 2026 release window. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); /// Errors produced by the transaction helper and the database port. /// @@ -732,6 +732,6 @@ mod tests { #[test] fn version_is_stamped() { - assert_eq!(VERSION, "26.6.24"); + assert_eq!(VERSION, env!("CARGO_PKG_VERSION")); } } diff --git a/crates/utils/src/lib.rs b/crates/utils/src/lib.rs index a9ab6e3d..fc2c420b 100644 --- a/crates/utils/src/lib.rs +++ b/crates/utils/src/lib.rs @@ -73,13 +73,13 @@ pub use template::{render_html, render_text, TemplateError}; pub use tryfn::{try_of, try_run, TryError}; /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); #[cfg(test)] mod tests { /// The version stamp matches the workspace CalVer release. #[test] fn version_stamp() { - assert_eq!(super::VERSION, "26.6.24"); + assert_eq!(super::VERSION, env!("CARGO_PKG_VERSION")); } } diff --git a/crates/validators/src/lib.rs b/crates/validators/src/lib.rs index 71fb2d34..1c996af7 100644 --- a/crates/validators/src/lib.rs +++ b/crates/validators/src/lib.rs @@ -49,7 +49,7 @@ pub mod bean; pub use bean::{Validate, ValidationError as FieldError, ValidationErrors}; /// Framework version stamp. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); /// The canonical error returned by every validator when the input is /// malformed. @@ -1135,6 +1135,6 @@ mod tests { #[test] fn version_stamp() { - assert_eq!(VERSION, "26.6.24"); + assert_eq!(VERSION, env!("CARGO_PKG_VERSION")); } } diff --git a/crates/webhooks/README.md b/crates/webhooks/README.md index 50d924cb..55e4166f 100644 --- a/crates/webhooks/README.md +++ b/crates/webhooks/README.md @@ -15,7 +15,7 @@ The crate is split into focused modules: | Module | What it provides | |--------------|-------------------------------------------------------------------------| | `interfaces` | `Inbound` DTO + `Validator`, `Processor` ports | -| `core` | `Pipeline`, in-memory `MemoryDlq`, four canonical signature validators | +| `core` | `Pipeline`, in-memory `MemoryDlq`, idempotency `EventStore`, four canonical signature validators | | `processor` | SPI surface for service-supplied per-provider processors | | `web` | `POST /api/webhooks/{provider}` ingestion `axum::Router` | | `sdk` | Typed forwarder (replay DLQ entries; cross-service composition) | diff --git a/crates/webhooks/src/lib.rs b/crates/webhooks/src/lib.rs index fd42c1b3..24b2e135 100644 --- a/crates/webhooks/src/lib.rs +++ b/crates/webhooks/src/lib.rs @@ -95,4 +95,4 @@ pub use sdk::Client; pub use web::router; /// The released framework version (CalVer expressed as semver). -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/crates/websocket/src/lib.rs b/crates/websocket/src/lib.rs index d912383e..c3803276 100644 --- a/crates/websocket/src/lib.rs +++ b/crates/websocket/src/lib.rs @@ -84,7 +84,7 @@ pub use session::WsSession; /// Released framework version. Calendar-versioned (`YY.M.PATCH`), the Rust /// port's counterpart of the Go `kernel.Version` constant. -pub const VERSION: &str = "26.6.24"; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); #[cfg(test)] mod tests {