pub mod backend; pub mod handlers; pub mod tus; use axum::{extract::DefaultBodyLimit, routing::{delete, get, post, patch}, Router}; use common::Config; use handlers::StorageState; use sqlx::PgPool; use std::sync::Arc; use crate::backend::{AwsS3Backend, StorageBackend}; pub async fn init(db: PgPool, config: Config) -> Router { // Initialize S3 Backend let backend: Arc = Arc::new( AwsS3Backend::new(&config).await.expect("Failed to init storage backend") ); let bucket_name = config.s3_bucket.clone(); // Create bucket if not exists let _ = backend.create_bucket(&bucket_name).await; let state = StorageState { db, backend, config, bucket_name }; Router::new() // Health check .route("/health", get(handlers::health_check)) // Bucket operations .route("/bucket", get(handlers::list_buckets).post(handlers::create_bucket)) .route("/bucket/:bucket_id", delete(handlers::delete_bucket)) // Object operations .route("/object/list/:bucket_id", post(handlers::list_objects)) .route( "/object/sign/:bucket_id/*filename", post(handlers::sign_object).get(handlers::get_signed_object), ) .route( "/object/public/:bucket_id/*filename", get(handlers::get_public_url), ) .route( "/object/:bucket_id/*filename", get(handlers::download_object).post(handlers::upload_object).delete(handlers::delete_object), ) // Copy and move operations .route("/object/copy", post(handlers::copy_object)) .route("/object/move", post(handlers::move_object)) // TUS Resumable Uploads .route("/upload/resumable", post(tus::tus_create_upload).options(tus::tus_options)) .route("/upload/resumable/:upload_id", patch(tus::tus_patch_upload) .head(tus::tus_head_upload) .options(tus::tus_options) ) .layer(DefaultBodyLimit::max(1024 * 1024 * 1024)) // 1GB limit for TUS .with_state(state) }