Backend: - user roles (DB + JWT + first-user-is-admin) - volume-aware file resolver (multi-volume asset serving) - directory scanner uses volume URI directly - date-summary endpoint (capture date from EXIF) - timeline ordered by capture date - list endpoints: volumes, plugins, pipelines, library paths - delete endpoints: volumes, library paths - configurable upload body limit (MAX_UPLOAD_BYTES) Frontend: - auth: login/register, token refresh, role-based admin gate - timeline: date-grouped grid, infinite scroll, date scrubber - image viewer: fullscreen zoom/pan/pinch, metadata sidebar - upload: drag-drop, sequential upload, progress tracking - albums: create, add/remove photos, asset picker dialog - admin: storage (import library), jobs (pagination, error details), plugins (list + toggle), pipelines, sidecars, duplicates - multi-select mode with add-to-album action - TanStack Query for all data fetching
159 lines
2.6 KiB
TypeScript
159 lines
2.6 KiB
TypeScript
export interface UserResponse {
|
|
id: string
|
|
username: string
|
|
email: string
|
|
role: string
|
|
created_at: string
|
|
}
|
|
|
|
export interface AuthResponse {
|
|
token: string
|
|
refresh_token: string
|
|
user: UserResponse
|
|
}
|
|
|
|
export interface AssetResponse {
|
|
id: string
|
|
asset_type: string
|
|
mime_type: string
|
|
file_size: number
|
|
is_processed: boolean
|
|
created_at: string
|
|
metadata: Record<string, unknown>
|
|
}
|
|
|
|
export interface TimelineResponse {
|
|
assets: AssetResponse[]
|
|
total: number
|
|
}
|
|
|
|
export interface DateCountEntry {
|
|
date: string
|
|
count: number
|
|
}
|
|
|
|
export interface DateSummaryResponse {
|
|
dates: DateCountEntry[]
|
|
}
|
|
|
|
export interface AlbumResponse {
|
|
id: string
|
|
title: string
|
|
description: string
|
|
creator_id: string
|
|
asset_count: number
|
|
asset_ids: string[]
|
|
created_at: string
|
|
}
|
|
|
|
export interface IngestResponse {
|
|
asset: AssetResponse
|
|
session_id: string
|
|
}
|
|
|
|
export interface LoginRequest {
|
|
email: string
|
|
password: string
|
|
}
|
|
|
|
export interface RegisterRequest {
|
|
username: string
|
|
email: string
|
|
password: string
|
|
}
|
|
|
|
export interface CreateAlbumRequest {
|
|
title: string
|
|
}
|
|
|
|
export interface UpdateAlbumRequest {
|
|
title?: string
|
|
description?: string
|
|
}
|
|
|
|
// --- Storage Admin ---
|
|
|
|
export interface VolumeResponse {
|
|
id: string
|
|
volume_name: string
|
|
uri_prefix: string
|
|
is_writable: boolean
|
|
}
|
|
|
|
export interface LibraryPathResponse {
|
|
id: string
|
|
volume_id: string
|
|
relative_path: string
|
|
is_ingest_destination: boolean
|
|
}
|
|
|
|
// --- Processing ---
|
|
|
|
export interface JobResponse {
|
|
job_id: string
|
|
job_type: string
|
|
status: string
|
|
priority: number
|
|
created_at: string
|
|
error_message: string | null
|
|
}
|
|
|
|
export interface JobListResponse {
|
|
jobs: JobResponse[]
|
|
total: number
|
|
}
|
|
|
|
export interface BatchProgressResponse {
|
|
batch_id: string
|
|
batch_type: string
|
|
total: number
|
|
completed: number
|
|
failed: number
|
|
status: string
|
|
jobs: JobResponse[]
|
|
}
|
|
|
|
export interface PluginResponse {
|
|
plugin_id: string
|
|
name: string
|
|
plugin_type: string
|
|
is_enabled: boolean
|
|
}
|
|
|
|
export interface PipelineResponse {
|
|
pipeline_id: string
|
|
trigger_event: string
|
|
steps_count: number
|
|
}
|
|
|
|
// --- Sidecars ---
|
|
|
|
export interface SidecarExportResponse {
|
|
asset_id: string
|
|
status: string
|
|
path: string
|
|
}
|
|
|
|
export interface DetectChangesResponse {
|
|
changed_count: number
|
|
}
|
|
|
|
export interface SidecarImportResponse {
|
|
asset_id: string
|
|
status: string
|
|
}
|
|
|
|
// --- Duplicates ---
|
|
|
|
export interface DuplicateGroupResponse {
|
|
group_id: string
|
|
detection_method: string
|
|
status: string
|
|
candidates: DuplicateCandidateResponse[]
|
|
}
|
|
|
|
export interface DuplicateCandidateResponse {
|
|
asset_id: string
|
|
similarity_score: number
|
|
}
|