212 lines
5.5 KiB
Rust
212 lines
5.5 KiB
Rust
use axum::{
|
|
Json,
|
|
extract::{Path, Query, State},
|
|
http::{
|
|
HeaderValue, StatusCode,
|
|
header::{CONTENT_DISPOSITION, CONTENT_TYPE},
|
|
},
|
|
response::{IntoResponse, Response},
|
|
};
|
|
use serde_json::{Value, json};
|
|
|
|
use crate::{
|
|
error::ApiError,
|
|
routes::access::WorkspacePath,
|
|
service::{ApprovalDecisionPayload, ApprovalsQuery, LogsQuery, UsageRequestQuery},
|
|
state::AppState,
|
|
};
|
|
|
|
#[derive(serde::Deserialize)]
|
|
pub struct WorkspaceLogPath {
|
|
pub workspace_id: String,
|
|
pub log_id: String,
|
|
}
|
|
|
|
#[derive(serde::Deserialize)]
|
|
pub struct WorkspaceApprovalPath {
|
|
pub workspace_id: String,
|
|
pub approval_id: String,
|
|
}
|
|
|
|
#[derive(serde::Deserialize)]
|
|
pub struct WorkspaceOperationUsagePath {
|
|
pub workspace_id: String,
|
|
pub operation_id: String,
|
|
}
|
|
|
|
#[derive(serde::Deserialize)]
|
|
pub struct WorkspaceAgentUsagePath {
|
|
pub workspace_id: String,
|
|
pub agent_id: String,
|
|
}
|
|
|
|
pub async fn list_logs(
|
|
Path(path): Path<WorkspacePath>,
|
|
Query(query): Query<LogsQuery>,
|
|
State(state): State<AppState>,
|
|
) -> Result<Json<Value>, ApiError> {
|
|
let items = state
|
|
.service
|
|
.list_logs(&path.workspace_id.as_str().into(), query)
|
|
.await?;
|
|
Ok(Json(json!(items)))
|
|
}
|
|
|
|
pub async fn export_logs_csv(
|
|
Path(path): Path<WorkspacePath>,
|
|
Query(query): Query<LogsQuery>,
|
|
State(state): State<AppState>,
|
|
) -> Result<Response, ApiError> {
|
|
let csv = state
|
|
.service
|
|
.export_logs_csv(&path.workspace_id.as_str().into(), query)
|
|
.await?;
|
|
let mut response = (StatusCode::OK, csv).into_response();
|
|
response.headers_mut().insert(
|
|
CONTENT_TYPE,
|
|
HeaderValue::from_static("text/csv; charset=utf-8"),
|
|
);
|
|
response.headers_mut().insert(
|
|
CONTENT_DISPOSITION,
|
|
HeaderValue::from_static("attachment; filename=\"crank-invocation-history.csv\""),
|
|
);
|
|
Ok(response)
|
|
}
|
|
|
|
pub async fn export_usage_csv(
|
|
Path(path): Path<WorkspacePath>,
|
|
Query(query): Query<UsageRequestQuery>,
|
|
State(state): State<AppState>,
|
|
) -> Result<Response, ApiError> {
|
|
let csv = state
|
|
.service
|
|
.export_usage_csv(&path.workspace_id.as_str().into(), query)
|
|
.await?;
|
|
let mut response = (StatusCode::OK, csv).into_response();
|
|
response.headers_mut().insert(
|
|
CONTENT_TYPE,
|
|
HeaderValue::from_static("text/csv; charset=utf-8"),
|
|
);
|
|
response.headers_mut().insert(
|
|
CONTENT_DISPOSITION,
|
|
HeaderValue::from_static("attachment; filename=\"crank-usage.csv\""),
|
|
);
|
|
Ok(response)
|
|
}
|
|
|
|
pub async fn get_log(
|
|
Path(path): Path<WorkspaceLogPath>,
|
|
State(state): State<AppState>,
|
|
) -> Result<Json<Value>, ApiError> {
|
|
let item = state
|
|
.service
|
|
.get_log(
|
|
&path.workspace_id.as_str().into(),
|
|
&path.log_id.as_str().into(),
|
|
)
|
|
.await?;
|
|
Ok(Json(json!(item)))
|
|
}
|
|
|
|
pub async fn list_approvals(
|
|
Path(path): Path<WorkspacePath>,
|
|
Query(query): Query<ApprovalsQuery>,
|
|
State(state): State<AppState>,
|
|
) -> Result<Json<Value>, ApiError> {
|
|
let items = state
|
|
.service
|
|
.list_approvals(&path.workspace_id.as_str().into(), query)
|
|
.await?;
|
|
Ok(Json(json!({ "items": items })))
|
|
}
|
|
|
|
pub async fn get_approval(
|
|
Path(path): Path<WorkspaceApprovalPath>,
|
|
State(state): State<AppState>,
|
|
) -> Result<Json<Value>, ApiError> {
|
|
let item = state
|
|
.service
|
|
.get_approval(
|
|
&path.workspace_id.as_str().into(),
|
|
&path.approval_id.as_str().into(),
|
|
)
|
|
.await?;
|
|
Ok(Json(json!(item)))
|
|
}
|
|
|
|
pub async fn approve_approval(
|
|
Path(path): Path<WorkspaceApprovalPath>,
|
|
State(state): State<AppState>,
|
|
Json(payload): Json<ApprovalDecisionPayload>,
|
|
) -> Result<Json<Value>, ApiError> {
|
|
let item = state
|
|
.service
|
|
.approve_approval(
|
|
&path.workspace_id.as_str().into(),
|
|
&path.approval_id.as_str().into(),
|
|
payload,
|
|
)
|
|
.await?;
|
|
Ok(Json(json!(item)))
|
|
}
|
|
|
|
pub async fn deny_approval(
|
|
Path(path): Path<WorkspaceApprovalPath>,
|
|
State(state): State<AppState>,
|
|
Json(payload): Json<ApprovalDecisionPayload>,
|
|
) -> Result<Json<Value>, ApiError> {
|
|
let item = state
|
|
.service
|
|
.deny_approval(
|
|
&path.workspace_id.as_str().into(),
|
|
&path.approval_id.as_str().into(),
|
|
payload,
|
|
)
|
|
.await?;
|
|
Ok(Json(json!(item)))
|
|
}
|
|
|
|
pub async fn get_usage(
|
|
Path(path): Path<WorkspacePath>,
|
|
Query(query): Query<UsageRequestQuery>,
|
|
State(state): State<AppState>,
|
|
) -> Result<Json<Value>, ApiError> {
|
|
let usage = state
|
|
.service
|
|
.get_usage_overview(&path.workspace_id.as_str().into(), query)
|
|
.await?;
|
|
Ok(Json(json!(usage)))
|
|
}
|
|
|
|
pub async fn get_operation_usage(
|
|
Path(path): Path<WorkspaceOperationUsagePath>,
|
|
Query(query): Query<UsageRequestQuery>,
|
|
State(state): State<AppState>,
|
|
) -> Result<Json<Value>, ApiError> {
|
|
let usage = state
|
|
.service
|
|
.get_operation_usage(
|
|
&path.workspace_id.as_str().into(),
|
|
&path.operation_id.as_str().into(),
|
|
query,
|
|
)
|
|
.await?;
|
|
Ok(Json(json!(usage)))
|
|
}
|
|
|
|
pub async fn get_agent_usage(
|
|
Path(path): Path<WorkspaceAgentUsagePath>,
|
|
Query(query): Query<UsageRequestQuery>,
|
|
State(state): State<AppState>,
|
|
) -> Result<Json<Value>, ApiError> {
|
|
let usage = state
|
|
.service
|
|
.get_agent_usage(
|
|
&path.workspace_id.as_str().into(),
|
|
&path.agent_id.as_str().into(),
|
|
query,
|
|
)
|
|
.await?;
|
|
Ok(Json(json!(usage)))
|
|
}
|