Commit Graph

341 Commits

Author SHA1 Message Date
ext.jeremy.guillot@maxicoffee.domains
345434c25d fix(manga): afficher le titre du chapitre téléchargé individuellement
Quand un chapitre téléchargé est seul dans son groupe (volumeChapterCount === 1),
on affichait "Chapitre 42" au lieu du titre réel. La condition isVolumeGroup
s'appliquait même pour les groupes à un seul élément.

Fix : la mise en forme "Chapitres X-Y" n'est désormais appliquée que lorsque
volumeChapterCount > 1, sinon on affiche chapter.title comme pour les chapitres
non téléchargés.
2026-03-27 11:29:13 +01:00
2868772f5c Merge pull request 'fix(deploy): vider le cache prod au démarrage du conteneur' (#39) from fix/entrypoint-clear-cache into main
All checks were successful
Deploy / deploy (push) Successful in 1m9s
Reviewed-on: #39
2026-03-26 18:50:15 +01:00
a2469b6c07 Merge branch 'main' into fix/entrypoint-clear-cache 2026-03-26 18:50:08 +01:00
ext.jeremy.guillot@maxicoffee.domains
926f938c45 fix(deploy): vider le cache prod au démarrage du conteneur
Sans ce fix, les workers FrankenPHP démarrent avec l'ancien cache persisté
dans le volume Docker. Si les classes référencées (ex. EntityManagerGhost,
LazyGhostTrait) ne correspondent plus à la version déployée, les workers
crashent en boucle, rendant le conteneur instable et faisant échouer le
cache:clear lancé ensuite par Deployer (exit 137).

La suppression de var/cache/prod à l'entrypoint garantit que les workers
démarrent toujours sur un cache vierge, généré à chaud à la première requête.
2026-03-26 18:49:30 +01:00
5551d73962 Merge pull request 'fix: limiter les workers FrankenPHP et nettoyer le Dockerfile' (#38) from fix/cache-clear-oom into main
Some checks failed
Deploy / deploy (push) Failing after 35s
Reviewed-on: #38
2026-03-26 18:44:26 +01:00
395a0a16cb Merge branch 'main' into fix/cache-clear-oom 2026-03-26 18:44:17 +01:00
ext.jeremy.guillot@maxicoffee.domains
8e2e608ad9 fix: limiter les workers FrankenPHP et nettoyer le Dockerfile
- worker.Caddyfile : limiter à 2 workers FrankenPHP pour éviter l'OOM
  lors du cache:clear en prod (chaque worker charge le kernel Symfony
  complet, la valeur par défaut = nb de CPUs était trop élevée)
- Dockerfile : supprimer les COPY des assets UX (ux-live-component,
  ux-react, ux-turbo) supprimés de composer.json
2026-03-26 18:43:51 +01:00
0f80cb9fec Merge pull request 'fix(doctrine): supprimer auto_generate_proxy_classes et proxy_dir' (#37) from fix/doctrine-orm3-config into main
Some checks failed
Deploy / deploy (push) Failing after 36s
Reviewed-on: #37
2026-03-26 18:39:56 +01:00
a3477629fb Merge branch 'main' into fix/doctrine-orm3-config 2026-03-26 18:39:51 +01:00
ext.jeremy.guillot@maxicoffee.domains
cde701986e fix(doctrine): supprimer auto_generate_proxy_classes et proxy_dir
Ces options ont été supprimées de Doctrine Bundle 3.x / ORM 3.x.
Elles causaient une erreur "Unrecognized options" au cache:clear en prod.
2026-03-26 18:39:22 +01:00
b921768aef Merge pull request 'chore: supprimer les dépendances Twig/Stimulus/React/Turbo inutilisées' (#36) from chore/cleanup-unused-dependencies into main
Some checks failed
Deploy / deploy (push) Failing after 1m10s
Reviewed-on: #36
2026-03-26 18:36:11 +01:00
ext.jeremy.guillot@maxicoffee.domains
5f0178f784 chore: supprimer les dépendances Twig/Stimulus/React/Turbo inutilisées
PHP : suppression de symfony/stimulus-bundle, ux-live-component, ux-react,
ux-turbo, twig/extra-bundle et symfony/form (plus utilisés depuis la
migration vers Vue.js SPA).

npm : suppression de @hotwired/stimulus, @hotwired/turbo, react, react-dom,
alpinejs, bootstrap, daisyui, sortablejs, vuedraggable et leurs types.
Corrige l'erreur de déploiement causée par vitest@^4.1.0 (introuvable)
requis par les anciens packages @symfony/ux-react et @symfony/ux-turbo v2.33.0.
2026-03-26 18:35:40 +01:00
c610d22bd2 Merge pull request 'feature/upgrade-symfony-8' (#35) from feature/upgrade-symfony-8 into main
Some checks failed
Deploy / deploy (push) Failing after 21s
Reviewed-on: #35
2026-03-26 18:23:13 +01:00
ab2cf319ac Merge branch 'main' into feature/upgrade-symfony-8 2026-03-26 18:23:07 +01:00
ext.jeremy.guillot@maxicoffee.domains
69c6757cf8 fix: corriger l'erreur HTTP 400 sur les endpoints content-sources POST/PUT
- ContentSourceForm.vue : convertir testChapterNumber en float/null avant
  envoi (évite d'envoyer "" pour ?float, rejeté par Symfony 8 strict)
- UpsertContentSourceResource : ajouter collectDenormalizationErrors: true
  pour que les erreurs de type retournent 422 au lieu de 400 via le
  chemin input: de API Platform 4
- ContentSource entity : corriger setImageSelector(string) → setImageSelector(?string)
  cohérent avec la colonne nullable
- Ajouter les tests manquants (testChapterNumber float/null/chaîne vide)
  qui auraient détecté ces bugs plus tôt
2026-03-26 18:22:31 +01:00
ext.jeremy.guillot@maxicoffee.domains
21d8111734 fix: migrer les données manga.genres de PHP sérialisé vers JSON
La migration vers DBAL 4 a changé le type de colonne genres de
Types::ARRAY (PHP sérialisé) vers Types::JSON. Les données existantes
en base doivent être converties via preUp() avant l'ALTER TABLE.
2026-03-26 17:58:07 +01:00
ext.jeremy.guillot@maxicoffee.domains
5ed303612a feat: migrer vers Symfony 8, PHP 8.4 et les dépendances majeures associées
- PHP 8.3 → 8.4 (Dockerfile + composer.json)
- Symfony 7.0 → 8.0 (tous les composants symfony/*)
- API Platform 3.x → 4.x : migration openapiContext → openapi: new Operation(...)
- Doctrine DBAL 3 → 4 : suppression use_savepoints, replace prepare/executeQuery
- Doctrine ORM 2.x → 3.x : ClassMetadataInfo → ClassMetadata, setParameters → setParameter
- Doctrine Bundle 2.x → 3.x, Fixtures Bundle 3.x → 4.x
- zenstruck/foundry 1.x → 2.x : ModelFactory → PersistentObjectFactory, getDefaults → defaults
- phpmd/phpmd 2.x → 3.x-dev (seule version supportant Symfony 8)
- phparkitect 0.3 → 0.8 : NotDependsOnTheseNamespaces prend un array
- symfony/mercure-bundle 0.3 → 0.4, symfony/monolog-bundle 3 → 4
- Suppression de runtime/frankenphp-symfony (intégré nativement dans symfony/runtime 8)
- worker.Caddyfile : suppression de APP_RUNTIME (détection automatique Symfony 8)
- Routes errors.xml/wdt.xml/profiler.xml → .php (Symfony 8 supprime le XML)
- Types::ARRAY → Types::JSON dans Entity/Manga.php (DBAL 4 retire array type)
- Suppression de src/Schedule.php (doublon vide avec MonitoringSchedule)
- Tests : hydra:Collection → Collection, hydra:member → member (API Platform 4)
2026-03-26 17:55:12 +01:00
4e30af6a16 Merge pull request 'refactor: supprimer tout le code legacy MVC/Twig/Stimulus' (#34) from refactor/remove-legacy-code into main
All checks were successful
Deploy / deploy (push) Successful in 1m7s
Reviewed-on: #34
2026-03-26 17:01:34 +01:00
ext.jeremy.guillot@maxicoffee.domains
5a0888eb28 refactor: supprimer tout le code legacy MVC/Twig/Stimulus
Supprime toutes les couches pré-DDD pour ne garder que l'architecture
hexagonale (src/Domain/), les entités Doctrine et le front Vue.js SPA.

Supprimé :
- src/Controller/ (9 controllers Twig, garde SecurityController)
- src/Service/, src/Message/, src/MessageHandler/ (services et messages legacy)
- src/Manager/, src/Twig/, src/Form/ (UI legacy)
- src/Event/, src/EventListener/, src/EventSubscriber/QueueStatusSubscriber
- src/Client/MangadexClient.php (doublon du Domain)
- src/Interface/, src/Factory/, src/DataFixtures/, src/Scheduler/MainSchedule
- templates/ (tous sauf vue/ et base retiré — SecurityController = pur JSON)
- assets/controllers/ (20 Stimulus controllers), app.js, bootstrap.js, controllers.json

Modifié :
- config/routes.yaml : suppression du chargement des controllers legacy
- config/packages/messenger.yaml : suppression des routes legacy
- config/services.yaml : suppression des bindings legacy + entrées Domain\Import fantômes
- webpack.config.js : suppression entry 'app' et enableStimulusBridge
- src/Entity/Chapter.php : suppression #[Broadcast] (Turbo Streams legacy)

Déplacé :
- src/Factory/*.php → tests/Factory/ (namespace App\Tests\Factory)
2026-03-26 17:00:46 +01:00
d7e6bf56d0 Merge pull request 'fix(layout): corriger la barre blanche en bas sur mobile réel' (#33) from fix/mobile-dvh-viewport into main
All checks were successful
Deploy / deploy (push) Successful in 1m12s
Reviewed-on: #33
2026-03-26 16:35:29 +01:00
17d44f68e5 Merge branch 'main' into fix/mobile-dvh-viewport 2026-03-26 16:35:22 +01:00
ext.jeremy.guillot@maxicoffee.domains
90d6feee2d fix(layout): corriger la barre blanche en bas sur mobile réel
Sur un vrai appareil mobile, 100vh inclut le chrome du navigateur
(barre de navigation), ce qui cachait le contenu en bas.
- Remplace h-screen (100vh) par h-[100dvh] (dynamic viewport height)
- Ajoute viewport-fit=cover pour préparer le support safe-area iOS
2026-03-26 16:35:00 +01:00
0880a77546 Merge pull request 'fix(layout): corriger le scroll coupé sur mobile' (#32) from fix/mobile-scroll-layout into main
All checks were successful
Deploy / deploy (push) Successful in 1m12s
Reviewed-on: #32
2026-03-26 16:27:18 +01:00
ext.jeremy.guillot@maxicoffee.domains
9926da6730 fix(layout): corriger le scroll coupé sur mobile
RouterView n'avait pas de contrainte de hauteur dans le flex-col de main,
empêchant overflow-y-auto de se déclencher. Le contenu dépassait la hauteur
de main.overflow-hidden et était silencieusement tronqué sur mobile.
2026-03-26 16:25:36 +01:00
4c80aa6b42 Merge pull request 'fix(reader): corriger le scroll vers le haut bloqué en mode infini' (#31) from fix/reader-infinite-scroll-up into main
All checks were successful
Deploy / deploy (push) Successful in 1m12s
Reviewed-on: #31
2026-03-26 16:11:50 +01:00
c0307a9173 Merge branch 'main' into fix/reader-infinite-scroll-up 2026-03-26 16:11:43 +01:00
ext.jeremy.guillot@maxicoffee.domains
45f7e88024 fix(reader): corriger le scroll vers le haut bloqué en mode infini
Les IntersectionObserver utilisaient root: null (viewport) au lieu du
conteneur de scroll réel (.infinite-reader). Le rootMargin de 1000px
était donc calculé par rapport au viewport, causant un montage/démontage
des pages à des moments imprécis et des sauts de layout lors du scroll
vers le haut.

Supprime également scroll-behavior: smooth sur le conteneur, qui entrait
en conflit avec le scroll anchoring du navigateur lors des corrections de
position, donnant l'impression que le scroll redescendait tout seul.
2026-03-26 16:11:19 +01:00
507fac5b5e Merge pull request 'fix(reader): corriger le chevauchement des pages en mode scroll avec zoom' (#30) from fix/reader-zoom-overlap-mobile into main
All checks were successful
Deploy / deploy (push) Successful in 1m19s
Reviewed-on: #30
2026-03-26 15:58:06 +01:00
071e12a06c Merge branch 'main' into fix/reader-zoom-overlap-mobile 2026-03-26 15:57:51 +01:00
ext.jeremy.guillot@maxicoffee.domains
59f72339fa fix(reader): corriger le chevauchement des pages en mode scroll avec zoom
En mode scroll infini, le zoom était appliqué via transform: scale() qui
n'affecte pas le flux de mise en page. Les pages se chevauchaient visuellement
quand le zoom était modifié. Passage à la propriété CSS zoom dans les deux
modes pour un comportement de layout correct.

Met aussi à jour le calcul de hauteur des placeholders pour inclure le
facteur de zoom et éviter les sauts de layout lors du chargement paresseux.
2026-03-26 15:56:18 +01:00
3963efa986 Merge pull request 'feat(system): page Status avec endpoint API Platform et composants Vue' (#29) from feat/system-status-page into main
All checks were successful
Deploy / deploy (push) Successful in 2m33s
Reviewed-on: #29
2026-03-17 22:05:27 +01:00
ext.jeremy.guillot@maxicoffee.domains
ca8791cc0d feat(system): page Status avec endpoint API Platform et composants Vue
- Nouveau domaine System/Domain/Model/SystemStatus (value object)
- QueryHandler agrégeant métriques mangas, chapitres, jobs (global/24h/7j), stockage et sources
- Endpoint GET /api/system/status via API Platform (singleton)
- Calcul de l'espace disque par RecursiveDirectoryIterator sur public/images
- Page Vue /system/status avec 6 cards (Mangas, Chapitres, Jobs, Stockage, Sources, Système)
- Nettoyage du router : suppression des PlaceholderComponent et routes placeholder
- Sidebar : suppression des entrées sans page réelle
2026-03-17 22:04:48 +01:00
c2b55e9018 Merge pull request 'feat/activity-realtime-mercure' (#28) from feat/activity-realtime-mercure into main
All checks were successful
Deploy / deploy (push) Successful in 2m39s
Reviewed-on: #28
2026-03-17 16:30:32 +01:00
ext.jeremy.guillot@maxicoffee.domains
07d1b2daed feat(activity): mises à jour temps réel des jobs via Mercure
- Ajoute jobId dans ChapterScrapingStarted et ChapterScrapingFailed
- Publie job.created (PENDING) depuis ScrapeChapterStateProcessor
- Publie job.status_changed (in_progress/completed/failed) depuis ScrapingEventSubscriber
- Gère job.created et job.status_changed dans activityStore : ajout instantané et suppression différée (1.5s)
2026-03-17 16:29:47 +01:00
a7e6879e83 Merge pull request 'refactor(scraping): job PENDING dès le POST HTTP, handler sans Doctrine' (#27) from refactor/scraping-ddd-pending-job into main
All checks were successful
Deploy / deploy (push) Successful in 2m29s
Reviewed-on: #27
2026-03-17 15:38:55 +01:00
ext.jeremy.guillot@maxicoffee.domains
fa035bfbfa refactor(scraping): job PENDING dès le POST HTTP, handler sans Doctrine
- ScrapingJob: mangaId/chapterNumber/sourceId optionnels (nullable) pour
  permettre la création en PENDING sans lookup DB dans le StateProcessor
- ScrapeChapter: ajoute jobId (pré-généré par le StateProcessor)
- ScrapeChapterStateProcessor: crée et persiste le job PENDING avant
  dispatch; injecte JobRepositoryInterface uniquement
- ScrapeChapterHandler: supprime EntityManagerInterface, beginTransaction/
  commit/rollback; charge le job existant via jobId, complete() sur succès
  seulement, fail() si toutes les sources échouent
- ScrapeChapterHandlerTest: pré-crée le job, passe jobId dans la commande,
  supprime le mock EntityManagerInterface
- ScrapeChapterTest: accès aux messages via static InMemoryMessageBus,
  vérifie la présence du jobId dans la commande dispatchée
2026-03-17 15:33:20 +01:00
ext.jeremy.guillot@maxicoffee.domains
ec4a8be934 feat(system): ajouter filtre par statut dans la page Logs
All checks were successful
Deploy / deploy (push) Successful in 2m30s
- Filtre toolbar : Échecs / Terminés / Tous (défaut : Échecs)
- Badge statut sur chaque LogItem (vert Terminé / rouge Échec)
- deleteAllLogs respecte le filtre actif
2026-03-16 15:00:12 +01:00
8443120c2f Merge pull request 'feat(system): implémenter la page Logs des erreurs de scraping' (#26) from feat/system-logs into main
All checks were successful
Deploy / deploy (push) Successful in 2m32s
Reviewed-on: #26
2026-03-16 14:50:14 +01:00
7a8f749f3f Merge branch 'main' into feat/system-logs 2026-03-16 14:50:04 +01:00
ext.jeremy.guillot@maxicoffee.domains
670e3f5315 feat(system): implémenter la page Logs des erreurs de scraping
- Nouveau domaine `system` avec `logsStore` (Pinia) filtré sur
  status=failed&type=scraping_job, tri, pagination et suppression
- Composant `LogItem` : affiche titre manga, chapitre, date, durée,
  domaine source (lien vers page d'édition), badge type scraping,
  slug utilisé, message d'erreur expandable
- Page `LogsPage` : toolbar avec badge total, dropdown tri, rafraîchir,
  tout supprimer ; charge les ContentSources pour enrichir l'affichage
- Route /system/logs branchée sur LogsPage
- ApiJobRepository : ajout du paramètre `type` dans getJobs
- Job entity : ajout des champs startedAt et completedAt
2026-03-16 14:43:19 +01:00
4398170989 Merge pull request 'feat(setting): implémenter la suppression d'une ContentSource' (#25) from feat/delete-content-source into main
All checks were successful
Deploy / deploy (push) Successful in 2m57s
Reviewed-on: #25
2026-03-16 00:27:59 +01:00
ext.jeremy.guillot@maxicoffee.domains
fc4ab68e8b feat(setting): implémenter la suppression d'une ContentSource
- Ajoute DeleteContentSourceCommand + CommandHandler (CQRS)
- Expose DELETE /api/content-sources/{id} via API Platform (Resource, Provider, Processor)
- Ajoute 2 tests Feature (204 succès, 404 not found)
- Frontend : méthode delete() dans le repository, action deleteSource() dans le store
- Nouveau composant ContentSourceDeleteModal (modale de confirmation)
- Bouton Supprimer dans la toolbar de ScrapperEdit (visible en mode édition uniquement)
2026-03-16 00:27:31 +01:00
36f873aaca Merge pull request 'feat/scrapers-content-sources-healthcheck' (#24) from feat/scrapers-content-sources-healthcheck into main
All checks were successful
Deploy / deploy (push) Successful in 3m17s
Reviewed-on: #24
2026-03-16 00:11:52 +01:00
ext.jeremy.guillot@maxicoffee.domains
874003eb35 fix(scraping): corriger les 403 sur les images avec protection anti-hotlink
- Ajouter le header Referer (origin de l'image) dans ImageDownloader pour les téléchargements backend
- Ajouter referrerpolicy="no-referrer" sur les <img> de la modale de test pour les previews navigateur
2026-03-16 00:11:17 +01:00
ext.jeremy.guillot@maxicoffee.domains
01474c264b feat(scraping): implémenter le health check de tous les scrapers
- Commande CheckAllScrapersHealth + handler avec ports dédiés
- Value Object ContentSourceHealthCheckData
- Resource API Platform et State Processor
- Adapters InMemory et tests unitaires + fonctionnels
2026-03-16 00:11:17 +01:00
ext.jeremy.guillot@maxicoffee.domains
795cbeccc3 feat(setting): étendre ContentSource avec champs de test et domain model
- Ajouter testSlug, testChapterNumber, baseUrl sur ContentSource (entité, domain model, migration)
- Exposer ces champs dans les Resources, Processors, Providers et Mapper
- Mettre à jour store Pinia, repository API et composants Vue (form, card, liste)
2026-03-16 00:11:17 +01:00
b0ce36096f Merge pull request 'feat(ui): harmoniser les pages Scrapers sur le design system Mangarr' (#23) from feat/ui-scrapers-harmonization into main
All checks were successful
Deploy / deploy (push) Successful in 2m58s
Reviewed-on: #23
2026-03-15 22:52:56 +01:00
ext.jeremy.guillot@maxicoffee.domains
da8a19cbcb feat(ui): harmoniser les pages Scrapers sur le design system Mangarr
- Layout canonique px-6 py-8 + sections border-t (suppression container mx-auto)
- Toolbar : label titre + bouton retour (ScrapperEdit) + boutons actions (ScrapperConfigurations)
- Bouton submit déplacé dans la toolbar droite via defineExpose/ref
- ContentSourceForm aplati (suppression du wrapper carte et du header)
- Séparation des sections du formulaire par border-t
- Suppression de tous les rounded-* sur les 4 composants
- Suppression du bloc debug "aucune source" et du h1 volant
2026-03-15 22:52:23 +01:00
ext.jeremy.guillot@maxicoffee.domains
367b361eef fix(manga): afficher la plage de chapitres au lieu du numéro de volume dans la liste
All checks were successful
Deploy / deploy (push) Successful in 2m58s
Pour les chapitres regroupés en volume (isVolumeGroup), la colonne "#" affichait
"Vol. X" au lieu du numéro/plage de chapitres. Remplacé par volumeChaptersRange.
2026-03-15 22:21:19 +01:00
ext.jeremy.guillot@maxicoffee.domains
9c5ae4bf16 fix(scheduler): désactiver MainSchedule legacy au profit de MonitoringSchedule DDD
All checks were successful
Deploy / deploy (push) Successful in 2m53s
MainSchedule (toutes les 6h) et MonitoringSchedule (toutes les 2h) tournaient
en parallèle sur les mêmes mangas surveillés, causant des doubles appels MangaDex
et des doublons de scraping.
2026-03-15 22:08:46 +01:00