use pforge_runtime::Handler;
use std::path::{Path, PathBuf};
use crate::tripwire::audit_trail;
use super::types::*;
pub struct AuditHandler;
pub struct WorkspaceHandler;
const DEFAULT_AUDIT_LIMIT: usize = 20;
#[async_trait::async_trait]
impl Handler for AuditHandler {
type Input = AuditInput;
type Output = AuditOutput;
type Error = pforge_runtime::Error;
async fn handle(&self, input: Self::Input) -> pforge_runtime::Result<Self::Output> {
let state_dir =
super::paths::resolve_state_dir_opt(input.path.as_deref(), input.state_dir.as_deref());
let limit = input.limit.unwrap_or(DEFAULT_AUDIT_LIMIT);
let events = audit_trail::collect_events(&state_dir, input.machine.as_deref(), limit)
.map_err(pforge_runtime::Error::Handler)?;
let events: Vec<AuditEventOutput> = events
.into_iter()
.map(|(machine, ev)| {
let event = serde_json::to_value(&ev.event).unwrap_or(serde_json::Value::Null);
AuditEventOutput {
machine,
timestamp: ev.ts,
event,
}
})
.collect();
Ok(AuditOutput {
event_count: events.len(),
events,
})
}
}
#[async_trait::async_trait]
impl Handler for WorkspaceHandler {
type Input = WorkspaceInput;
type Output = WorkspaceOutput;
type Error = pforge_runtime::Error;
async fn handle(&self, input: Self::Input) -> pforge_runtime::Result<Self::Output> {
let root: PathBuf = input
.path
.as_deref()
.and_then(|p| Path::new(p).parent().map(Path::to_path_buf))
.unwrap_or_else(|| PathBuf::from("."));
let state_base =
super::paths::resolve_state_base_opt(input.path.as_deref(), input.state_dir.as_deref());
let found = crate::cli::workspace::list_workspaces_in(&root, &state_base)
.map_err(pforge_runtime::Error::Handler)?;
let active = crate::cli::workspace::current_workspace_in(&root);
let workspace_state_dir = match active.as_deref() {
Some(ws) => state_base.join(ws),
None => state_base.clone(),
};
Ok(WorkspaceOutput {
active,
workspaces: found
.into_iter()
.map(|w| WorkspaceEntryOutput {
name: w.name,
active: w.active,
})
.collect(),
state_base_exists: state_base.exists(),
state_base: state_base.display().to_string(),
workspace_state_dir: workspace_state_dir.display().to_string(),
})
}
}