gitdataai/lib/api/src/workspace/workspace.rs
2026-05-30 01:38:40 +08:00

170 lines
4.5 KiB
Rust

use actix_web::{HttpRequest, HttpResponse, web};
use serde::Serialize;
use service::{
AppService,
workspace::{
types::WorkspaceResponse,
workspace::{AvatarUploadResponse, CreateWorkspace, UpdateWorkspace},
},
};
use session::Session;
use crate::error::ApiError;
fn ok_json<T: Serialize>(data: T) -> Result<HttpResponse, ApiError> {
Ok(HttpResponse::Ok().json(data))
}
#[utoipa::path(
post,
path = "/api/v1/workspace",
request_body = CreateWorkspace,
responses(
(status = 200, body = WorkspaceResponse),
(status = 401, description = "Unauthorized"),
(status = 409, description = "Workspace name already exists"),
),
security(
("session" = [])
)
)]
pub async fn create_workspace(
session: Session,
service: web::Data<AppService>,
params: web::Json<CreateWorkspace>,
) -> Result<HttpResponse, ApiError> {
let data = service
.workspace_create(&session, params.into_inner())
.await?;
ok_json(data)
}
#[utoipa::path(
get,
path = "/api/v1/workspace/my",
responses(
(status = 200, body = Vec<WorkspaceResponse>),
(status = 401, description = "Unauthorized"),
),
security(
("session" = [])
)
)]
pub async fn my_workspaces(
session: Session,
service: web::Data<AppService>,
) -> Result<HttpResponse, ApiError> {
let data = service.workspace_my(&session).await?;
ok_json(data)
}
#[utoipa::path(
get,
path = "/api/v1/workspace/{wk}",
params(
("wk" = String, Path, description = "Workspace name"),
),
responses(
(status = 200, body = WorkspaceResponse),
(status = 401, description = "Unauthorized"),
(status = 404, description = "Workspace not found"),
),
security(
("session" = [])
)
)]
pub async fn get_workspace(
session: Session,
service: web::Data<AppService>,
path: web::Path<String>,
) -> Result<HttpResponse, ApiError> {
let wk = path.into_inner();
let data = service.workspace_get(&session, &wk).await?;
ok_json(data)
}
#[utoipa::path(
put,
path = "/api/v1/workspace/{wk}",
params(
("wk" = String, Path, description = "Workspace name"),
),
request_body = UpdateWorkspace,
responses(
(status = 200, body = WorkspaceResponse),
(status = 401, description = "Unauthorized"),
(status = 403, description = "Permission denied"),
(status = 404, description = "Workspace not found"),
),
security(
("session" = [])
)
)]
pub async fn update_workspace(
session: Session,
service: web::Data<AppService>,
path: web::Path<String>,
params: web::Json<UpdateWorkspace>,
) -> Result<HttpResponse, ApiError> {
let wk = path.into_inner();
let data = service
.workspace_update(&session, &wk, params.into_inner())
.await?;
ok_json(data)
}
#[utoipa::path(
get,
path = "/api/v1/workspace/{wk}/avatar",
params(
("wk" = String, Path, description = "Workspace name"),
),
responses(
(status = 302, description = "Redirect to avatar image URL"),
(status = 404, description = "Workspace or avatar not found"),
),
tag = "workspace"
)]
pub async fn get_avatar(
service: web::Data<AppService>,
path: web::Path<String>,
) -> Result<HttpResponse, ApiError> {
let wk = path.into_inner();
let url = service.workspace_get_avatar_url(&wk).await?;
Ok(HttpResponse::Found()
.insert_header(("Location", url))
.finish())
}
#[utoipa::path(
post,
path = "/api/v1/workspace/{wk}/avatar",
params(
("wk" = String, Path, description = "Workspace name"),
),
request_body(content = Vec<u8>, content_type = "image/*"),
responses(
(status = 200, body = AvatarUploadResponse),
(status = 400, description = "Invalid file type or size"),
(status = 403, description = "Permission denied"),
),
security(
("session" = [])
)
)]
pub async fn upload_avatar(
session: Session,
service: web::Data<AppService>,
path: web::Path<String>,
body: web::Bytes,
req: HttpRequest,
) -> Result<HttpResponse, ApiError> {
let wk = path.into_inner();
let content_type = req
.headers()
.get("content-type")
.and_then(|v| v.to_str().ok())
.unwrap_or("application/octet-stream");
let response = service
.workspace_upload_avatar(&session, &wk, body.to_vec(), content_type)
.await?;
ok_json(response)
}