use async_nats::jetstream::{ stream::{Config as StreamConfig, RetentionPolicy, StorageType}, Context, }; use tracing::info; use crate::Error; /// Provision all six JetStream streams required by the provisioning platform. /// Idempotent — uses `get_or_create_stream` so safe to call on every startup. pub async fn ensure_provisioning_streams(js: &Context) -> Result<(), Error> { let streams: &[(&str, &[&str], RetentionPolicy)] = &[ ( "TASKS", &["provisioning.tasks.>"], RetentionPolicy::WorkQueue, ), ( "VAULT", &["provisioning.vault.>"], RetentionPolicy::Interest, ), ("AUTH", &["provisioning.auth.>"], RetentionPolicy::Interest), ( "WORKSPACE", &["provisioning.workspace.>"], RetentionPolicy::Limits, ), ("AUDIT", &["provisioning.audit.>"], RetentionPolicy::Limits), ( "HEALTH", &["provisioning.health.>"], RetentionPolicy::Interest, ), ]; for (name, subjects, retention) in streams { let cfg = StreamConfig { name: name.to_string(), subjects: subjects.iter().map(|s| s.to_string()).collect(), retention: *retention, storage: StorageType::File, ..Default::default() }; js.get_or_create_stream(cfg) .await .map_err(|e| Error::Stream(format!("failed to ensure stream {name}: {e}")))?; info!(stream = name, "JetStream stream ready"); } Ok(()) }