From b244d0e925690b7c318ea09654c6c3cae88fbcdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Contreras=20Guill=C3=A9n?= Date: Tue, 16 Jun 2026 16:39:33 +0200 Subject: [PATCH] fix: per-crate README audit + VERSION no longer drifts (26.6.26) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A correctness release with one real framework bug fix surfaced by the audit. VERSION drift (framework bug) Every crate's `pub const VERSION` was a hardcoded `"26.6.24"` literal 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. The `version_matches_crate_version` guard tests only passed while the workspace happened to sit at 26.6.24; the previous release (26.6.25) actually shipped with these tests red. All 52 hardcoded constants now derive from env!("CARGO_PKG_VERSION") (the re-exporting crates already chained to firefly_kernel::VERSION), and the cli FRAMEWORK_VERSION const plus the six unit/integration tests that asserted VERSION == "26.6.24" against a frozen literal were de-hardcoded the same way. VERSION can never drift again. (The cli render_for / SBOM-parser fixtures keep their literal sample versions — that string is arbitrary test data, not the build version.) Per-crate README audit (43 confirmed fixes across 28 crates) Every one of the 74 crate READMEs was audited against that crate's actual shipped public API, each finding verified against the source before applying: - Phantom / incomplete public surface: admin AdminDeps.environment; openapi RouteDef (request_schema/response_schema/query_schema/pageable), Parameter::{query,header}, Builder::{add_schema,add_schema_descriptors, from_inventory,docs_router}, DocsConfig; orchestration CompensationPolicy (all 6 variants) + SagaError; starter-web WebStack::{set_security, set_exception_advice}; testkit BuiltSlice::web_client; idp Error + change_password; security/webhooks/kernel/transactional/plugins. - Wrong signatures / variants: notifications-* EmailStatus::SENT/FAILED -> Sent/Failed (serde rename only affects the wire form); plugins Vec> -> the real Extension = Arc; notifications-twilio / session-redis param names. - Wrong facts: admin bean graph ships dependency `edges` (not nodes-only); backoffice middleware order includes TraceContext; container warm->form typo; resilience / starter-core / eda-kafka / session-* fixes. - Stale version pins: README dependency examples pinned the long-stale 26.6.7; now use the self-maintaining minor pin version = "26.6". 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 member. (The audit flagged the cache README as wrong here; the README was right and the lib.rs comment was the stale one — fixed the actual source of truth.) make ci green end to end: 315 suites, 4484 tests, 0 failed. --- CHANGELOG.md | 55 +++++++ Cargo.lock | 172 ++++++++++---------- Cargo.toml | 150 ++++++++--------- crates/actuator/README.md | 2 +- crates/actuator/src/lib.rs | 4 +- crates/admin/README.md | 8 +- crates/admin/src/lib.rs | 2 +- crates/aop/src/lib.rs | 2 +- crates/backoffice/README.md | 2 +- crates/cache-postgres/src/lib.rs | 2 +- crates/cache-redis/src/lib.rs | 2 +- crates/cache/src/lib.rs | 6 +- crates/callbacks/src/lib.rs | 2 +- crates/cli/src/diagnostics.rs | 2 +- crates/cli/src/lib.rs | 2 +- crates/config-server/src/lib.rs | 2 +- crates/container/README.md | 2 +- crates/container/src/lib.rs | 2 +- crates/cqrs/src/lib.rs | 2 +- crates/data-mongodb/README.md | 2 +- crates/data-mongodb/src/lib.rs | 2 +- crates/data-sqlx/README.md | 4 +- crates/data-sqlx/src/lib.rs | 2 +- crates/data/src/lib.rs | 2 +- crates/ecm-esignature-adobe-sign/src/lib.rs | 2 +- crates/ecm-esignature-docusign/src/lib.rs | 2 +- crates/ecm-esignature-logalty/src/lib.rs | 2 +- crates/ecm-storage-aws/src/lib.rs | 2 +- crates/ecm-storage-azure/src/lib.rs | 2 +- crates/ecm/src/lib.rs | 2 +- crates/eda-kafka/README.md | 2 +- crates/eda-kafka/src/lib.rs | 2 +- crates/eda-postgres/src/lib.rs | 2 +- crates/eda-rabbitmq/src/lib.rs | 2 +- crates/eda-redis/src/lib.rs | 2 +- crates/eda/src/lib.rs | 2 +- crates/eventsourcing/src/lib.rs | 2 +- crates/i18n/src/lib.rs | 2 +- crates/idp/README.md | 13 +- crates/kernel/README.md | 9 +- crates/kernel/src/lib.rs | 2 +- crates/kernel/tests/kernel_test.rs | 2 +- crates/migrations/src/lib.rs | 2 +- crates/notifications-firebase/README.md | 2 +- crates/notifications-firebase/src/lib.rs | 2 +- crates/notifications-resend/README.md | 4 +- crates/notifications-sendgrid/README.md | 4 +- crates/notifications-smtp/README.md | 6 +- crates/notifications-smtp/src/lib.rs | 2 +- crates/notifications-twilio/README.md | 4 +- crates/notifications-twilio/src/lib.rs | 4 +- crates/notifications/src/lib.rs | 2 +- crates/openapi/README.md | 22 ++- crates/openapi/src/lib.rs | 2 +- crates/orchestration/README.md | 4 +- crates/orchestration/src/lib.rs | 4 +- crates/plugins/README.md | 2 +- crates/plugins/src/lib.rs | 2 +- crates/resilience/README.md | 3 +- crates/resilience/src/lib.rs | 2 +- crates/rule-engine/src/lib.rs | 2 +- crates/scheduling/src/lib.rs | 2 +- crates/security/README.md | 2 + crates/security/src/lib.rs | 2 +- crates/session-mongodb/README.md | 2 +- crates/session-mongodb/src/lib.rs | 2 +- crates/session-postgres/README.md | 3 +- crates/session-postgres/src/lib.rs | 2 +- crates/session-redis/README.md | 2 +- crates/session-redis/src/lib.rs | 2 +- crates/session/src/lib.rs | 2 +- crates/shell/src/lib.rs | 2 +- crates/sse/src/lib.rs | 2 +- crates/starter-core/README.md | 1 + crates/starter-web/README.md | 3 + crates/testkit/README.md | 3 + crates/testkit/src/lib.rs | 2 +- crates/transactional/README.md | 2 +- crates/transactional/src/lib.rs | 4 +- crates/utils/src/lib.rs | 4 +- crates/validators/src/lib.rs | 4 +- crates/webhooks/README.md | 2 +- crates/webhooks/src/lib.rs | 2 +- crates/websocket/src/lib.rs | 2 +- 84 files changed, 354 insertions(+), 262 deletions(-) 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 {