breathe-api-server 0.1.29

breathe's REST surface (axum) over the BreatheStore facade — the same typed core the MCP drives. Routes for bands + nodepools + catalog mirror spec/breathe.openapi.yaml (the source of truth); handlers are kube-rs facade calls (the design's legit hand-serve).
Documentation
[package]
name = "breathe-api-server"
version = "0.1.29"
edition.workspace = true
rust-version.workspace = true
license.workspace = true
authors.workspace = true
repository.workspace = true
description = "breathe's REST surface (axum) over the BreatheStore facade — the same typed core the MCP drives. Routes for bands + nodepools + catalog mirror spec/breathe.openapi.yaml (the source of truth); handlers are kube-rs facade calls (the design's legit hand-serve)."

[[bin]]
name = "breathe-api-server"
path = "src/main.rs"

[dependencies]
breathe-facade = { path = "../breathe-facade", version = "0.1.29" }
# CONFIRMED_ANNOTATION + DimensionId::dry_run_is_honored — the surface needs the
# canonical facts, not a local copy of them.
breathe-provider = { path = "../breathe-provider", version = "0.1.29" }
# Explicit process-wide CryptoProvider install (main.rs) -- see
# breathe-controller/Cargo.toml for the full story.
rustls = { version = "0.23", default-features = false, features = ["aws_lc_rs"] }
axum = "0.7"
async-graphql = "7"
async-graphql-axum = "7"
tonic = "0.12"
prost = "0.13"
prost-types = "0.13"
# pbjson makes the generated proto messages serde-(de)serializable (the proto3
# JSON mapping) so the facade's serde_json::Value bridges to typed gRPC.
pbjson = "0.7"
pbjson-types = "0.7"
tokio = { version = "1.40", features = ["macros", "rt-multi-thread"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1.0"
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter", "json"] }

[build-dependencies]
tonic-build = "0.12"
prost-build = "0.13"
pbjson-build = "0.7"
protoc-bin-vendored = "3"   # vendored protoc for local builds; nix uses system protobuf
which = "6"

[dev-dependencies]
async-trait = "0.1"
# spec/breathe.openapi.yaml calls itself the SINGLE SOURCE OF TRUTH, and forge-gen
# emits SDKs and docs from it — so a stale BandKind enum there propagates into every
# generated artifact. `openapi_spec_band_kinds_match_the_code` parses the real file
# and pins it to DimensionId::ALL. That claim needs a YAML reader to be mechanical
# rather than a comment.
serde_yaml = "0.9"
tower = { version = "0.5", features = ["util"] }
http-body-util = "0.1"
# The canonical dimension count — the catalog tests assert against ALL_DIMENSIONS
# so the API-surface count never goes stale when a dimension lands (it bit 7->8
# and 8->9 as hardcoded literals; now it tracks the source of truth).
breathe-catalog = { path = "../breathe-catalog", version = "0.1.29" }

[lints]
workspace = true