feat: ajout de la fonctionnalité de monitoring des mangas, incluant l'activation et la désactivation du suivi, la synchronisation des chapitres, et la mise à jour de l'API pour gérer ces nouvelles actions. Création de nouveaux composants Vue pour le rafraîchissement des chapitres et l'affichage des notifications. Intégration de tests unitaires pour valider le bon fonctionnement de ces fonctionnalités.

This commit is contained in:
ext.jeremy.guillot@maxicoffee.domains
2025-07-22 15:57:25 +02:00
parent d9e78b5229
commit 00d63dffeb
45 changed files with 2021 additions and 264 deletions

View File

@@ -2,6 +2,7 @@
namespace App\Domain\Manga\Infrastructure\Persistence;
use App\Domain\Manga\Application\Query\MonitoringCriteria;
use App\Domain\Manga\Domain\Contract\Repository\MangaRepositoryInterface;
use App\Domain\Manga\Domain\Model\Manga as DomainManga;
use App\Domain\Manga\Domain\Model\ValueObject\ExternalId;
@@ -9,6 +10,7 @@ use App\Domain\Manga\Domain\Model\ValueObject\ImageUrls;
use App\Domain\Manga\Domain\Model\ValueObject\MangaId;
use App\Domain\Manga\Domain\Model\ValueObject\MangaSlug;
use App\Domain\Manga\Domain\Model\ValueObject\MangaTitle;
use App\Domain\Manga\Domain\Model\ValueObject\MonitoringStatus;
use App\Entity\Manga as EntityManga;
use Doctrine\ORM\EntityManagerInterface;
use App\Domain\Manga\Domain\Model\Chapter;
@@ -50,7 +52,12 @@ readonly class LegacyMangaRepository implements MangaRepositoryInterface
public function findById(string $id): ?DomainManga
{
$entity = $this->entityManager->find(EntityManga::class, $id);
// Convertir le string ID en integer pour la base de données
if (!is_numeric($id)) {
return null;
}
$entity = $this->entityManager->find(EntityManga::class, (int) $id);
return $entity ? $this->toDomain($entity) : null;
}
@@ -88,18 +95,15 @@ readonly class LegacyMangaRepository implements MangaRepositoryInterface
->setStatus($manga->getStatus())
->setImageUrl($fullImageUrl ?? null)
->setThumbnailUrl($thumbnailUrl ?? null)
->setAlternativeSlugs($manga->getAlternativeSlugs());
->setAlternativeSlugs($manga->getAlternativeSlugs())
->setMonitored($manga->isMonitoringEnabled())
->setLastMonitoringCheck($manga->getLastMonitoringCheck());
// Only set externalId if it exists (to avoid setting null on update)
if ($manga->getExternalId()) {
$entity->setExternalId($manga->getExternalId()->getValue());
}
// Only set monitored for new entities
if (!$entity->getId()) {
$entity->setMonitored(false);
}
if ($manga->getRating() !== null) {
$entity->setRating($manga->getRating());
}
@@ -162,7 +166,7 @@ readonly class LegacyMangaRepository implements MangaRepositoryInterface
return $entity ? $this->toDomain($entity) : null;
}
public function saveChapter(Chapter $chapter): void
public function saveChapter(Chapter $chapter): ChapterId
{
$manga = $this->entityManager->find(EntityManga::class, $chapter->getMangaId());
@@ -179,6 +183,8 @@ readonly class LegacyMangaRepository implements MangaRepositoryInterface
$this->entityManager->persist($entity);
$this->entityManager->flush();
return new ChapterId((string) $entity->getId());
}
public function search(string $query, int $page = 1, int $limit = 20): array
@@ -241,6 +247,25 @@ readonly class LegacyMangaRepository implements MangaRepositoryInterface
return $chaptersByNumber;
}
public function findByMonitoringCriteria(MonitoringCriteria $criteria): array
{
$queryBuilder = $this->entityManager->createQueryBuilder()
->select('m')
->from(EntityManga::class, 'm')
->where('m.monitored = :enabled')
->setParameter('enabled', $criteria->enabled);
if ($criteria->lastCheckBefore) {
$queryBuilder->andWhere('(m.lastMonitoringCheck IS NULL OR m.lastMonitoringCheck < :lastCheckBefore)')
->setParameter('lastCheckBefore', $criteria->lastCheckBefore);
}
return array_map(
fn (EntityManga $entity) => $this->toDomain($entity),
$queryBuilder->getQuery()->getResult()
);
}
private function toDomain(EntityManga $entity): DomainManga
{
return new DomainManga(
@@ -258,6 +283,7 @@ readonly class LegacyMangaRepository implements MangaRepositoryInterface
imageUrls: $entity->getImageUrl() ? new ImageUrls($entity->getImageUrl() ?? '', $entity->getThumbnailUrl() ?? '') : null,
alternativeSlugs: $entity->getAlternativeSlugs() ?? [],
createdAt: $entity->getCreatedAt(),
monitoringStatus: $entity->isMonitored() ? MonitoringStatus::enabled() : MonitoringStatus::disabled()
);
}