Skip to content
CAI
Software that uses CAICheck a score

masfernandez/symfony-ddd-hexarch-cqrs

62.1

Adequate · 21 September 2026

5.5k

lines of production code

PHP

primary language

4

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is a Symfony-based API service for managing music catalog data, specifically handling albums, artists, labels, and tracks. It provides backoffice capabilities for creating, updating, and deleting these entities, supported by a dual authentication mechanism using JWT and opaque tokens. The architecture has been refactored to use a modular Docker environment and a shared domain layer, with a focus on clean separation of concerns and modernized dependencies.

How it got here

2021 — Catalog domain removal and infrastructure modernization

21 changes.

This period focused on removing the MusicLabel Catalog bounded context, specifically deleting all Album and Artist domain models, application services, and persistence implementations. The project simultaneously modernized its shared infrastructure by upgrading to Symfony 6.1 and PHP 8.1, while refactoring the Docker environment and test suites to support a cleaner, modular architecture.

2022 — Authentication and catalog domain implementation

5 changes.

This period focused on establishing the core domain models and authentication infrastructure for the MusicLabel API. It introduced dual JWT and opaque token-based login flows, while simultaneously defining the backoffice catalog entities and commands for managing albums, labels, and artists. The work also included initial database schema configuration and comprehensive test coverage for these new features.

Features

Album and label management commands and domain models

Users can now create, update, delete, and search for albums and labels in the backoffice catalog. This change introduces the domain models (Album, Label, Artist, Track) and their associated repositories, value objects, and application service commands (e.g., CreateAlbumCommand, UpdateAlbumCommand, DeleteLabelCommand) that enable these catalog management operations.

src/Backoffice, src/Shared/Domain/Id · high confidence

Initial database schema and configuration for MusicLabel API

The MusicLabel API is initialized with environment configuration files (.env, .env.dev, .env.preprod) and secret management for JWT authentication. The application is configured with Doctrine ORM mappings for entities including User, Token, Album, Artist, Label, and Track, along with corresponding database migrations. Service definitions are established for the Symfony framework, including Redis caching, Messenger handlers for commands and events, and repository implementations for the backoffice catalog and authentication domains.

apps/MusicLabel · high confidence

Introduced dual authentication mechanisms: JSON Web Tokens (JWT) and opaque tokens

The authentication subsystem now supports two distinct token-based login flows. Users can authenticate using a JSON Web Token (JWT) via the new \JsonWebTokenCreator\ and \JwTokenAuthenticator\ classes, which validate and generate signed tokens. Simultaneously, the system supports a traditional opaque token flow via \TokenCreator\ and \TokenAuthenticator\, which generate and verify random string tokens. Both flows rely on new domain models (\Token\, \JsonWebToken\) and value objects (\TokenValue\, \JsonWebTokenValue\) to manage credentials and session state.

src/Auth · high confidence

Removals

Removed Album domain model and repository interface

The Album domain model, its associated collection wrapper, and the AlbumRepository interface have been removed from the codebase. This eliminates the ability to create, read, update, or delete album entities through the existing repository contract, effectively removing album management capabilities from the catalog domain.

src/MusicLabel/Catalog/Domain/Model/Album · high confidence

Removed MusicLabelApp Catalog backend implementation

All backend infrastructure for the MusicLabelApp Catalog has been removed, including the Album controllers (GET, POST, PATCH), request input data classes, and Symfony configuration files (services, packages, env). This eliminates the HTTP API endpoints for managing albums in the Catalog bounded context.

apps/MusicLabelApp · high confidence

Removed all album application service classes

The application layer for managing albums has been removed. Specifically, the commands, handlers, and service classes for creating (Post), updating (Put), deleting (Delete), and retrieving (Get) albums have been deleted from the codebase. This eliminates the ability to perform these operations through the current application service architecture.

src/MusicLabel/Catalog/Application · high confidence

Behavioural changes

Refactor shared domain classes and restructure management email components

The email handling logic in the Management module has been moved from the MusicLabel namespace to the root Management namespace, with the listener class updated to use a new EventHandler interface and execute method signature. In the shared domain layer, the abstract Aggregate class has been renamed to AggregateRoot and moved to the shared domain namespace, while the DomainEventAbstract class has been renamed to DomainEvent and similarly relocated. Additionally, the AlbumNotFound exception has been renamed to DomainException and moved to the shared domain namespace, consolidating domain-level error handling.

src/Management, src/Shared/Domain · high confidence

Refactored shared application layer with new service interfaces and criteria handling

The shared application layer was restructured to support a cleaner separation of concerns. A new \Select\ class was added to handle field selection and aliasing logic. The \ApplicationService\ interface was introduced to define the standard contract for application services, replacing the previous \TransactionalApplicationServiceDecorator\ which was removed. Additionally, the \Criteria\ class was moved from the music label catalog domain to the shared application layer, with its constructor simplified to remove the \fields\ parameter and \getFieldsToFilter\ method, while \Request\ and \Response\ interfaces were renamed and relocated from the domain bus to the application service layer.

src/Shared/Application · high confidence

Removal of Artist and ArtistCollection domain models

The Artist and ArtistCollection domain models have been removed from the catalog's domain layer. This eliminates the ability to manage artist data and collections within the system, meaning any functionality relying on these models is no longer available.

src/MusicLabel/Catalog/Domain/Model/Artist · high confidence

Removal of Doctrine-based transactional session and Symfony compiler pass

The \DoctrineTransactionalSession\ class and the \TransactionalDecoratorPass\ compiler pass have been removed from the shared infrastructure. This eliminates the previous mechanism for wrapping application services with transactional behavior via Symfony's dependency injection container, meaning any services relying on this automatic transactional decoration will no longer receive it.

src/Shared/Infrastructure · high confidence

Removed Doctrine-based persistence implementation for the Album and Artist entities

The Doctrine-specific repository, custom type mappings, and ORM XML mapping files for Album and Artist have been deleted. This removes the existing Doctrine-based persistence layer for these entities, likely as part of a broader migration away from Doctrine ORM for this domain.

src/MusicLabel/Catalog/Infrastructure · high confidence

Removed shared value object base classes

The abstract base classes UuidValueObject and ValueObjectBase, which previously provided shared validation and value-extraction logic for domain value objects, have been removed from the codebase. This eliminates the generic validation framework that automatically enforced constraints on value object construction.

src/Shared/Domain/ValueObject · high confidence

Renames and reorganizes album API feature tests

The album-related feature tests have been reorganized from the 'Catalog' to the 'Backoffice' directory, reflecting a shift in how album management is categorized. The 'AlbumPost' feature was renamed to 'AlbumPatch' to accurately reflect that the tests now cover partial updates via the PATCH method, replacing the previous creation-focused tests. Additionally, new feature files were added for 'JsonWebToken' and 'Token' authentication scenarios, while the 'AlbumDelete' and 'AlbumGet' tests were moved and updated to use database fixtures instead of live API calls, and the 'AlbumsGet' tests were updated to reflect the 'release\_date' field rename from 'publishing\_date'.

features/MusicLabel · medium confidence

Reorganized directory structure for logs and database files

The project has reorganized its directory structure by moving several .gitkeep files to new locations. Specifically, the MusicLabel-related .gitkeep files have been moved to var/log/symfony/MusicLabel/, var/log/xdebug/, and var/log/nginx/. Additionally, the AlbumPut.feature file has been renamed to var/db/.gitkeep, and the src/MusicLabel/Management/.gitkeep has been renamed to var/log/.gitkeep. These changes reflect a more organized approach to managing log files and database-related placeholders.

var · medium confidence

Restructured Docker and development environment configuration

The project's Docker Compose setup has been reorganized from a single monolithic configuration into environment-specific files (local, local-dev, local-prod, prod) to better separate concerns for different deployment scenarios. The legacy \docker-compose.yml\ and \docker-compose.override.yml\ have been removed in favor of the new modular approach. Additionally, a \.env.dist\ file has been introduced to template environment variables for all services (Nginx, PHP, MySQL, MariaDB, RabbitMQ, Elastic Stack), and the \Makefile\ has been updated to use a new \console\ and \composer\ wrapper scripts that automatically start the appropriate Docker containers. The \behat.yml\ configuration has also been updated to reflect the new directory structure (\apps/MusicLabel/api\ instead of \apps/MusicLabelApp/Catalog/backend\).

(repo-wide) · high confidence

Updated Docker environment configuration and paths

The Docker configuration has been updated to reflect new file paths and structural changes. The ELK stack components (Elasticsearch, Kibana, Logstash) have been reorganized under the \docker/elastic\ directory, with Logstash configuration updated to use \symfony.monolog\ type and new log paths (\/tmp/app/logs/...\). The PHP environment now points to \/var/www/html/apps/MusicLabel/api\ for the messenger worker and preload scripts, and includes a 512MB memory limit for PHPStan. Nginx configuration has been simplified to use a template-based approach, and the old \backend.127.0.0.1.xip.io.conf\ has been removed. Additionally, SSL certificates and keys have been rotated, and Logstash patterns have been extended to support \messenger\, \deprecation\, and \console\ log types.

docker · high confidence

Test coverage

Added Behat test context classes for authentication; Added and reorganized Behat test context classes; Added test fixtures and migrated album tests to the backoffice module; Refactored test context classes to use shared abstract base classes; Refactored test infrastructure for MySQL and SQLite persistence cleaners; Removal of Album test fixtures and handlers; Removed Symfony test for TransactionalInterfaceDecoratorPass; Updated test namespace to include MusicLabel context; Updated test suite for transactional application service and shared criteria.

Dependencies

Upgrade to Symfony 6.1 and modernize dependencies

The project has been upgraded to Symfony 6.1, with corresponding updates to related Symfony components (console, framework-bundle, messenger, etc.). Several dependencies have been updated or added, including doctrine/annotations, doctrine/doctrine-bundle, and symfony/flex. The autoloading namespace has been updated from Masfernandez to Masfernandez\\MusicLabel, and a custom repository for behatch/contexts has been added. Additionally, PHP version requirements have been updated to ^8.1, and dev dependencies like phpstan and rector have been upgraded.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings — which rule fired, in which file, on which line, and how to fix it — are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.

Score

  • CAI 59 → 62 (+2.7)
  • Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 99 → 99 (-0.2)
  • Architecture 100 → 78 (-21.9)
  • Maturity 50 → 50 (+0.0)
  • Readiness 59 → 66 (+7.0)
  • Security 54 → 68 (+14.0)
  • Domain Modelling 100 → 100 (+0.0)

Resolved (32)

  • Coverage not included — suite not readable by the collector
  • Critical CVE: [GHSA redacted] (composer.lock)
  • Dependency hygiene not measured — dependency manifest found but not parsed for hygiene
  • Duplicated block (14 lines × 2) (apps/MusicLabel/api/src/Controller/Auth/InputRequest/JwtPostInputData.php)
  • Duplicated block (15 lines × 2) (apps/MusicLabel/api/src/Controller/Backoffice/InputRequest/AlbumPostCollectionInputData.php)
  • High CVE: [GHSA redacted] (composer.lock)
  • High CVE: [GHSA redacted] (composer.lock)
  • High CVE: [GHSA redacted] (composer.lock)
  • High CVE: [GHSA redacted] (composer.lock)
  • High CVE: [GHSA redacted] (composer.lock)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • Low CVE: [GHSA redacted] (composer.lock)
  • Low CVE: [GHSA redacted] (composer.lock)
  • Low CVE: [GHSA redacted] (composer.lock)
  • Medium CVE: [GHSA redacted] (composer.lock)
  • Medium CVE: [GHSA redacted] (composer.lock)
  • Medium CVE: [GHSA redacted] (composer.lock)
  • Medium CVE: [GHSA redacted] (composer.lock)
  • …and 12 more

New (52)

  • Abandoned package: composer/package-versions-deprecated
  • Abandoned package: doctrine/annotations
  • Abandoned package: sensio/framework-extra-bundle
  • Critical CVE: [GHSA redacted] (composer.lock)
  • Documentation: no installation or build instructions (README.md)
  • Documentation: no usage examples (README.md)
  • Duplicated block (10 lines × 3) (apps/MusicLabel/api/src/Repository/Auth/DoctrineUserRepository.php)
  • Duplicated block (12 lines × 2) (src/Auth/Application/JsonWebToken/Create/CreateJsonWebTokenCommand.php)
  • Duplicated block (12 lines × 2) (src/Backoffice/Catalog/Application/Album/AddLabelToAlbum/AddLabelToAlbumCommand.php)
  • Duplicated block (15 lines × 2) (apps/MusicLabel/api/src/Controller/Auth/InputRequest/JwtPostInputData.php)
  • Duplicated block (15–16 lines × 2) (apps/MusicLabel/api/src/Controller/Backoffice/InputRequest/AlbumPostCollectionInputData.php)
  • Duplicated block (18 lines × 2) (src/Backoffice/Catalog/Application/Album/Replace/ReplaceAlbumCommand.php)
  • Duplicated block (8 lines × 2) (apps/MusicLabel/api/src/Controller/Backoffice/AlbumPatchController.php)
  • High CVE: [GHSA redacted] (composer.lock)
  • High CVE: [GHSA redacted] (composer.lock)
  • High CVE: [GHSA redacted] (composer.lock)
  • High CVE: [GHSA redacted] (composer.lock)
  • High CVE: [GHSA redacted] (composer.lock)
  • High CVE: [GHSA redacted] (composer.lock)
  • High IaC: WD-COMPOSE-0002 (docker-compose.local-prod.yml)
  • …and 32 more

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

masfernandez/symfony-ddd-hexarch-cqrs was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 21 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit ae7ff7c9ca9370408725bb0ac60f5b23783ba528 — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-fa71c66cabd8.