Files
Mangarr/CLAUDE.md
ext.jeremy.guillot@maxicoffee.domains dae215dd3d
All checks were successful
Build and Deploy / deploy (push) Successful in 9m36s
feat: ajout de claude + correction des tests
2026-03-09 17:09:31 +01:00

4.3 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Overview

Mangarr is a Symfony 7.0 manga management/reader application. It scrapes manga chapters from various sources, stores them as CBZ files, and provides a reader interface. It runs on FrankenPHP inside Docker.

Common Commands

All commands run via Docker through the Makefile. Use make help to see all available targets.

make start          # Start Docker containers
make stop           # Stop containers
make install        # Build images, start containers, install deps (first-time setup)
make logs           # Follow container logs
make sh             # Shell into the PHP container

PHP / Symfony:

make sf c="about"                   # Run any Symfony console command
make cc                             # Clear cache
make vendor                         # Install Composer dependencies
make migration-migrate              # Run pending migrations
make fixtures-load                  # Load fixtures (drops and recreates data)

Testing:

make test                           # Run all tests
make test f="ScrapeChapterHandlerTest"  # Run a specific test by class name
make test c="--group e2e"           # Pass phpunit options

Code Quality:

make phpcs          # Fix code style (PSR-12 via php-cs-fixer)
make phpmd          # Run PHP Mess Detector
make quality        # Run both phpmd and phpcs
make phparkitect    # Check architectural rules

Frontend:

make npm-run        # Build assets once (dev)
make npm-watch      # Watch and rebuild assets
make npm-add p=pkg  # Add an npm dependency

Messenger workers (run in separate terminals):

make consume-commands   # Process command.bus messages
make consume-events     # Process domain events
make consume-schedule   # Process scheduled tasks

Architecture

The project uses Domain-Driven Design with strict layer separation enforced by PHPArkitect (phparkitect.php).

Domain Structure

src/Domain/
  {DomainName}/
    Domain/       # Pure domain: Models, Contracts (interfaces), Events, Exceptions
    Application/  # Use cases: Commands, Queries, CommandHandlers, QueryHandlers, Responses
    Infrastructure/ # Framework: Persistence, API Platform State, Clients, Services
  Shared/         # Cross-domain contracts and infrastructure (MangaPathManagerInterface, EventDispatcherInterface, etc.)

Business domains: Manga, Reader, Scraping, Conversion, Setting (+ Shared)

Architectural rules enforced:

  • Domain layer has no outside dependencies (only std exceptions)
  • Application layer may depend on its own Domain + App\Domain\Shared\Domain\Contract + Symfony\Messenger + Ramsey\Uuid; never on Infrastructure
  • Shared depends on nothing outside itself

Outside Domain (src/)

  • src/Entity/ — Doctrine ORM entities (legacy, used by repositories)
  • src/Controller/ — Symfony HTTP controllers
  • src/ApiResource/ — API Platform resource definitions + OpenApiFactoryDecorator
  • src/Service/ — Legacy services (being migrated into Domain)
  • src/Message/ + src/MessageHandler/ — Legacy Messenger messages (outside DDD)

Frontend

  • assets/controllers/ — Stimulus controllers (one per UI interaction)
  • assets/vue/app/ — Vue.js SPA mounted at /vue/*
  • Tailwind CSS via PostCSS, bundled with Webpack Encore
  • Mercure for real-time updates (queue status, download progress)

Key Infrastructure

  • Database: PostgreSQL 16 via Doctrine ORM; Adminer on port 8080
  • Scraping: scrapers.json defines per-site CSS selectors; HtmlScraper and JavascriptScraper (Panther) strategies
  • File storage: CBZ files stored at MANGA_DATA_PATH (default ~/Mangas); images at IMAGE_DATA_PATH
  • External API: MangaDex client for metadata (MANGADEX_CLIENT_ID/SECRET/USERNAME/PASSWORD env vars)
  • Messenger buses: command.bus (sync commands), events transport, commands transport, async transport (scheduler)

Adding a New Domain Feature

  1. Define contracts (interfaces) in Domain/{Name}/Domain/Contract/
  2. Write Command/Query + Handler in Domain/{Name}/Application/
  3. Implement interfaces in Domain/{Name}/Infrastructure/
  4. Register infrastructure aliases in config/services.yaml
  5. Run make phparkitect to validate layer boundaries