//! [`HealthUseCase`] — a trivial, in-memory use case used to validate the //! end-to-end wiring (composition root → Tauri command → use case → ports → //! frontend gateway). It carries its ports as `Arc`, exactly like //! every real use case will (ARCHITECTURE §6). //! //! It depends only on the utility ports [`Clock`] and [`IdGenerator`], so it //! exercises dependency injection without needing any I/O adapter. use std::sync::Arc; use domain::ports::{Clock, EventBus, IdGenerator}; use domain::DomainEvent; use domain::ProjectId; use crate::error::AppError; /// Input for [`HealthUseCase::execute`]. #[derive(Debug, Clone, PartialEq, Eq, Default)] pub struct HealthInput { /// Optional caller-supplied note echoed back in the report (used by tests /// and the frontend smoke check). pub note: Option, } /// Output of [`HealthUseCase::execute`]: a small health report. #[derive(Debug, Clone, PartialEq, Eq)] pub struct HealthReport { /// Application/crate version (`CARGO_PKG_VERSION`). pub version: String, /// Liveness flag — always `true` if the use case ran. pub alive: bool, /// Server "now" in epoch milliseconds (from the injected [`Clock`]). pub time_millis: i64, /// A fresh correlation id (from the injected [`IdGenerator`]). pub correlation_id: String, /// Echoed caller note, if any. pub note: Option, } /// Trivial health/ping use case validating the DI + IPC pipeline. pub struct HealthUseCase { clock: Arc, ids: Arc, events: Arc, } impl HealthUseCase { /// Builds the use case from its injected ports. #[must_use] pub fn new( clock: Arc, ids: Arc, events: Arc, ) -> Self { Self { clock, ids, events } } /// Executes the health check. /// /// As a side effect it publishes a [`DomainEvent`] on the [`EventBus`] so /// the event-relay path is exercised end to end (the relay forwards it to a /// Tauri event). A `ProjectCreated`-shaped event is reused here purely as a /// no-op smoke signal; no project is actually created. /// /// # Errors /// Returns [`AppError`] — never, in this trivial implementation, but the /// signature matches the real use-case contract. pub fn execute(&self, input: HealthInput) -> Result { let correlation = self.ids.new_uuid(); // Exercise the event-bus relay path with a harmless smoke event. self.events.publish(DomainEvent::ProjectCreated { project_id: ProjectId::from_uuid(correlation), }); Ok(HealthReport { version: env!("CARGO_PKG_VERSION").to_owned(), alive: true, time_millis: self.clock.now_millis(), correlation_id: correlation.to_string(), note: input.note, }) } }