feat: frontend-ready backend — pagination, auto-derivatives, list endpoints, bulk ops, OpenAPI

Pagination: count_by_owner + count_search on AssetRepository,
timeline/search return real total count (not page len).

Auto-derivatives: worker enqueues GenerateDerivative when
ExtractMetadata job completes, closing the upload→thumbnail gap.

List endpoints: GET /albums, GET /stacks with user scoping.
ListAlbumsHandler, ListStacksHandler, find_by_owner on AssetStackRepository.

Tag filtering: tag_name field on AssetFilters, JOIN asset_tags+tags
in postgres search/count queries.

Bulk operations: POST /assets/bulk-delete, POST /assets/bulk-tag.

Album update: PUT /albums/{id} with UpdateAlbumHandler (title, description).

OpenAPI: utoipa annotations on all 47 endpoints + all request/response
schemas registered. Scalar UI at /scalar covers full API.
This commit is contained in:
2026-05-31 23:06:25 +02:00
parent bcaf49cc81
commit 7b5bb66b37
33 changed files with 1048 additions and 72 deletions

View File

@@ -4,15 +4,16 @@ use application::{
catalog::{
CreateStackHandler, DeleteAssetHandler, DeleteStackHandler, DetectLivePhotosHandler,
GetAssetHandler, GetStackHandler, GetTimelineHandler, ListDuplicatesHandler,
ReadAssetFileHandler, ReadDerivativeHandler, RegisterAssetHandler, ResolveDuplicateHandler,
SearchAssetsHandler, UpdateMetadataHandler,
ListStacksHandler, ReadAssetFileHandler, ReadDerivativeHandler, RegisterAssetHandler,
ResolveDuplicateHandler, SearchAssetsHandler, UpdateMetadataHandler,
},
identity::{
GetProfileHandler, LoginUserHandler, LogoutHandler, RefreshTokenHandler,
RegisterUserHandler,
},
organization::{
CreateAlbumHandler, GetAlbumHandler, ManageAlbumEntriesHandler, TagAssetHandler,
CreateAlbumHandler, GetAlbumHandler, ListAlbumsHandler, ManageAlbumEntriesHandler,
TagAssetHandler, UpdateAlbumHandler,
},
processing::{
CompleteJobHandler, ConfigurePipelineHandler, EnqueueJobHandler, FailJobHandler,
@@ -59,13 +60,16 @@ pub struct CatalogHandlers {
pub get_stack: Arc<GetStackHandler>,
pub delete_stack: Arc<DeleteStackHandler>,
pub detect_live_photos: Arc<DetectLivePhotosHandler>,
pub list_stacks: Arc<ListStacksHandler>,
}
#[derive(Clone)]
pub struct OrganizationHandlers {
pub create_album: Arc<CreateAlbumHandler>,
pub get_album: Arc<GetAlbumHandler>,
pub list_albums: Arc<ListAlbumsHandler>,
pub manage_album_entries: Arc<ManageAlbumEntriesHandler>,
pub update_album: Arc<UpdateAlbumHandler>,
pub tag_asset: Arc<TagAssetHandler>,
}