- Extract series code from books.rs into dedicated series.rs module
- Reorganize OpenAPI tags: split overloaded "books" tag into books, series, search, stats
- Add missing endpoints to OpenAPI: metadata_batch, metadata_refresh, komga, update_metadata_provider
- Add missing schemas: MissingVolumeInput, Komga/Batch/Refresh DTOs
- Fix access control: move GET /libraries and POST /libraries/:id/scan to read routes
so non-admin tokens can list libraries and trigger scans
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Eliminates N+1 sequential fetchSeries calls on the libraries page by
returning series count and up to 5 thumbnail book IDs (one per series)
directly from GET /libraries.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add "Deep rescan" job type that clears directory mtimes to force
re-walking all directories, discovering newly supported formats (e.g.
EPUB) without deleting existing data or metadata.
Also improve full rebuild button: red destructive styling instead of
warning, and FR description explicitly mentions metadata/reading status
loss. Rename FR rebuild label to "Mise à jour".
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add metadata_refresh_mode (manual/hourly/daily/weekly) to libraries,
with automatic scheduling via the indexer. Includes API support,
backoffice UI controls, i18n translations, and DB migration.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add metadata_batch job type with background processing via tokio::spawn
- Auto-apply metadata only when single result at 100% confidence
- Support primary + fallback provider per library, "none" to opt out
- Add batch report/results API endpoints and job detail UI
- Add series_status and has_missing filters to both series listing pages
- Add GET /series/statuses endpoint for dynamic filter options
- Normalize series_metadata status values (migration 0036)
- Hide ComicVine provider tab when no API key configured
- Translate entire backoffice UI from English to French
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a complete metadata synchronization system allowing users to search
and sync series/book metadata from external providers (Google Books,
Open Library, ComicVine, AniList, Bédéthèque). Each library can use a
different provider. Matching requires manual approval with detailed sync
reports showing what was updated or skipped (locked fields protection).
Key changes:
- DB migrations: external_metadata_links, external_book_metadata tables,
library metadata_provider column, locked_fields, total_volumes, book
metadata fields (summary, isbn, publish_date)
- Rust API: MetadataProvider trait + 5 provider implementations,
7 metadata endpoints (search, match, approve, reject, links, missing,
delete), sync report system, provider language preference support
- Backoffice: MetadataSearchModal, ProviderIcon, SafeHtml components,
settings UI for provider/language config, enriched book detail page,
edit forms with locked fields support, API proxy routes
- OpenAPI/Swagger documentation for all new endpoints and schemas
Closes#3
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Pages: mode Original (zero-transcoding), ETag/304, cache index CBZ,
préfetch next 2 pages, filtre Triangle par défaut
- Thumbnails: DCT scaling JPEG via jpeg-decoder (decode 7x plus rapide),
img.thumbnail() pour resize, support format Original, fix JPEG RGBA8
- API fallback thumbnail: OutputFormat::Original + DCT scaling au lieu
de WebP full-decode, retour (bytes, content_type) dynamique
- Watcher: remplacement notify par poll léger sans inotify/fd,
skip poll quand job actif, snapshots en mémoire
- Jobs: mutex exclusif corrigé (tous statuts actifs, tous types exclusifs)
- Robustesse: suppression fs::canonicalize (problèmes fd Docker),
list_folders avec erreurs explicites, has_children default true
- Backoffice: FormRow items-start pour alignement inputs avec helper text,
labels settings clarifiés
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Change all instances of AppState to reference the new state module across multiple files for consistency.
- Clean up imports in auth, books, index_jobs, libraries, pages, search, settings, thumbnails, and tokens modules.
- Simplify main.rs by removing unused code and organizing middleware and route handlers under the new handlers module.
- Migration 0006: colonne watcher_enabled
- Crate notify pour surveillance FS temps réel (FSEvents/inotify)
- Watcher redémarré toutes les 30s si config change
- Détection instantanée création/modification/suppression
- Création job immédiate quand fichier détecté
- API: support watcher_enabled dans UpdateMonitoringRequest
- Backoffice: toggle Watcher avec indicateur ⚡
- Fonctionne en parallèle du scheduler auto-scan
Usage: Activer Watcher + Auto-scan pour réactivité max
- Ajout scheduler dans l'indexer (vérifie toutes les minutes)
- Migration 0004: colonnes monitor_enabled, scan_mode, next_scan_at
- API: GET /libraries avec champs monitoring
- API: PATCH /libraries/:id/monitoring pour configuration
- Composant MonitoringForm (client) avec checkbox et select
- Badge Auto/Manual avec couleurs différentes
- Affichage temps restant avant prochain scan
- Proxy route /api/libraries/:id/monitoring
Le scheduler crée automatiquement des jobs quand next_scan_at <= NOW()
- Ajout migrations DB: index_job_errors, library_monitoring, full_rebuild_type
- API: endpoints progression temps reel (/jobs/:id/stream), active jobs, details
- API: support full_rebuild avec suppression donnees existantes
- Indexer: logs detailles avec timing [SCAN][META][PARSER][BDD]
- Indexer: optimisation parsing PDF (lopdf -> pdfinfo) 235x plus rapide
- Indexer: corrections chemins LIBRARIES_ROOT_PATH pour dev local
- Backoffice: composants JobProgress, JobsIndicator (header), JobsList
- Backoffice: SSE streaming pour progression temps reel
- Backoffice: boutons Index/Index Full sur page libraries
- Backoffice: highlight job apres creation avec redirection
- Fix: parsing volume type i32, sync meilisearch cleanup
Perf: parsing PDF passe de 8.7s a 37ms
Perf: indexation 45 fichiers en ~15s vs plusieurs minutes avant