//! Router assembly. Exactly one route is unauthenticated: `GET /health`.
pub(crate) mod apps;
pub(crate) mod jobs;
use axum::routing::{get, post};
use axum::{Json, Router, middleware};
use twice_core::{API_PREFIX, HealthResponse};
use crate::auth;
use crate::state::AppState;
/// Builds the full application router, mounted under [`API_PREFIX`].
pub(crate) fn router(state: AppState) -> Router {
let protected = Router::new()
.route("/apps", get(apps::list))
.route("/apps/{host}/start", post(apps::start))
.route("/apps/{host}/stop", post(apps::stop))
.route("/apps/{host}/update", post(apps::update_image))
.route("/infrastructure/apply", post(apps::apply_infrastructure))
.route("/jobs", get(jobs::list))
.route("/jobs/{id}", get(jobs::get_one))
.route("/jobs/{id}/stream", get(jobs::stream))
.route_layer(middleware::from_fn_with_state(
std::sync::Arc::clone(&state.config),
auth::require_api_key,
));
let api = Router::new()
.route("/health", get(health))
.merge(protected)
.with_state(state);
Router::new().nest(API_PREFIX, api)
}
async fn health() -> Json<HealthResponse> {
Json(HealthResponse {
service: "twice".to_owned(),
version: env!("CARGO_PKG_VERSION").to_owned(),
})
}