- Nouvelle table `torrent_downloads` pour suivre les téléchargements gérés
- API : endpoint POST /torrent-downloads/notify (webhook optionnel) et GET /torrent-downloads
- Poller background toutes les 30s qui interroge qBittorrent pour détecter
les torrents terminés — aucune config "run external program" nécessaire
- Import automatique : déplacement des fichiers vers la série cible,
renommage selon le pattern existant (détection de la largeur des digits),
support packs multi-volumes, scan job déclenché après import
- Page /downloads dans le backoffice : filtres, auto-refresh, carte par download
- Toggle auto-import intégré dans la card qBittorrent des settings
- Erreurs de détection download affichées dans le détail des jobs
- Volume /downloads monté dans docker-compose
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- metadata_batch, metadata_refresh, reading_status_match, reading_status_push,
download_detection : library_id devient optionnel, la boucle passe côté API
- rebuild (index_jobs.rs), thumbnail_rebuild, thumbnail_regenerate : même logique,
suppression du job unique library_id=NULL au profit d'un job par lib
- Backoffice simplifié : suppression des boucles frontend, les Server Actions
appellent directement l'API sans library_id pour le cas "toutes les librairies"
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When the API returns an error (e.g. no approved links for ongoing series),
the catch block was silently returning undefined from the server action,
making the button appear frozen with no feedback to the user.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Filter jobs by type, status, or library with dropdowns above the table.
Shows filtered count and a clear button when filters are active.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add download_detection to replayable job types and replay route handler.
Give each job type a unique colored background badge for better visual
distinction in the jobs table.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Show a download button on each available release in the detection report
when qBittorrent is configured, matching the Prowlarr search modal behavior.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove dashboard link from desktop/tablet nav (logo already links to /).
Move user switcher into hamburger menu as inline clickable items on mobile.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add a standalone toast notification system (no Provider needed) and use it
for settings save feedback. Skip save when fields are empty. Remove save
button on Anilist local user select in favor of auto-save on change.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds a configurable schedule (manual/hourly/daily/weekly) for the
download detection job in the library settings modal. The indexer
scheduler triggers the job automatically, and the API job poller
processes it — consistent with the reading_status_push pattern.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
For each series with missing volumes and an approved metadata link,
calls Prowlarr to find available matching releases and stores them in
a report (no auto-download). Includes per-series detail page, Telegram
notifications with per-event toggles, and stats display in the jobs table.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add revalidatePath("/libraries") to the monitoring, metadata-provider
and reading-status-provider route handlers so that saving library
settings invalidates the Next.js data cache and the page reflects
fresh data on reload.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Push reading statuses (PLANNING/CURRENT/COMPLETED) to AniList for all
linked series that changed since last sync, or have new books/no sync yet.
- Migration 0057: adds reading_status_push to index_jobs type constraint
- Migration 0058: creates reading_status_push_results table (pushed/skipped/no_books/error)
- API: new reading_status_push module with start_push, get_push_report, get_push_results
- Differential detection: synced_at IS NULL OR reading progress updated OR new books added
- Same 429 retry logic as reading_status_match (wait 10s, retry once, abort on 2nd 429)
- Notifications: ReadingStatusPushCompleted/Failed events
- Backoffice: push button in reading status group, job detail report with per-series list
- Replay support, badge label, i18n (FR + EN)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add /api/jobs/list endpoint and fetch the updated list right after
a successful replay so the new job appears instantly instead of
waiting for the next SSE poll (up to 15s when idle).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Shows a "Replay" button on non-active jobs that re-creates a new job
of the same type and library. Supports all replayable job types:
rebuild, full_rebuild, rescan, scan, thumbnail_rebuild,
thumbnail_regenerate, metadata_batch, metadata_refresh.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Allow switching between number of books and number of pages on the
dashboard reading activity chart. Adds pages_read to the stats API
response and a MetricToggle component alongside the existing PeriodToggle.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add full AniList integration: OAuth connect, series linking, push/pull sync
- Push: PLANNING/CURRENT/COMPLETED based on books read vs total_volumes (never auto-complete from owned books alone)
- Pull: update local reading progress from AniList list (per-user)
- Detailed sync/pull reports with per-series status and progress
- Local user selector in settings to scope sync to a specific user
- Rename "AniList" tab/buttons to generic "État de lecture" / "Reading status"
- Make Bédéthèque and AniList badges clickable links on series detail page
- Fix ON CONFLICT error on series link (provider column in PK)
- Migration 0054: fix series_metadata missing columns (authors, publishers, locked_fields, total_volumes, status)
- Align button heights on series detail page; move MarkSeriesReadButton to action row
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Scope all reading progress (books, series, stats) by user via
Option<Extension<AuthUser>> — admin sees aggregate, read token sees own data
- Fix duplicate book rows when admin views lists (IS NOT NULL guard on JOIN)
- Add X-As-User header support: admin can impersonate any user from backoffice
- UserSwitcher dropdown in nav header (persisted via as_user_id cookie)
- Per-user filter pills on "Currently reading" and "Recently read" dashboard sections
- Inline username editing (UsernameEdit component with optimistic update)
- PATCH /admin/users/:id endpoint to rename a user
- Unassigned read tokens row in users table
- Komga sync now requires a user_id — reading progress attributed to selected user
- Migration 0051: add user_id column to komga_sync_reports
- Nav breakpoints: icons-only from md, labels from xl, hamburger until md
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add login page with logo background, glassmorphism card
- Add session management via JWT (jose) with httpOnly cookie
- Add Next.js proxy middleware to protect all routes
- Add logout button in nav
- Restructure app into (app) route group to isolate login layout
- Add ADMIN_USERNAME, ADMIN_PASSWORD, SESSION_SECRET env vars
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Metadata refresh now skips series with ended/cancelled status
- Add xs size to Button component
- Unify view/cancel button sizes (h-7) with icons (eye & cross)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add Tooltip UI component for styled hover tooltips
- Replace native title attributes with Tooltip on all job stats
- Add refresh icon (green) showing actual refreshed count for metadata refresh
- Add icon+tooltip to scanned files stat
- Add icon prop to StatBox component
- Add refreshed field to stats_json types
- Distinct tooltip labels for total links vs refreshed count
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add multi-line chart showing job runs over time by type (scan,
rebuild, thumbnails, other) with the same day/week/month toggle
- Limit currently reading and recently read lists to 3 visible items
with a scrollbar for overflow
- Fix NUMERIC→BIGINT cast for SUM/COALESCE in jobs SQL queries
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a period selector (day, week, month) to the reading activity and
books added charts. The API now accepts a ?period= query param and
returns gap-filled data using generate_series so all time slots appear
even with zero values. Labels are locale-aware (short month, weekday).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add ETag header to API thumbnail responses for 304 Not Modified support.
Forward If-None-Match/ETag through the Next.js proxy route handler and
add next.revalidate for 24h server-side fetch caching to reduce
SSR-to-API round trips on the libraries page.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Thumbnails are already optimized (WebP) by the API, so disable Next.js
image optimization to avoid redundant CPU work. Switch route handlers
from buffering (arrayBuffer) to streaming (response.body) to reduce
memory usage and latency.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace relative time formatting (which incorrectly showed "just now"
for many jobs due to negative time diffs from server/client timezone
mismatch) with absolute locale-formatted date/time.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add currently reading, recently read, and reading activity sections to
the dashboard. Replace all custom SVG/CSS charts with recharts library
(donut, area, stacked bar, horizontal bar). Reorganize layout: libraries
and popular series side by side, books added chart full width below.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add notifications crate shared between API and indexer to send Telegram
messages on scan/thumbnail/conversion completion/failure, metadata linking,
batch and refresh events. Configurable via a new Notifications tab in the
backoffice settings with per-event toggle switches grouped by category.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Authors were only sourced from books.authors/books.author fields which are
often empty. Now also aggregates authors from series_metadata.authors
(populated by metadata providers like bedetheque). Adds author filter to
/series endpoint and updates the author detail page to use it.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When no specific library is selected, iterate over all libraries and
trigger a job for each one, skipping libraries with metadata disabled.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Server and client could use different default locales for
toLocaleDateString/toLocaleString, causing React hydration errors.
Pass the user locale explicitly in JobsList and SettingsPage.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace fetch polling in JobsIndicator with EventSource connected to
/api/jobs/stream. Fix the SSE route to return all jobs (via
/index/status) instead of only active ones, since JobsList also
consumes this stream for the full job history. JobsIndicator now
filters active jobs client-side. SSE server-side uses adaptive
interval (2s active, 15s idle) and only sends when data changes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Prevent unnecessary re-renders of book grid items when parent
components update without changing book data.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Dynamic import EditBookForm, EditSeriesForm, MetadataSearchModal, and
ProwlarrSearchModal so their code is split into separate chunks and
only fetched when the user interacts with them.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pause polling when the tab is hidden, refetch immediately when it
becomes visible again, and use a 30s interval when no jobs are active
instead of polling every 2s unconditionally.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove `unoptimized` flag from all thumbnail/cover Image components
and add proper responsive `sizes` props. Convert raw `<img>` tags on
the libraries page to next/image. Add 24h minimumCacheTTL for
optimized images. BookPreview keeps `unoptimized` since the API
already returns optimized WebP.
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>
Save/restore filter values in LiveSearchForm using localStorage keyed
by basePath (e.g. filters:/books, filters:/series). Filters are restored
on mount when the URL has no active filters, and cleared when the user
clicks the Clear button.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add two new filters to the books listing page:
- Format filter (CBZ/CBR/PDF/EPUB) using existing API support
- Metadata linked/unlinked filter with new API support via
LEFT JOIN on external_metadata_links (using DISTINCT ON CTE
matching the series endpoint pattern)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>