Skip to main content

assay_workflow/api/
meta.rs

1//! Engine metadata endpoints — version, build info.
2//!
3//! Exists so the CLI, the dashboard, and any third-party monitor can
4//! discover which build they're talking to without parsing banner text
5//! from server logs. `GET /api/v1/version` is meant to be cheap,
6//! unauthenticated (when auth mode allows), and version-stamped via
7//! `env!("CARGO_PKG_VERSION")` at compile time.
8
9use std::sync::Arc;
10
11use axum::extract::State;
12use axum::routing::get;
13use axum::{Json, Router};
14use serde::Serialize;
15use utoipa::ToSchema;
16
17use crate::api::AppState;
18use crate::store::WorkflowStore;
19
20#[derive(Serialize, ToSchema)]
21pub struct VersionInfo {
22    /// Semver of the `assay-workflow` crate at compile time
23    /// (`CARGO_PKG_VERSION`). Matches `assay --version` for the binary.
24    pub version: &'static str,
25    /// `release` or `debug` — derived from `cfg!(debug_assertions)`.
26    pub build_profile: &'static str,
27}
28
29pub fn router<S: WorkflowStore + 'static>() -> Router<Arc<AppState<S>>> {
30    Router::new().route("/version", get(version))
31}
32
33#[utoipa::path(
34    get,
35    path = "/api/v1/version",
36    tag = "meta",
37    responses((status = 200, description = "Engine version info", body = VersionInfo)),
38)]
39pub async fn version<S: WorkflowStore>(
40    State(state): State<Arc<AppState<S>>>,
41) -> Json<VersionInfo> {
42    // Prefer the embedding binary's version if it was supplied (e.g. the
43    // `assay` CLI passes its own CARGO_PKG_VERSION). Fall back to this
44    // crate's version for embedders that didn't set it.
45    let version = state
46        .binary_version
47        .unwrap_or(env!("CARGO_PKG_VERSION"));
48    Json(VersionInfo {
49        version,
50        build_profile: if cfg!(debug_assertions) {
51            "debug"
52        } else {
53            "release"
54        },
55    })
56}