use axum::Json;
use axum::extract::{Path, Query, State};
use serde::Deserialize;
use serde_json::Value;
use crate::admin;
use crate::sqlite::status::{UnknownStatus, UpstreamOrderStatus};
use crate::sqlite::upstream_order::{UpstreamOrder, UpstreamOrderQuery};
use crate::webadmin::AdminState;
use crate::webadmin::error::AdminError;
use crate::webadmin::handlers::jobs::bad_status;
use crate::webadmin::handlers::paging::{PageParams, page_envelope};
use crate::webadmin::handlers::params::empty_is_absent;
use crate::webadmin::session::Authenticated;
#[derive(Debug, Deserialize, Default)]
pub struct UpstreamOrderListParams {
#[serde(default, deserialize_with = "empty_is_absent")]
pub profile: Option<String>,
#[serde(default, deserialize_with = "empty_is_absent")]
pub status: Option<String>,
pub limit: Option<i64>,
pub offset: Option<i64>,
}
impl UpstreamOrderListParams {
pub fn parsed_status(&self) -> Result<Option<UpstreamOrderStatus>, UnknownStatus> {
self.status.as_deref().map(str::parse).transpose()
}
}
pub async fn list_upstream_orders(
State(state): State<AdminState>,
Query(params): Query<UpstreamOrderListParams>,
_auth: Authenticated,
) -> Result<Json<Value>, AdminError> {
let page = PageParams::from(params.limit, params.offset).resolve(&state.config);
let status = params.parsed_status().map_err(bad_status)?;
let query = UpstreamOrderQuery {
profile: params.profile,
status,
limit: page.limit,
offset: page.offset,
};
let (rows, total) = UpstreamOrder::search(&query, &state.database).await?;
let items = rows.iter().map(admin::render_upstream_order_json).collect();
Ok(Json(page_envelope(items, total, page)))
}
pub async fn get_upstream_order(
State(state): State<AdminState>,
Path(id): Path<String>,
_auth: Authenticated,
) -> Result<Json<Value>, AdminError> {
let detail = admin::load_upstream_order_detail(&id, state.database.clone())
.await?
.ok_or_else(|| AdminError::not_found(format!("no upstream order for local order {id}")))?;
Ok(Json(admin::render_upstream_order_detail_json(&detail)))
}