feat: wire remaining handlers — tag, quota, register asset, sidecar, processing
14 new endpoints: POST tags, GET quota, POST register, 6 sidecar, 7 processing. DTOs, AppState groups, LogSidecarWriter, full bootstrap wiring.
This commit is contained in:
@@ -4,9 +4,16 @@ use crate::{
|
||||
extractors::{JwtClaims, UploadedAsset},
|
||||
state::AppState,
|
||||
};
|
||||
use api_types::responses::{AssetResponse, IngestResponse, TimelineResponse};
|
||||
use api_types::{
|
||||
requests::{RegisterAssetRequest, TagAssetRequest},
|
||||
responses::{AssetResponse, IngestResponse, TagResponse, TimelineResponse},
|
||||
};
|
||||
use application::{
|
||||
catalog::{GetAssetQuery, GetTimelineQuery, ReadAssetFileQuery, UpdateMetadataCommand},
|
||||
catalog::{
|
||||
GetAssetQuery, GetTimelineQuery, ReadAssetFileQuery, RegisterAssetCommand,
|
||||
UpdateMetadataCommand,
|
||||
},
|
||||
organization::TagAssetCommand,
|
||||
storage::IngestAssetCommand,
|
||||
};
|
||||
use axum::{
|
||||
@@ -16,7 +23,11 @@ use axum::{
|
||||
http::{StatusCode, header},
|
||||
response::Response,
|
||||
};
|
||||
use domain::value_objects::{MetadataValue, StructuredData, SystemId};
|
||||
use domain::{
|
||||
catalog::entities::AssetType,
|
||||
errors::DomainError,
|
||||
value_objects::{MetadataValue, StructuredData, SystemId},
|
||||
};
|
||||
|
||||
#[derive(Debug, serde::Deserialize)]
|
||||
pub struct TimelineParams {
|
||||
@@ -124,3 +135,51 @@ pub async fn serve_file(
|
||||
.body(Body::from(result.data))
|
||||
.map_err(|e| AppError::from(domain::errors::DomainError::Internal(e.to_string())))
|
||||
}
|
||||
|
||||
pub async fn tag_asset(
|
||||
State(state): State<AppState>,
|
||||
claims: JwtClaims,
|
||||
Path((asset_id,)): Path<(uuid::Uuid,)>,
|
||||
Json(req): Json<TagAssetRequest>,
|
||||
) -> Result<(StatusCode, Json<TagResponse>), AppError> {
|
||||
let cmd = TagAssetCommand {
|
||||
asset_id: SystemId::from_uuid(asset_id),
|
||||
tag_name: req.tag_name,
|
||||
user_id: claims.user_id,
|
||||
};
|
||||
let (tag, _asset_tag) = state.organization.tag_asset.execute(cmd).await?;
|
||||
Ok((StatusCode::CREATED, Json(TagResponse::from_domain(&tag))))
|
||||
}
|
||||
|
||||
fn parse_asset_type(s: &str) -> Result<AssetType, AppError> {
|
||||
match s {
|
||||
"image" => Ok(AssetType::Image),
|
||||
"video" => Ok(AssetType::Video),
|
||||
"live_photo" => Ok(AssetType::LivePhoto),
|
||||
_ => Err(AppError::from(DomainError::Validation(format!(
|
||||
"Invalid asset type: {s}"
|
||||
)))),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn register_asset(
|
||||
State(state): State<AppState>,
|
||||
claims: JwtClaims,
|
||||
Json(req): Json<RegisterAssetRequest>,
|
||||
) -> Result<(StatusCode, Json<AssetResponse>), AppError> {
|
||||
let asset_type = parse_asset_type(&req.asset_type)?;
|
||||
let cmd = RegisterAssetCommand {
|
||||
volume_id: SystemId::from_uuid(req.volume_id),
|
||||
relative_path: req.relative_path,
|
||||
checksum: req.checksum,
|
||||
asset_type,
|
||||
mime_type: req.mime_type,
|
||||
file_size: req.file_size,
|
||||
owner_id: claims.user_id,
|
||||
};
|
||||
let (asset, _dup_group) = state.catalog.register_asset.execute(cmd).await?;
|
||||
Ok((
|
||||
StatusCode::CREATED,
|
||||
Json(AssetResponse::from_domain(&asset, &StructuredData::new())),
|
||||
))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user