Commit Graph

26 Commits

Author SHA1 Message Date
127cd8a42c feat(komga): add Komga read-status sync with reports and history
Adds Komga sync feature to import read status from a Komga server.
Books are matched by title (case-insensitive) with series+title primary
match and title-only fallback. Sync reports are persisted with matched,
newly marked, and unmatched book lists. UI shows check icon for newly
marked books, sorted to top. Credentials (URL+username) are saved
between sessions. Uses HashSet for O(1) lookups to handle large libraries.

Closes #2

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 22:04:19 +01:00
bc98067871 feat(books): édition des métadonnées livres et séries + champ authors multi-valeurs
- Nouveaux endpoints PATCH /books/:id et PATCH /libraries/:id/series/:name pour éditer les métadonnées
- GET /libraries/:id/series/:name/metadata pour récupérer les métadonnées de série
- Ajout du champ `authors` (Vec<String>) sur les structs Book/BookDetails
- 3 migrations : table series_metadata, colonne authors sur series_metadata et books
- Composants EditBookForm et EditSeriesForm dans le backoffice
- Routes API Next.js correspondantes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 17:21:55 +01:00
b14accbbe0 fix(books): tri des séries par volume + suppression de l'ancienne extract_page
- Ajout de `b.volume NULLS LAST` comme première clé de tri dans list_books
  et dans tous les ROW_NUMBER() OVER (...) des CTEs series, pour corriger
  l'ordre des volumes dont les titres varient en format (ex: "Round" vs "R")
- Suppression de l'ancienne extract_page publique et de ses 4 helpers
  (extract_cbz_page_n, extract_cbz_page_n_streaming, extract_cbr_page_n,
  extract_pdf_page_n) remplacés par la nouvelle implémentation avec cache
- Suppression de archive_index_cache dans AppState (remplacé par le cache
  statique CBZ_INDEX_CACHE dans parsers), import StdMutex nettoyé

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 12:08:03 +01:00
bf5a20882b perf(pages): cache de l'index d'archive en mémoire (-73% CBZ, -76% CBR cold)
Chaque cold render ré-énumérait toutes les entrées ZIP/RAR pour construire
la liste triée des images. Maintenant la liste est mise en cache dans l'AppState
(LruCache<String, Arc<Vec<String>>>, std::sync::Mutex pour accès spawn_blocking).

Nouvelles fonctions dans parsers :
- list_archive_images(path, format) -> Vec<String>
- extract_image_by_name(path, format, name) -> Vec<u8>

Mesures avant/après (cache disque froid, n=20) :
- CBZ cold : 43ms → 11.9ms (-73%)
- CBR cold : 46ms → 11.0ms (-76%)
- Warm/concurrent : identique

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 08:09:32 +01:00
cf2e7a0be7 feat(backoffice): add dashboard statistics with charts
Add GET /stats API endpoint with collection overview, reading status,
format/library breakdowns, top series, and monthly additions.
Replace static home page with interactive dashboard featuring donut
charts, bar charts, and progress bars. Use distinct colors for series
(warning/yellow) across nav, page titles, and quick links.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 18:37:53 +01:00
1d25c8869f feat(backoffice): add reading progress management, series page, and live search
- API: add POST /series/mark-read to batch mark all books in a series
- API: add GET /series cross-library endpoint with search, library and status filters
- API: add library_id to SeriesItem response
- Backoffice: mark book as read/unread button on book detail page
- Backoffice: mark series as read/unread button on series cards
- Backoffice: new /series top-level page with search and filters
- Backoffice: new /libraries/[id]/series/[name] series detail page
- Backoffice: opacity on fully read books and series cards
- Backoffice: live search with debounce on books and series pages
- Backoffice: reading status filter on books and series pages
- Fix $2 -> $1 parameter binding in mark-series-read SQL

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 18:17:16 +01:00
fd277602c9 feat(api): add GET /series/ongoing and GET /books/ongoing endpoints
Two new read routes for the home screen:
- /series/ongoing: partially read series sorted by last activity
- /books/ongoing: next unread book per ongoing series

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 16:24:05 +01:00
03af82d065 feat(tokens): allow permanent deletion of revoked tokens
Add POST /admin/tokens/{id}/delete endpoint that permanently removes
a token from the database (only if already revoked). Add delete button
in backoffice UI for revoked tokens.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 15:19:44 +01:00
648d86970f feat: suivi de la progression de lecture par livre
- 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>
2026-03-10 21:53:52 +01:00
c81f7ce1b7 feat(api): relier les settings DB au comportement runtime
- Ajout de DynamicSettings dans AppState (Arc<RwLock>) chargé depuis la DB
- rate_limit_per_second, timeout_seconds : plus hardcodés, lus depuis settings
- image_processing (format, quality, filter, max_width) : appliqués comme
  valeurs par défaut sur les requêtes de pages (overridables via query params)
- cache.directory : lu depuis settings au lieu de la variable d'env
- update_setting recharge immédiatement le DynamicSettings en mémoire
  pour les clés limits, image_processing et cache (sans redémarrage)
- parse_filter() : mapping lanczos3/triangle/nearest → FilterType

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-09 23:27:09 +01:00
e0b80cae38 feat: conversion CBR → CBZ via job asynchrone
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>
2026-03-09 23:02:08 +01:00
cfc896e92f feat: two-phase indexation with direct thumbnail generation in indexer
Phase 1 (discovery): walkdir + filename-only metadata, zero archive I/O.
Books are visible immediately in the UI while Phase 2 runs in background.

Phase 2 (analysis): open each archive once via analyze_book() to extract
page_count and first page bytes, then generate WebP thumbnail directly in
the indexer — removing the HTTP roundtrip to the API checkup endpoint.

- Add parse_metadata_fast() (infallible, no archive I/O)
- Add analyze_book() returning (page_count, first_page_bytes) in one pass
- Add looks_like_image() magic bytes check for unrar p stdout validation
- Add lsar fallback in list_cbr_images() for UTF-16BE encoded filenames
- Add directory_mtimes table to skip unchanged dirs on incremental scans
- Add analyzer.rs: generate_thumbnail, analyze_library_books, regenerate_thumbnails
- Remove run_checkup() from API; indexer handles thumbnail jobs directly
- Remove api_base_url/api_bootstrap_token from IndexerConfig and AppState
- Add unar + poppler-utils to indexer Dockerfile
- Fix smoke.sh: wait for job completion, check thumbnail_url field

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-09 22:13:05 +01:00
6d4c400017 refactor: update AppState references to use state module
- 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.
2026-03-08 21:19:22 +01:00
b1844a4f01 feat: enhance concurrency settings for rendering and thumbnail generation
- Introduce dynamic loading of concurrent render limits from the database for both page rendering and thumbnail generation.
- Update API to utilize the loaded concurrency settings, defaulting to 8 for page renders and 4 for thumbnails.
- Modify front-end settings page to reflect changes in concurrency limits and provide user guidance on their impact.
- Ensure that changes to limits require a server restart to take effect, with clear messaging in the UI.
2026-03-08 21:03:04 +01:00
e64848a216 feat: implement thumbnail generation and management
- 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.
2026-03-08 20:55:12 +01:00
c93a7d5d29 feat: thumbnails : part1 2026-03-08 17:54:47 +01:00
217919fa77 perf: increase concurrent renders limit from 4 to 8 2026-03-07 12:16:23 +01:00
292c61566c feat: add image optimization and settings page
- Add persistent disk cache for processed images
- Optimize image processing with short-circuit and quality settings
- Add WebP lossy encoding with configurable quality
- Add settings API endpoints (GET/POST /settings, cache management)
- Add database table for app configuration
- Add /settings page in backoffice for image/cache/limits config
- Add cache stats and clear functionality
- Update navigation with settings link
2026-03-07 09:12:06 +01:00
6e0a77fae0 feat(monitoring): T23 - Surveillance automatique des libraries
- 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()
2026-03-06 11:42:41 +01:00
5f51955f4d feat(indexing): Lot 4 - Progression temps reel, Full Rebuild, Optimisations
- 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
2026-03-06 11:33:32 +01:00
d33a4b02d8 feat: add series support for book organization
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.
2026-03-05 22:58:28 +01:00
40b7200bb3 add OpenAPI/Swagger documentation with utoipa 2026-03-05 21:46:29 +01:00
ef8a755a83 add book_count feature, migrate backoffice to server actions, fix healthcheck 2026-03-05 21:29:48 +01:00
20f9af6cba add page streaming, admin ui flows, and runtime hardening 2026-03-05 15:26:47 +01:00
6eaf2ba5dc add indexing jobs, parsers, and search APIs 2026-03-05 15:05:34 +01:00
88db9805b5 bootstrap rust services, auth, and compose stack 2026-03-05 14:51:02 +01:00