feat: add presentation layer + bootstrap wiring for vertical slice

This commit is contained in:
2026-05-31 05:51:09 +02:00
parent 8c1a0e4519
commit 201eff717d
21 changed files with 726 additions and 51 deletions

View File

@@ -0,0 +1,72 @@
use crate::{errors::AppError, extractors::JwtClaims, state::AppState};
use api_types::{
requests::{AlbumEntryRequest, CreateAlbumRequest},
responses::AlbumResponse,
};
use application::organization::{
AlbumAction, CreateAlbumCommand, GetAlbumQuery, ManageAlbumEntriesCommand,
};
use axum::{
Json,
extract::{Path, State},
http::StatusCode,
};
use domain::value_objects::SystemId;
pub async fn create_album(
State(state): State<AppState>,
claims: JwtClaims,
Json(req): Json<CreateAlbumRequest>,
) -> Result<(StatusCode, Json<AlbumResponse>), AppError> {
let cmd = CreateAlbumCommand {
title: req.title,
creator_id: claims.user_id,
};
let album = state.create_album_handler.execute(cmd).await?;
Ok((StatusCode::CREATED, Json(AlbumResponse::from_domain(&album))))
}
pub async fn get_album(
State(state): State<AppState>,
_claims: JwtClaims,
Path((album_id,)): Path<(uuid::Uuid,)>,
) -> Result<Json<AlbumResponse>, AppError> {
let query = GetAlbumQuery {
album_id: SystemId::from_uuid(album_id),
};
let album = state.get_album_handler.execute(query).await?;
Ok(Json(AlbumResponse::from_domain(&album)))
}
pub async fn add_entry(
State(state): State<AppState>,
claims: JwtClaims,
Path((album_id,)): Path<(uuid::Uuid,)>,
Json(req): Json<AlbumEntryRequest>,
) -> Result<(StatusCode, Json<AlbumResponse>), AppError> {
let cmd = ManageAlbumEntriesCommand {
album_id: SystemId::from_uuid(album_id),
action: AlbumAction::Add {
asset_id: SystemId::from_uuid(req.asset_id),
},
user_id: claims.user_id,
};
let album = state.manage_album_entries_handler.execute(cmd).await?;
Ok((StatusCode::OK, Json(AlbumResponse::from_domain(&album))))
}
pub async fn remove_entry(
State(state): State<AppState>,
claims: JwtClaims,
Path((album_id, asset_id)): Path<(uuid::Uuid, uuid::Uuid)>,
) -> Result<Json<AlbumResponse>, AppError> {
let cmd = ManageAlbumEntriesCommand {
album_id: SystemId::from_uuid(album_id),
action: AlbumAction::Remove {
asset_id: SystemId::from_uuid(asset_id),
},
user_id: claims.user_id,
};
let album = state.manage_album_entries_handler.execute(cmd).await?;
Ok(Json(AlbumResponse::from_domain(&album)))
}