omniterm 0.1.7

Web-based tmux terminal manager with AI agent monitoring
use axum::{
    extract::{Path, State},
    http::StatusCode,
    response::IntoResponse,
    routing::{delete, get},
    Json, Router,
};
use serde_json::json;
use uuid::Uuid;

use crate::models::target::{CreateTarget, Target};
use crate::AppState;

pub fn routes() -> Router<AppState> {
    Router::new()
        .route("/targets", get(list_targets).post(create_target))
        .route("/targets/{id}", delete(delete_target))
}

async fn list_targets(State(state): State<AppState>) -> impl IntoResponse {
    let targets: Vec<Target> = sqlx::query_as("SELECT * FROM targets ORDER BY created_at DESC")
        .fetch_all(&state.db)
        .await
        .unwrap();

    Json(json!(targets))
}

async fn create_target(
    State(state): State<AppState>,
    Json(req): Json<CreateTarget>,
) -> impl IntoResponse {
    let id = Uuid::new_v4().to_string();
    let now = chrono::Utc::now().to_rfc3339();

    sqlx::query(
        "INSERT INTO targets (id, name, type, config, created_at) VALUES (?, ?, ?, ?, ?)",
    )
    .bind(&id)
    .bind(&req.name)
    .bind(&req.target_type)
    .bind(&req.config)
    .bind(&now)
    .execute(&state.db)
    .await
    .unwrap();

    let target = Target {
        id,
        name: req.name,
        target_type: req.target_type,
        config: req.config,
        created_at: now,
    };

    (StatusCode::CREATED, Json(json!(target)))
}

async fn delete_target(
    State(state): State<AppState>,
    Path(id): Path<String>,
) -> impl IntoResponse {
    let result = sqlx::query("DELETE FROM targets WHERE id = ?")
        .bind(&id)
        .execute(&state.db)
        .await
        .unwrap();

    if result.rows_affected() == 0 {
        return (StatusCode::NOT_FOUND, Json(json!({ "error": "not found" })));
    }

    (StatusCode::OK, Json(json!({ "ok": true })))
}