- Cover w-48 → w-40 (cohérent avec la page série)
- Titre séparé, auteur + série + statut de lecture regroupés en badges
- Métadonnées (format, pages, langue, ISBN, date) en ligne texte
au lieu de pills (style série)
- Toolbar d'actions groupée en bas (Edit, MarkRead, Convert, Delete)
- Tous les boutons d'action (MarkBookRead, Convert, Delete) alignés en
py-1.5 au lieu de Button size=sm (h-9)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- ProwlarrSearchModal: py-2 → py-1.5, gap-2 → gap-1.5 (aligné avec les autres)
- DeleteSeriesButton: remplace Button size=sm (h-9) par bouton inline
avec py-1.5 cohérent avec le reste de la toolbar
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Quand on fait un replace sans volumes manquants, expected_volumes n'était
pas envoyé → is_managed=false → pas d'insertion dans torrent_downloads
→ le torrent n'apparaissait pas dans la page downloads.
Maintenant un replace avec libraryId envoie toujours expected_volumes
(même vide) pour garantir le tracking.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
alwaysShowReplace suffit maintenant à montrer le bouton replace,
même quand allVolumes est vide (série complète sans volumes manquants).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Backend:
- Ajoute DELETE /libraries/:id/series/:name dans series.rs
- Supprime tous les fichiers physiques des livres de la série
- Supprime le dossier de la série (remove_dir_all)
- Nettoie en DB : books, series_metadata, external_metadata_links,
anilist_series_links, available_downloads
- Queue un scan job pour cohérence
Frontend:
- Crée DeleteSeriesButton.tsx avec modale de confirmation
- Ajouté dans la toolbar de la page détail série
- i18n fr/en pour les textes de confirmation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Prowlarr search modal : les releases avec le même titre sont groupées
avec rowSpan sur la colonne titre, sources listées en sous-lignes
- Downloads page : même logique, titre + volumes affichés une seule fois,
sources (indexer, seeders, taille, boutons) en lignes compactes
- Fonction utilitaire groupReleasesByTitle() dans les deux composants
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Ajout DELETE /books/:id : supprime le fichier physique, la thumbnail,
le book en DB et queue un scan de la lib. Bouton avec confirmation
sur la page de détail du livre.
- L'import torrent utilise unaccent() en SQL pour matcher les séries
indépendamment des accents (ex: "les géants" = "les geants").
- Fallback filesystem avec strip_accents pour les séries sans livre en DB.
- Migration 0069: activation de l'extension PostgreSQL unaccent.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Ajoute DELETE /available-downloads/:id?release=N pour supprimer une
release spécifique du JSON array (supprime l'entrée série si c'est
la dernière). Bouton trash sur chaque release dans la page downloads.
Corrige aussi le parsing des ranges de volumes sans préfixe sur le
second nombre (T17-23 détecte maintenant T17 à T23).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
La navigation client-side (via Link) servait des pages cachées,
empêchant les recherches de fonctionner sans Ctrl+R.
staleTimes.dynamic: 0 force Next.js à toujours re-fetcher les pages
dynamiques lors de la navigation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
La recherche utilise désormais le endpoint paginé /books avec un filtre
ILIKE sur title/series/author, ce qui permet la pagination des résultats.
Les series_hits sont toujours récupérés en parallèle via searchBooks.
Corrige aussi le remount du LiveSearchForm lors de la navigation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Modale Prowlarr (page série) : remplacé le bouton qBittorrent brut
par QbittorrentDownloadButton avec suivi managé (libraryId,
seriesName, expectedVolumes) et bouton "télécharger et remplacer".
- Ajout de alwaysShowReplace pour la modale Prowlarr (toujours montrer
le bouton remplacer) vs la page downloads (seulement si allVolumes >
expectedVolumes).
- Fix parseur : les tags de version entre crochets [V2], [V3] ne sont
plus extraits comme volumes (le préfixe "v" est ignoré après "[").
- Progression qBittorrent : utilise directement le champ progress
(completed et amount_left sont non-fiables sur qBittorrent 4.3.2).
- Référence import : ne plus exclure les volumes attendus de la
recherche de référence (corrige le mauvais dossier/nommage quand
tous les volumes sont dans expected_volumes).
- allVolumes ajouté à ProwlarrRelease (backend + frontend).
- flex-wrap sur les pastilles volumes dans la modale Prowlarr.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Ajout d'un bouton "télécharger et remplacer" avec popup de
confirmation, qui passe tous les volumes du pack (pas seulement
les manquants) et replace_existing=true à l'API.
- Nouvelle colonne replace_existing dans torrent_downloads.
- Fix critique du parseur de volumes : le pass 2 mélangeait les
indices d'octets (String::find) avec les indices de caractères
(Vec<char>), causant un décalage quand le titre contenait des
caractères multi-octets (é, à...). "Tome #097" extrayait 9
au lieu de 97. Réécrit en indexation char pure.
- Le préfixe "tome" skip désormais "#" (tome #097 → 97).
- Protection intra-batch : si une destination est déjà utilisée,
le fichier garde son nom original au lieu d'écraser.
- Alerte WARN si N fichiers source donnent N/3 volumes uniques.
- Nettoyage du répertoire sl-{id} et de la catégorie qBittorrent
après import.
- Badges volumes en flex-wrap dans la page downloads.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Le bouton revient à son état initial après l'icône verte de
confirmation, permettant de relancer un téléchargement si besoin.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
La section "available downloads" n'était jamais mise à jour après le
chargement initial car seuls les torrent downloads étaient rafraîchis.
Stocke latestFound en state React et le rafraîchit en parallèle.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Nouvelle table available_downloads (library_id, series_name) unique
comme source de vérité pour les téléchargements disponibles
- Les jobs de détection font UPSERT (ajout/mise à jour) et DELETE
(séries complètes ou sans résultat)
- Après import, mise à jour ciblée : retire les volumes importés des
releases, supprime l'entrée si plus de releases
- Migration avec import des données existantes depuis detection_results
- Endpoint latest-found simplifié : une seule query sur la table
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>