diff --git a/crates/presentation/src/routes.rs b/crates/presentation/src/routes.rs deleted file mode 100644 index a2f23ef..0000000 --- a/crates/presentation/src/routes.rs +++ /dev/null @@ -1,119 +0,0 @@ -use crate::{ - handlers::{ - albums, assets, auth, duplicates, health, processing, sharing, sidecar, stacks, storage, - }, - middleware::auth::require_auth, - openapi::openapi_router, - state::AppState, -}; -use axum::{ - Router, - middleware::from_fn_with_state, - routing::{delete, get, post, put}, -}; - -fn public_routes() -> Router { - Router::new() - .route("/auth/register", post(auth::register)) - .route("/auth/login", post(auth::login)) - .route("/auth/refresh", post(auth::refresh)) - .route("/sharing/access/{token}", get(sharing::access_by_token)) -} - -fn protected_routes(state: &AppState) -> Router { - Router::new() - // auth - .route("/auth/me", get(auth::me)) - .route("/auth/logout", post(auth::logout)) - // albums - .route( - "/albums", - get(albums::list_albums).post(albums::create_album), - ) - .route( - "/albums/{id}", - get(albums::get_album).put(albums::update_album), - ) - .route("/albums/{id}/entries", post(albums::add_entry)) - .route( - "/albums/{id}/entries/{asset_id}", - delete(albums::remove_entry), - ) - // assets - .route("/assets", get(assets::search_assets)) - .route("/assets/ingest", post(assets::ingest)) - .route("/assets/register", post(assets::register_asset)) - .route("/assets/timeline", get(assets::timeline)) - .route( - "/assets/{id}", - get(assets::get_asset).delete(assets::delete_asset), - ) - .route("/assets/{id}/metadata", put(assets::update_metadata)) - .route("/assets/{id}/file", get(assets::serve_file)) - .route( - "/assets/{id}/derivatives/{profile}", - get(assets::serve_derivative), - ) - .route("/assets/{id}/tags", post(assets::tag_asset)) - .route("/assets/bulk-delete", post(assets::bulk_delete)) - .route("/assets/bulk-tag", post(assets::bulk_tag)) - // stacks - .route( - "/stacks", - get(stacks::list_stacks).post(stacks::create_stack), - ) - .route( - "/stacks/detect-live-photos", - post(stacks::detect_live_photos), - ) - .route( - "/stacks/{id}", - get(stacks::get_stack).delete(stacks::delete_stack), - ) - // duplicates - .route("/duplicates", get(duplicates::list_duplicates)) - .route( - "/duplicates/{id}/resolve", - post(duplicates::resolve_duplicate), - ) - // sharing - .route("/sharing", post(sharing::share_resource)) - .route("/sharing/links", post(sharing::generate_link)) - .route("/sharing/{id}", delete(sharing::revoke)) - // storage - .route("/storage/volumes", post(storage::register_volume)) - .route( - "/storage/library-paths", - post(storage::register_library_path), - ) - .route("/storage/quota", get(storage::check_quota)) - // sidecar - .route("/sidecar/export/{asset_id}", post(sidecar::export_sidecar)) - .route("/sidecar/detect-changes", post(sidecar::detect_changes)) - .route("/sidecar/import/{asset_id}", post(sidecar::import_sidecar)) - .route( - "/sidecar/resolve/{asset_id}", - post(sidecar::resolve_conflict), - ) - .route("/sidecar/full-export", post(sidecar::full_export)) - .route("/sidecar/full-import", post(sidecar::full_import)) - // processing - .route( - "/jobs", - get(processing::list_jobs).post(processing::enqueue_job), - ) - .route("/jobs/{id}/start", post(processing::start_job)) - .route("/jobs/{id}/complete", post(processing::complete_job)) - .route("/jobs/{id}/fail", post(processing::fail_job)) - .route("/jobs/batches/{id}", get(processing::batch_progress)) - .route("/plugins", post(processing::manage_plugin)) - .route("/pipelines", post(processing::configure_pipeline)) - .route_layer(from_fn_with_state(state.clone(), require_auth)) -} - -pub fn app_router(state: &AppState) -> Router { - Router::new() - .route("/health", get(health::health)) - .nest("/api/v1", public_routes().merge(protected_routes(state))) - .merge(openapi_router()) -} diff --git a/crates/presentation/src/routes/auth.rs b/crates/presentation/src/routes/auth.rs new file mode 100644 index 0000000..bdee041 --- /dev/null +++ b/crates/presentation/src/routes/auth.rs @@ -0,0 +1,18 @@ +use crate::{handlers::auth, state::AppState}; +use axum::{ + Router, + routing::{get, post}, +}; + +pub fn public() -> Router { + Router::new() + .route("/auth/register", post(auth::register)) + .route("/auth/login", post(auth::login)) + .route("/auth/refresh", post(auth::refresh)) +} + +pub fn protected() -> Router { + Router::new() + .route("/auth/me", get(auth::me)) + .route("/auth/logout", post(auth::logout)) +} diff --git a/crates/presentation/src/routes/catalog.rs b/crates/presentation/src/routes/catalog.rs new file mode 100644 index 0000000..5c1d64b --- /dev/null +++ b/crates/presentation/src/routes/catalog.rs @@ -0,0 +1,46 @@ +use crate::{ + handlers::{assets, duplicates, stacks}, + state::AppState, +}; +use axum::{ + Router, + routing::{get, post, put}, +}; + +pub fn routes() -> Router { + Router::new() + .route("/assets", get(assets::search_assets)) + .route("/assets/ingest", post(assets::ingest)) + .route("/assets/register", post(assets::register_asset)) + .route("/assets/timeline", get(assets::timeline)) + .route( + "/assets/{id}", + get(assets::get_asset).delete(assets::delete_asset), + ) + .route("/assets/{id}/metadata", put(assets::update_metadata)) + .route("/assets/{id}/file", get(assets::serve_file)) + .route( + "/assets/{id}/derivatives/{profile}", + get(assets::serve_derivative), + ) + .route("/assets/{id}/tags", post(assets::tag_asset)) + .route("/assets/bulk-delete", post(assets::bulk_delete)) + .route("/assets/bulk-tag", post(assets::bulk_tag)) + .route( + "/stacks", + get(stacks::list_stacks).post(stacks::create_stack), + ) + .route( + "/stacks/detect-live-photos", + post(stacks::detect_live_photos), + ) + .route( + "/stacks/{id}", + get(stacks::get_stack).delete(stacks::delete_stack), + ) + .route("/duplicates", get(duplicates::list_duplicates)) + .route( + "/duplicates/{id}/resolve", + post(duplicates::resolve_duplicate), + ) +} diff --git a/crates/presentation/src/routes/mod.rs b/crates/presentation/src/routes/mod.rs new file mode 100644 index 0000000..23e98e9 --- /dev/null +++ b/crates/presentation/src/routes/mod.rs @@ -0,0 +1,35 @@ +mod auth; +mod catalog; +mod organization; +mod processing; +mod sharing; +mod sidecar; +mod storage; + +use crate::{ + handlers::health, middleware::auth::require_auth, openapi::openapi_router, state::AppState, +}; +use axum::{Router, middleware::from_fn_with_state, routing::get}; + +fn public_routes() -> Router { + Router::new().merge(auth::public()).merge(sharing::public()) +} + +fn protected_routes(state: &AppState) -> Router { + Router::new() + .merge(auth::protected()) + .merge(catalog::routes()) + .merge(organization::routes()) + .merge(sharing::protected()) + .merge(storage::routes()) + .merge(sidecar::routes()) + .merge(processing::routes()) + .route_layer(from_fn_with_state(state.clone(), require_auth)) +} + +pub fn app_router(state: &AppState) -> Router { + Router::new() + .route("/health", get(health::health)) + .nest("/api/v1", public_routes().merge(protected_routes(state))) + .merge(openapi_router()) +} diff --git a/crates/presentation/src/routes/organization.rs b/crates/presentation/src/routes/organization.rs new file mode 100644 index 0000000..80690f4 --- /dev/null +++ b/crates/presentation/src/routes/organization.rs @@ -0,0 +1,22 @@ +use crate::{handlers::albums, state::AppState}; +use axum::{ + Router, + routing::{delete, get, post}, +}; + +pub fn routes() -> Router { + Router::new() + .route( + "/albums", + get(albums::list_albums).post(albums::create_album), + ) + .route( + "/albums/{id}", + get(albums::get_album).put(albums::update_album), + ) + .route("/albums/{id}/entries", post(albums::add_entry)) + .route( + "/albums/{id}/entries/{asset_id}", + delete(albums::remove_entry), + ) +} diff --git a/crates/presentation/src/routes/processing.rs b/crates/presentation/src/routes/processing.rs new file mode 100644 index 0000000..69f3538 --- /dev/null +++ b/crates/presentation/src/routes/processing.rs @@ -0,0 +1,19 @@ +use crate::{handlers::processing, state::AppState}; +use axum::{ + Router, + routing::{get, post}, +}; + +pub fn routes() -> Router { + Router::new() + .route( + "/jobs", + get(processing::list_jobs).post(processing::enqueue_job), + ) + .route("/jobs/{id}/start", post(processing::start_job)) + .route("/jobs/{id}/complete", post(processing::complete_job)) + .route("/jobs/{id}/fail", post(processing::fail_job)) + .route("/jobs/batches/{id}", get(processing::batch_progress)) + .route("/plugins", post(processing::manage_plugin)) + .route("/pipelines", post(processing::configure_pipeline)) +} diff --git a/crates/presentation/src/routes/sharing.rs b/crates/presentation/src/routes/sharing.rs new file mode 100644 index 0000000..800c963 --- /dev/null +++ b/crates/presentation/src/routes/sharing.rs @@ -0,0 +1,16 @@ +use crate::{handlers::sharing, state::AppState}; +use axum::{ + Router, + routing::{delete, get, post}, +}; + +pub fn public() -> Router { + Router::new().route("/sharing/access/{token}", get(sharing::access_by_token)) +} + +pub fn protected() -> Router { + Router::new() + .route("/sharing", post(sharing::share_resource)) + .route("/sharing/links", post(sharing::generate_link)) + .route("/sharing/{id}", delete(sharing::revoke)) +} diff --git a/crates/presentation/src/routes/sidecar.rs b/crates/presentation/src/routes/sidecar.rs new file mode 100644 index 0000000..e6bdbb7 --- /dev/null +++ b/crates/presentation/src/routes/sidecar.rs @@ -0,0 +1,15 @@ +use crate::{handlers::sidecar, state::AppState}; +use axum::{Router, routing::post}; + +pub fn routes() -> Router { + Router::new() + .route("/sidecar/export/{asset_id}", post(sidecar::export_sidecar)) + .route("/sidecar/detect-changes", post(sidecar::detect_changes)) + .route("/sidecar/import/{asset_id}", post(sidecar::import_sidecar)) + .route( + "/sidecar/resolve/{asset_id}", + post(sidecar::resolve_conflict), + ) + .route("/sidecar/full-export", post(sidecar::full_export)) + .route("/sidecar/full-import", post(sidecar::full_import)) +} diff --git a/crates/presentation/src/routes/storage.rs b/crates/presentation/src/routes/storage.rs new file mode 100644 index 0000000..16937b9 --- /dev/null +++ b/crates/presentation/src/routes/storage.rs @@ -0,0 +1,15 @@ +use crate::{handlers::storage, state::AppState}; +use axum::{ + Router, + routing::{get, post}, +}; + +pub fn routes() -> Router { + Router::new() + .route("/storage/volumes", post(storage::register_volume)) + .route( + "/storage/library-paths", + post(storage::register_library_path), + ) + .route("/storage/quota", get(storage::check_quota)) +}