- Ajout de targets de log par domaine (scan, extraction, thumbnail, watcher)
contrôlables via RUST_LOG pour activer/désactiver les logs granulaires
- Ajout de logs détaillés dans extracting_pages (per-book timing en debug,
progression toutes les 25 books en info)
- Réduction de la consommation de fd: walkdir max_open(20/10), comptage
séquentiel au lieu de par_iter parallèle, suppression de rayon
- Détection ENFILE dans le scanner: abort après 10 erreurs IO consécutives
- Backoffice: settings dans le burger mobile, masquer "backoffice" et
icône settings en mobile
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>
- Indexer: ajout du champ `warnings` dans JobStats pour les erreurs
non-fatales (fichiers inaccessibles, permissions)
- Indexer: skip les fichiers dont le stat échoue au lieu de faire
crasher tout le scan de la library
- Backoffice: affichage des warnings dans le détail job (summary,
timeline, Index Statistics) et dans la popin jobs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Parsers: raw ZIP reader (flate2) contournant la validation CRC32 des
Unicode extra fields (0x7075) qui bloquait certains CBZ
- Parsers: nouvelle API publique extract_page() pour extraire une page
par index depuis CBZ/CBR/PDF avec fallbacks automatiques
- API: suppression du code d'extraction dupliqué, délégation à parsers::extract_page()
- API: retrait des dépendances directes zip/unrar/pdfium-render/natord
- Indexer: nettoyage Meili systématique à chaque sync (au lieu de ~10%)
avec pagination pour supporter les grosses collections — corrige les
doublons dans la recherche
- Indexer: retrait de la dépendance rand (plus utilisée)
- Backoffice: popin jobs rendue via createPortal avec positionnement
dynamique — corrige le débordement desktop et le header cassé en mobile
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Added a new job status 'extracting_pages' to represent the first sub-phase of thumbnail generation.
- Updated the database schema to include a timestamp for when thumbnail generation starts.
- Enhanced job progress components to handle the new status, including UI updates for displaying progress and status labels.
- Refactored job-related logic to accommodate the two-phase process: extracting pages and generating thumbnails.
- Adjusted SQL queries and job detail responses to include the new fields and statuses.
This change improves the clarity of job processing states and enhances user feedback during the thumbnail generation process.
La contrainte index_jobs_status_check ne listait pas 'cancelled', ce qui
causait une erreur 500 à chaque tentative d'annulation de job.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- meili.rs: corrige la désérialisation de la réponse paginée de
Meilisearch (attendait Vec<Value>, l'API retourne {results:[...]}) —
la suppression des documents obsolètes ne s'exécutait jamais, laissant
d'anciens UUIDs qui généraient des 404 sur les thumbnails
- books.rs: fallback sur render_book_page_1 si le fichier thumbnail
n'est plus accessible sur le disque (au lieu de 500)
- pages.rs: retourne 404 au lieu de 500 quand le fichier CBZ est absent
- search.rs + api.ts + BookCard: ajout série hits, statut lecture,
pagination OFFSET, filtre reading_status, et placeholder onError
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- API : nouvelle table book_reading_progress (migration 0016) et module
reading_progress.rs avec GET/PATCH /books/:id/progress (token read)
- API : GET /books/:id enrichi avec reading_status, reading_current_page,
reading_last_read_at via LEFT JOIN
- Backoffice : badge de statut (Non lu / En cours · p.N / Lu) sur la page
de détail et overlay sur les BookCards
- OpenSpec : change reading-progress avec proposal/design/specs/tasks
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Ajoute migration 0015 : colonne phase2_started_at sur index_jobs
- Indexer : renseigne phase2_started_at lors du passage à generating_thumbnails
- API : expose phase2_started_at et book_id dans IndexJobDetailResponse
- Page détail : timeline avec durée de chaque phase (Discovery / Thumbnails)
- Page détail : banners contextuels (success/failed/cancelled) avec résumé en une ligne
- Page détail : description textuelle du type de job, durée dans l'overview
- Page détail : stats normalisées selon le type (index vs thumbnail-only)
- JobRow : affiche le type via JobTypeBadge (cohérence visuelle)
- Badge : labels lisibles pour tous les types de jobs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Ajoute la possibilité de convertir un livre CBR en CBZ depuis le backoffice.
La conversion est sécurisée : le CBR original n'est supprimé qu'après vérification
du CBZ généré et mise à jour de la base de données.
- parsers: nouvelle fn `convert_cbr_to_cbz` (unar extract → zip pack → vérification → rename atomique)
- api: `POST /books/:id/convert` crée un job `cbr_to_cbz` (vérifie format CBR, détecte collision)
- indexer: nouveau `converter.rs` dispatché depuis `job.rs`
- backoffice: bouton "Convert to CBZ" sur la page détail (visible si CBR), label dans JobRow
- migrations: colonne `book_id` sur `index_jobs` + type `cbr_to_cbz` dans le check constraint
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Ajout d'un menu hamburger mobile (MobileNav) avec drawer animé via React Portal (évite le piège du backdrop-filter du header)
- Popin JobsIndicator adaptée mobile : positionnement fixed plein-écran sur petit écran, backdrop semi-transparent
- Navigation tablette (md→lg) : icônes seules avec tooltip natif, labels visibles uniquement sur lg+
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Shows 5 pages at a time in a full-width grid with prev/next navigation.
Pages are fetched via the existing proxy route with webp format.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove unused image dependencies from Cargo.lock.
- Update API to handle thumbnail generation and checkup processes.
- Introduce new routes for rebuilding and regenerating thumbnails.
- Enhance job tracking with progress indicators for thumbnail jobs.
- Update front-end components to display thumbnail job status and progress.
- Add backend logic for managing thumbnail jobs and integrating with the API.
- Refactor existing code to accommodate new thumbnail functionalities.
- Extend API /folders endpoint to support browsing subdirectories with path parameter
- Add depth and has_children fields to FolderItem
- Create FolderBrowser component with tree view navigation
- Create FolderPicker component with input, browse button and popup modal
- Add API proxy route for /api/folders
- Update LibraryForm to use new FolderPicker component
- Fix path handling to correctly resolve /libraries/ subdirectories
- Created reusable UI components (Card, Button, Badge, Form, Icon)
- Added PageIcon and NavIcon components with consistent styling
- Refactored all pages to use new UI components
- Added non-blocking image loading with skeleton for book covers
- Created LibraryActions dropdown for library settings
- Added emojis to buttons for better UX
- Fixed Client Component issues with getBookCoverUrl
- Spinner animé visible quand jobs en cours (avec pulse)
- Badge avec compteur de jobs actifs
- Popin moderne au clic avec:
- Header avec titre et lien View All
- Barre de progression globale
- Liste détaillée des jobs (status, type, %)
- Fichier en cours de traitement
- Mini-stats (indexed, errors)
- Footer avec info auto-refresh
- CSS complet avec animations et dark mode
- Suppression JobsIndicatorWrapper obsolète
- Mise à jour layout.tsx pour nouvelle API
- Remplacement du tableau moche par des cards modernes
- Layout responsive en grille (grid-template-columns)
- Cards avec hover effects (ombre + léger déplacement)
- Stats visibles en boxes cliquables (Books/Series)
- Monitoring compact avec checkboxes côte à côte
- Badges pour Disabled et Watcher (⚡)
- Actions regroupées avec boutons colorés
- Formulaire d'ajout plus visible et stylisé
- CSS complet avec dark mode support
- MonitoringForm simplifié et compact
- Ajout loading='lazy' sur les couvertures de livres (BookCard + detail)
- Correction couleur job-highlighted en dark mode (fond bleu foncé)
- Animation pulse adaptée pour le dark mode
- Page /jobs/[id] avec affichage complet des détails
- Timeline visuelle (Created → Started → Finished)
- Barre de progression avec stats (processed/total/remaining)
- Stats: scanned, indexed, removed, errors
- Vitesse de traitement (fichiers/sec)
- Liste des erreurs avec fichier et message
- Navigation retour vers la liste
- Bouton 'View' sur chaque ligne de job
- Lien cliquable sur l'ID du job
- Styles CSS pour timeline, progress bar, statistiques
DoD: Page job détaillée avec timeline, stats et navigation complète
- 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
API:
- Add /libraries/{id}/series endpoint to list series with book counts
- Add series filter to /books endpoint
- Fix SeriesItem to return first_book_id properly (using CTE with ROW_NUMBER)
Indexer:
- Parse series from parent folder name relative to library root
- Store series in database when indexing books
Backoffice:
- Add Books page with grid view, search, and pagination
- Add Series page showing series with cover images
- Add Library books page filtered by series
- Add book detail page
- Add Series column in libraries list with clickable link
- Create BookCard component for reusable book display
- Add CSS styles for books grid, series grid, and book details
- Add proxy API route for book cover images (fixing CORS issues)
Parser:
- Add series field to ParsedMetadata
- Extract series from file path relative to library root
Books without a parent folder are categorized as 'unclassified' series.