feat: add presentation layer + bootstrap wiring for vertical slice
This commit is contained in:
@@ -4,8 +4,9 @@ version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
domain = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
uuid = { workspace = true }
|
||||
chrono = { workspace = true }
|
||||
utoipa = { workspace = true }
|
||||
domain = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
uuid = { workspace = true }
|
||||
chrono = { workspace = true }
|
||||
utoipa = { workspace = true }
|
||||
|
||||
@@ -15,3 +15,28 @@ pub struct LoginRequest {
|
||||
pub struct CreateAlbumRequest {
|
||||
pub title: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, utoipa::ToSchema)]
|
||||
pub struct AlbumEntryRequest {
|
||||
pub asset_id: uuid::Uuid,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, utoipa::ToSchema)]
|
||||
pub struct RegisterVolumeRequest {
|
||||
pub volume_name: String,
|
||||
pub uri_prefix: String,
|
||||
pub is_writable: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, utoipa::ToSchema)]
|
||||
pub struct RegisterLibraryPathRequest {
|
||||
pub volume_id: uuid::Uuid,
|
||||
pub relative_path: String,
|
||||
pub owner_id: uuid::Uuid,
|
||||
pub is_ingest_destination: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, utoipa::ToSchema)]
|
||||
pub struct UpdateMetadataRequest {
|
||||
pub data: std::collections::HashMap<String, serde_json::Value>,
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ pub struct AlbumResponse {
|
||||
pub title: String,
|
||||
pub description: String,
|
||||
pub creator_id: Uuid,
|
||||
pub asset_count: usize,
|
||||
pub created_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
@@ -42,7 +43,109 @@ impl AlbumResponse {
|
||||
title: album.title.clone(),
|
||||
description: album.description.clone(),
|
||||
creator_id: *album.creator_user_id.as_uuid(),
|
||||
asset_count: album.asset_count(),
|
||||
created_at: *album.created_at.as_datetime(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Serialize, utoipa::ToSchema)]
|
||||
pub struct AssetResponse {
|
||||
pub id: Uuid,
|
||||
pub asset_type: String,
|
||||
pub mime_type: String,
|
||||
pub file_size: u64,
|
||||
pub is_processed: bool,
|
||||
pub created_at: DateTime<Utc>,
|
||||
pub metadata: std::collections::HashMap<String, serde_json::Value>,
|
||||
}
|
||||
|
||||
impl AssetResponse {
|
||||
pub fn from_domain(
|
||||
asset: &domain::entities::Asset,
|
||||
metadata: &domain::value_objects::StructuredData,
|
||||
) -> Self {
|
||||
let meta_map = metadata
|
||||
.inner()
|
||||
.iter()
|
||||
.map(|(k, v)| {
|
||||
let json_val = match v {
|
||||
domain::value_objects::MetadataValue::String(s) => {
|
||||
serde_json::Value::String(s.clone())
|
||||
}
|
||||
domain::value_objects::MetadataValue::Integer(i) => {
|
||||
serde_json::json!(*i)
|
||||
}
|
||||
domain::value_objects::MetadataValue::Float(f) => {
|
||||
serde_json::json!(*f)
|
||||
}
|
||||
domain::value_objects::MetadataValue::Boolean(b) => {
|
||||
serde_json::Value::Bool(*b)
|
||||
}
|
||||
domain::value_objects::MetadataValue::Null => serde_json::Value::Null,
|
||||
};
|
||||
(k.clone(), json_val)
|
||||
})
|
||||
.collect();
|
||||
|
||||
Self {
|
||||
id: *asset.asset_id.as_uuid(),
|
||||
asset_type: format!("{:?}", asset.asset_type),
|
||||
mime_type: asset.mime_type.clone(),
|
||||
file_size: asset.file_size,
|
||||
is_processed: asset.is_processed,
|
||||
created_at: *asset.created_at.as_datetime(),
|
||||
metadata: meta_map,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Serialize, utoipa::ToSchema)]
|
||||
pub struct TimelineResponse {
|
||||
pub assets: Vec<AssetResponse>,
|
||||
pub total: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Serialize, utoipa::ToSchema)]
|
||||
pub struct VolumeResponse {
|
||||
pub id: Uuid,
|
||||
pub volume_name: String,
|
||||
pub uri_prefix: String,
|
||||
pub is_writable: bool,
|
||||
}
|
||||
|
||||
impl VolumeResponse {
|
||||
pub fn from_domain(volume: &domain::entities::StorageVolume) -> Self {
|
||||
Self {
|
||||
id: *volume.volume_id.as_uuid(),
|
||||
volume_name: volume.volume_name.clone(),
|
||||
uri_prefix: volume.uri_prefix.clone(),
|
||||
is_writable: volume.is_writable,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Serialize, utoipa::ToSchema)]
|
||||
pub struct LibraryPathResponse {
|
||||
pub id: Uuid,
|
||||
pub volume_id: Uuid,
|
||||
pub relative_path: String,
|
||||
pub is_ingest_destination: bool,
|
||||
}
|
||||
|
||||
impl LibraryPathResponse {
|
||||
pub fn from_domain(path: &domain::entities::LibraryPath) -> Self {
|
||||
Self {
|
||||
id: *path.path_id.as_uuid(),
|
||||
volume_id: *path.volume_id.as_uuid(),
|
||||
relative_path: path.relative_path.clone(),
|
||||
is_ingest_destination: path.is_ingest_destination,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Serialize, utoipa::ToSchema)]
|
||||
pub struct IngestResponse {
|
||||
pub asset: AssetResponse,
|
||||
pub session_id: Uuid,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user