init
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
use crate::domain::dto::category::CategoryResponse;
|
||||
use crate::domain::dto::channel::ChannelResponse;
|
||||
use chrono::{DateTime, Utc};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use utoipa::ToSchema;
|
||||
@@ -50,3 +52,14 @@ pub struct ServerRolePermissionResponse {
|
||||
pub role_id: Uuid,
|
||||
pub permissions: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, ToSchema)]
|
||||
pub enum ServerExplorerItemResponse {
|
||||
Category(CategoryResponse, Vec<ChannelResponse>),
|
||||
Channel(ChannelResponse),
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, ToSchema)]
|
||||
pub struct ServerTreeResponse {
|
||||
pub items: Vec<ServerExplorerItemResponse>,
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ use utoipa::{Modify, OpenApi};
|
||||
server::handlers::create,
|
||||
server::handlers::update,
|
||||
server::handlers::delete,
|
||||
server::handlers::get_tree,
|
||||
category::handlers::get_all,
|
||||
category::handlers::get_by_id,
|
||||
category::handlers::create,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use crate::core::state::AppState;
|
||||
use crate::http::context::Superuser;
|
||||
use crate::http::error::HTTPError;
|
||||
use crate::repositories::types::{ChannelFilter, ServerTree};
|
||||
use crate::domain::dto::server::{
|
||||
CreateServerRequest, ServerResponse, ServerRolePermissionResponse,
|
||||
CreateServerRequest, ServerResponse, ServerRolePermissionResponse, ServerTreeResponse,
|
||||
ServerUserPermissionResponse, SetServerPermissionRequest, UpdateServerRequest,
|
||||
};
|
||||
use crate::http::context::Superuser;
|
||||
use crate::http::error::HTTPError;
|
||||
use crate::repositories::types::ChannelFilter;
|
||||
use crate::routes::server::mapper;
|
||||
use axum::{
|
||||
Json,
|
||||
@@ -83,7 +83,11 @@ pub async fn create(
|
||||
State(state): State<AppState>,
|
||||
Json(payload): Json<CreateServerRequest>,
|
||||
) -> Result<(StatusCode, Json<ServerResponse>), HTTPError> {
|
||||
let server = state.services.server.create_server(payload.name, payload.is_default).await?;
|
||||
let server = state
|
||||
.services
|
||||
.server
|
||||
.create_server(payload.name, payload.is_default)
|
||||
.await?;
|
||||
Ok((
|
||||
StatusCode::CREATED,
|
||||
Json(mapper::server_model_to_server_response(server)),
|
||||
@@ -122,7 +126,11 @@ pub async fn update(
|
||||
.await?
|
||||
.ok_or(HTTPError::NotFound)?;
|
||||
|
||||
let server = state.services.server.update_server(id, payload.name, payload.is_default).await?;
|
||||
let server = state
|
||||
.services
|
||||
.server
|
||||
.update_server(id, payload.name, payload.is_default)
|
||||
.await?;
|
||||
|
||||
Ok(Json(mapper::server_model_to_server_response(server)))
|
||||
}
|
||||
@@ -364,39 +372,42 @@ pub async fn remove_role_permission(
|
||||
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/servers/{id}/tree",
|
||||
path = "/servers/{server_id}/tree",
|
||||
responses(
|
||||
(status = 200, description = "Arborescence du serveur récupérée avec succès"),
|
||||
(status = 404, description = "Serveur introuvable"),
|
||||
(status = 500, description = "Erreur interne du serveur")
|
||||
),
|
||||
params(
|
||||
("id" = Uuid, Path, description = "ID du serveur")
|
||||
("server_id" = Uuid, Path, description = "ID du serveur")
|
||||
),
|
||||
tag = "Servers"
|
||||
)]
|
||||
pub async fn get_server_tree(
|
||||
pub async fn get_tree(
|
||||
State(state): State<AppState>,
|
||||
Path(id): Path<Uuid>,
|
||||
) -> Result<Json<ServerTree>, HTTPError> {
|
||||
Path(server_id): Path<Uuid>,
|
||||
) -> Result<Json<ServerTreeResponse>, HTTPError> {
|
||||
// Vérifier l'existence du serveur
|
||||
state
|
||||
.repositories
|
||||
.server
|
||||
.get_by_id(id)
|
||||
.get_by_id(server_id)
|
||||
.await?
|
||||
.ok_or(HTTPError::NotFound)?;
|
||||
|
||||
// Exécution parallèle des 3 requêtes via leurs repositories respectifs
|
||||
let (orders, channels, categories) = tokio::try_join!(
|
||||
state.repositories.server_item_order.get_by_server(id),
|
||||
state
|
||||
.repositories
|
||||
.server_item_order
|
||||
.get_by_server(server_id),
|
||||
state.repositories.channel.filter(ChannelFilter {
|
||||
server_id: Some(id)
|
||||
server_id: Some(server_id)
|
||||
}),
|
||||
state.repositories.category.get_by_server(id),
|
||||
state.repositories.category.get_by_server(server_id),
|
||||
)?;
|
||||
|
||||
// Assemblage du ServerTree via le mapper
|
||||
// Assemblage du ServerTreeResponse via le mapper
|
||||
let tree = mapper::build_server_tree(orders, channels, categories);
|
||||
|
||||
Ok(Json(tree))
|
||||
|
||||
+25
-10
@@ -1,11 +1,12 @@
|
||||
use crate::domain::dto::server::{
|
||||
CreateServerRequest, ServerExplorerItemResponse, ServerResponse, ServerRolePermissionResponse,
|
||||
ServerTreeResponse, ServerUserPermissionResponse, UpdateServerRequest,
|
||||
};
|
||||
use crate::models::{
|
||||
category, channel, server, server_item_order, server_role_permission, server_user_permission,
|
||||
};
|
||||
use crate::repositories::types::{ServerExplorerItem, ServerTree};
|
||||
use crate::domain::dto::server::{
|
||||
CreateServerRequest, ServerResponse, ServerRolePermissionResponse,
|
||||
ServerUserPermissionResponse, UpdateServerRequest,
|
||||
};
|
||||
use crate::routes::category::mapper::category_model_to_category_response;
|
||||
use crate::routes::channel::mapper::channel_model_to_channel_response;
|
||||
use sea_orm::Set;
|
||||
use std::collections::HashMap;
|
||||
use uuid::Uuid;
|
||||
@@ -66,7 +67,7 @@ pub fn build_server_tree(
|
||||
orders: Vec<server_item_order::Model>,
|
||||
channels: Vec<channel::Model>,
|
||||
categories: Vec<category::Model>,
|
||||
) -> ServerTree {
|
||||
) -> ServerTreeResponse {
|
||||
// Map d'accès rapide : resource_id -> order_key
|
||||
let order_map: HashMap<Uuid, i64> = orders
|
||||
.into_iter()
|
||||
@@ -91,18 +92,32 @@ pub fn build_server_tree(
|
||||
}
|
||||
|
||||
// Préparer les éléments racine (catégories & canaux orphelins) avec leur order_key
|
||||
let mut root_items: Vec<(ServerExplorerItem, i64)> = Vec::new();
|
||||
let mut root_items: Vec<(ServerExplorerItemResponse, i64)> = Vec::new();
|
||||
|
||||
for cat in categories {
|
||||
let cat_id = cat.id;
|
||||
let order_key = order_map.get(&cat_id).copied().unwrap_or(i64::MAX);
|
||||
let chans = category_channels.remove(&cat_id).unwrap_or_default();
|
||||
root_items.push((ServerExplorerItem::Category(cat, chans), order_key));
|
||||
|
||||
let cat_response = category_model_to_category_response(cat);
|
||||
let chan_responses = chans
|
||||
.into_iter()
|
||||
.map(channel_model_to_channel_response)
|
||||
.collect();
|
||||
|
||||
root_items.push((
|
||||
ServerExplorerItemResponse::Category(cat_response, chan_responses),
|
||||
order_key,
|
||||
));
|
||||
}
|
||||
|
||||
for chan in orphan_channels {
|
||||
let order_key = order_map.get(&chan.id).copied().unwrap_or(i64::MAX);
|
||||
root_items.push((ServerExplorerItem::Channel(chan), order_key));
|
||||
let chan_response = channel_model_to_channel_response(chan);
|
||||
root_items.push((
|
||||
ServerExplorerItemResponse::Channel(chan_response),
|
||||
order_key,
|
||||
));
|
||||
}
|
||||
|
||||
// Tri du niveau racine par order_key
|
||||
@@ -110,5 +125,5 @@ pub fn build_server_tree(
|
||||
|
||||
let items = root_items.into_iter().map(|(item, _)| item).collect();
|
||||
|
||||
ServerTree { items }
|
||||
ServerTreeResponse { items }
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use super::handlers;
|
||||
use crate::core::state::AppState;
|
||||
use axum::{routing::get, Router};
|
||||
use axum::{Router, routing::get};
|
||||
|
||||
pub fn router() -> Router<AppState> {
|
||||
Router::new()
|
||||
@@ -11,6 +11,7 @@ pub fn router() -> Router<AppState> {
|
||||
.put(handlers::update)
|
||||
.delete(handlers::delete),
|
||||
)
|
||||
.route("/servers/{server_id}/tree", get(handlers::get_tree))
|
||||
.route(
|
||||
"/servers/{server_id}/permissions/users/{user_id}",
|
||||
get(handlers::get_user_permission)
|
||||
|
||||
Reference in New Issue
Block a user