mabel/src/routes/collections.rs

106 lines
2.9 KiB
Rust

use axum::{
extract::{Path, Query},
response::IntoResponse,
routing::get,
Json, Router,
};
use std::sync::Arc;
use uuid::Uuid;
use crate::{
content::{collection::CollectionRepository, post::PostRepository, site::SiteRepository},
database::Database,
http::error::ApiError,
state::AppState,
};
use super::pagination::TimePaginationQuery;
const DEFAULT_PAGE_SIZE: i64 = 10;
pub(super) async fn create_collection<Repo: CollectionRepository>(repository: Repo) {
todo!()
}
pub(super) async fn get_collection<Repo: CollectionRepository>(repository: Repo) {
todo!()
}
/// List all collections in a site
#[utoipa::path(
get,
path = "/collections/{site}",
params(
("site" = String, Path, description = "Site slug")
),
responses(
(status = 200, description = "List of collections fetched", body = [CollectionData])
)
)]
pub(super) async fn list_collections_for_site<Repo: SiteRepository + CollectionRepository>(
repository: Repo,
Path(site): Path<String>,
) -> Result<impl IntoResponse, ApiError<'static>> {
let (site_id, _) = repository.get_site_id_and_owner(&site).await?;
Ok(Json(repository.list_collections(&site_id).await?))
}
pub(super) async fn update_collection<Repo: CollectionRepository>(repository: Repo) {
todo!()
}
pub(super) async fn delete_collection<Repo: CollectionRepository>(repository: Repo) {
todo!()
}
/// List posts within a collection (paginated)
#[utoipa::path(
get,
path = "/collections/{site}/{id}/posts",
params(
("site" = String, Path, description = "Site slug"),
("id" = Uuid, Path, description = "Collection ID"),
TimePaginationQuery
),
responses(
(status = 200, description = "List of collections fetched", body = [CollectionData])
)
)]
pub(super) async fn list_posts_in_collection<Repo: SiteRepository + PostRepository>(
repository: Repo,
Path((site, id)): Path<(String, Uuid)>,
query: Query<TimePaginationQuery>,
) -> Result<impl IntoResponse, ApiError<'static>> {
// Resolve site
let (site_id, _) = repository.get_site_id_and_owner(&site).await?;
let results = repository
.list_posts_in_collection(
&site_id,
&id,
query.before,
query.limit.unwrap_or(DEFAULT_PAGE_SIZE),
)
.await?;
Ok(Json(results))
}
pub(super) fn router() -> Router<Arc<AppState>> {
Router::new()
.route(
"/:site",
get(list_collections_for_site::<Database>).post(create_collection::<Database>),
)
.route(
"/:site/:id",
get(get_collection::<Database>)
.put(update_collection::<Database>)
.delete(delete_collection::<Database>),
)
.route(
"/:site/:id/posts",
get(list_posts_in_collection::<Database>),
)
}