wsb 0.164.718

Workspace - A tool suite for file operations, version management, and development workflow automation
use crate::prelude::*;
use axum::{
    extract::{Path, State},
    http::StatusCode,
    Json,
};

use super::sessions::ErrorResponse;
use crate::web::state::WebState;

pub async fn list_all_pins(
    State(state): State<WebState>,
) -> Result<Json<serde_json::Value>, (StatusCode, Json<ErrorResponse>)> {
    let db = state.db.clone();

    let pins = tokio::task::spawn_blocking(move || {
        db.session_repo.list_all_pins()
    }).await.unwrap_or_else(|e| Err(anyhow::anyhow!("join error: {}", e)))
    .map_err(|e| {
        (
            StatusCode::INTERNAL_SERVER_ERROR,
            Json(ErrorResponse {
                error: e.to_string(),
            }),
        )
    })?;
    Ok(Json(serde_json::json!({ "pins": pins })))
}

pub async fn list_session_pins(
    State(state): State<WebState>,
    Path(id): Path<String>,
) -> Result<Json<serde_json::Value>, (StatusCode, Json<ErrorResponse>)> {
    let db = state.db.clone();
    let id_clone = id.clone();

    let pins = tokio::task::spawn_blocking(move || {
        db.session_repo.list_session_pins(&id_clone)
    }).await.unwrap_or_else(|e| Err(anyhow::anyhow!("join error: {}", e)))
    .map_err(|e| {
        (
            StatusCode::INTERNAL_SERVER_ERROR,
            Json(ErrorResponse {
                error: e.to_string(),
            }),
        )
    })?;
    Ok(Json(serde_json::json!({ "pins": pins })))
}

#[derive(Deserialize)]
pub struct PinRequest {
    pub note: Option<String>,
}

pub async fn pin_message(
    State(state): State<WebState>,
    Path((session_id, message_id)): Path<(String, i64)>,
    Json(body): Json<PinRequest>,
) -> Result<(StatusCode, Json<serde_json::Value>), (StatusCode, Json<ErrorResponse>)> {
    let db = state.db.clone();

    let pin_id = tokio::task::spawn_blocking({
        let session_id = session_id.clone();
        move || {
            db.session_repo.pin_message(&session_id, message_id, body.note.as_deref())
        }
    }).await.unwrap_or_else(|e| Err(anyhow::anyhow!("join error: {}", e)))
    .map_err(|e| {
        (
            StatusCode::BAD_REQUEST,
            Json(ErrorResponse {
                error: e.to_string(),
            }),
        )
    })?;

    Ok((
        StatusCode::CREATED,
        Json(serde_json::json!({ "id": pin_id })),
    ))
}

pub async fn unpin_message(
    State(state): State<WebState>,
    Path((session_id, message_id)): Path<(String, i64)>,
) -> Result<StatusCode, (StatusCode, Json<ErrorResponse>)> {
    let db = state.db.clone();

    tokio::task::spawn_blocking({
        let session_id = session_id.clone();
        move || db.session_repo.unpin_message(&session_id, message_id)
    }).await.unwrap_or_else(|e| Err(anyhow::anyhow!("join error: {}", e)))
    .map_err(|e| {
        (
            StatusCode::INTERNAL_SERVER_ERROR,
            Json(ErrorResponse {
                error: e.to_string(),
            }),
        )
    })?;
    Ok(StatusCode::NO_CONTENT)
}