greentic-flow-builder 0.1.0

AI-powered Adaptive Card flow builder with visual graph editor and demo runner
Documentation
//! Template catalog endpoints.
//!
//! `GET /api/templates` returns presets grouped by category (the shape the
//! frontend expects). `GET /api/templates/:name` returns full details for a
//! single preset.

use crate::ui::state::AppState;
use axum::Json;
use axum::extract::{Path, State};
use axum::http::StatusCode;
use axum::response::IntoResponse;
use serde_json::{Value, json};
use std::sync::Arc;

pub async fn list_templates(State(state): State<Arc<AppState>>) -> Json<Value> {
    let mut categories = Vec::new();
    for category in &state.registry.categories {
        let presets: Vec<Value> = category
            .presets
            .iter()
            .filter_map(|name| state.registry.get_preset(name))
            .map(|p| {
                json!({
                    "name": p.name,
                    "title": p.title,
                    "description": p.description,
                    "tags": p.tags,
                    "use_cases": p.use_cases,
                    "example": p.example,
                })
            })
            .collect();
        categories.push(json!({
            "name": category.name,
            "display_name": category.display_name,
            "description": category.description,
            "presets": presets,
        }));
    }
    Json(json!({ "categories": categories }))
}

pub async fn get_template(
    State(state): State<Arc<AppState>>,
    Path(name): Path<String>,
) -> impl IntoResponse {
    match state.registry.get_preset(&name) {
        Some(preset) => Json(json!({
            "name": preset.name,
            "title": preset.title,
            "description": preset.description,
            "category": preset.category,
            "tags": preset.tags,
            "use_cases": preset.use_cases,
            "example": preset.example,
            "schema": preset.schema,
        }))
        .into_response(),
        None => (
            StatusCode::NOT_FOUND,
            Json(json!({
                "error": format!("preset '{name}' not found")
            })),
        )
            .into_response(),
    }
}