use wsb::prelude::*;
use axum::{extract::State, http::StatusCode, Json};
use super::fleet::{collect_repo_statuses, workspace_root_of};
use super::sessions::ErrorResponse;
use crate::web::state::WebState;
#[derive(Serialize)]
pub struct OverviewStats {
pub session_count: Option<i64>,
pub message_count: Option<i64>,
pub fleet_repo_count: i64,
pub open_issue_count: i64,
}
fn internal_error(msg: impl std::fmt::Display) -> (StatusCode, Json<ErrorResponse>) {
(
StatusCode::INTERNAL_SERVER_ERROR,
Json(ErrorResponse {
error: msg.to_string(),
}),
)
}
pub async fn get_overview_stats(
State(state): State<WebState>,
) -> Result<Json<OverviewStats>, (StatusCode, Json<ErrorResponse>)> {
let root = workspace_root_of(&state);
let fleet_repo_count = tokio::task::spawn_blocking(move || collect_repo_statuses(&root))
.await
.map_err(internal_error)?
.map_err(internal_error)?
.len() as i64;
let (session_count, message_count) = match state.place.clone() {
Some(place) => {
let db = state.sessions.clone();
let stats = tokio::task::spawn_blocking(move || db.get_stats(false, &place))
.await
.map_err(internal_error)?
.map_err(internal_error)?;
(Some(stats.session_count), Some(stats.message_count))
}
None => (None, None),
};
Ok(Json(OverviewStats {
session_count,
message_count,
fleet_repo_count,
open_issue_count: open_issue_count(&state).await?,
}))
}
async fn open_issue_count(state: &WebState) -> Result<i64, (StatusCode, Json<ErrorResponse>)> {
let github = crate::web::github::of(state)?;
let repositories = crate::web::github::repositories(state).await?;
let service = github.service.clone();
let facts = crate::web::github::blocking(move || service.overview(&repositories)).await?;
Ok(facts.values().map(|facts| facts.open_issues).sum())
}