Skip to content
CAI
Software that uses CAICheck a score

gbourgeat/clean-architecture-apiplatform

40.8

Weak · 22 September 2026

3.5k

lines of production code

PHP

primary language

7

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is a Symfony-based web application that manages user authentication, user profiles, and messaging conversations. It has been refactored to centralize authentication logic and user management, replacing a previous Backoffice structure with a dedicated Authentication context. The application utilizes JWT for secure token-based authentication and employs DTOs to decouple the API layer from the domain model.

Features

Added PHPUnit test runner script

A new executable script 'bin/phpunit' has been added to the project, providing a convenient way to run the PHPUnit test suite. The script first attempts to use the standard PHPUnit binary from the vendor directory, and if that is not found, it falls back to Symfony's 'simple-phpunit' bridge, ensuring tests can be executed regardless of the specific PHPUnit installation method.

bin · high confidence

Enhanced security with JWT keypair generation and configuration

The application now supports JWT authentication using a generated RSA keypair. A new script, generate-jwt-keypair.sh, creates the necessary private and public keys, which are mounted into the Docker container and exposed as environment variables (JWT\_PRIVATE\_KEY, JWT\_PUBLIC\_KEY) for the Symfony application to use for token signing and verification.

(repo-wide) · high confidence

Removals

Removed Backoffice authentication, user, and workspace domain and infrastructure code

The Backoffice module's internal implementation for authentication, user management, and workspace creation has been removed. This includes the deletion of domain entities (SecurityUser, Workspace, User), repositories, command/query handlers, infrastructure mappers, and API platform providers. This change eliminates the previous internal handling of user credentials and workspace creation within the Backoffice context.

src/Backoffice · high confidence

Security

Improved security for JWT keypair access

The Docker entrypoint script now applies specific file access control lists (ACLs) to the 'config/jwt' directory, granting the 'www-data' user read and execute permissions. This change ensures that the web server process can properly access the JWT keypair files, addressing a security concern related to keypair management.

docker · medium confidence

Behavioural changes

Add return types to Doctrine type converters

The Doctrine type converters for ConversationId, MessageId, ParticipantId, and the new ParticipantName now explicitly declare their return types (ConversationId, MessageId, ParticipantId, and ParticipantName respectively). This improves type safety and code clarity for developers working with these database mappings.

src/Messaging/Infrastructure/Doctrine/Type · high confidence

Add search capabilities to conversation and message repositories

The Doctrine repositories for conversations and messages now support paginated search. The ConversationRepository implements a new search method that returns a list of conversations, while the MessageRepository's searchByConversationId method has been updated to support pagination (page number and items per page) and returns an array of messages. Additionally, manual flush calls have been removed from the ConversationRepository to allow the Doctrine middleware to manage the unit of work via the command bus.

src/Messaging/Infrastructure/Doctrine/Repository · medium confidence

Authentication domain refactored with new entities, value objects, and events

The authentication domain has been restructured to separate user credentials from user details and enforce stricter validation. A new \UserCredential\ entity now stores the \UserId\, \Username\, and \HashedPassword\ together, while the \Password\ value object enforces a minimum length of 8 characters and requires uppercase, lowercase, number, and special characters. \Username\ is now validated as an email address, and \JWTToken\ and \HashedPassword\ value objects enforce format validation. Additionally, domain events for login, registration, and password/username changes have been introduced, and existing exceptions have been migrated to extend \ValidationFailed\ instead of \DomainException\.

src/Authentication/Domain · high confidence

Introduce Security session interface and restructure authentication DTOs

Added a new Security interface in the common application layer to manage security sessions, providing methods to check if a user is authenticated and to retrieve the connected user's details as an AuthUserDTO. Additionally, the AuthPassword value object was renamed and moved to a new PaginateResultDTO in the common application DTOs, reflecting a shift in how authentication and pagination data are handled across the application.

src/Common/Application · medium confidence

Messaging application services and queries now return DTOs instead of domain entities

The messaging application layer has been refactored to use Data Transfer Objects (DTOs) for all query and command responses. Specifically, the SearchConversationsPaginated, GetConversation, and GetMessages handlers now return arrays of ConversationDTO, ConversationDTO, and MessageDTO respectively, rather than raw domain entities or repositories. The CreateConversation and SendMessage command handlers have been updated to use new ConversationCreator and MessageCreator services, and the SearchConversations use case was renamed to SearchConversationsPaginated with updated pagination parameters (page and itemsPerPage).

src/Messaging/Application · high confidence

Migrate authentication endpoints from Backoffice to the main application

The authentication API endpoints (login, signup, and token decoding) have been moved from the Backoffice context to the main application layer. This includes renaming and refactoring DTOs (e.g., SecurityUser to AuthTokenDTO), use cases, and API Platform resources to reflect the new namespace and structure. The change simplifies the API surface by removing the Backoffice prefix and centralizing authentication logic.

src/Authentication/Application · high confidence

Migrate authentication from Kong header-based flow to JWT token-based flow

The authentication mechanism has been refactored to use JSON Web Tokens (JWT) instead of relying on a header from a Kong gateway. The \KongAuthenticator\ has been replaced by \JWTAuthenticator\, which now validates the \AUTHORIZATION\ header containing a Bearer token. A new \JWTUserProvider\ handles user loading via a \GetAuthUserFromToken\ query, replacing the previous flow that decoded user info from the \X-USERINFO\ header and potentially created new users. Additionally, the \Auth\ class has been renamed to \AuthUser\ and simplified by removing password hashing logic, while the \CursorFilter\ and \CursorResult\ classes have been removed.

src/Common/UserInterface · high confidence

Migrate user credential storage and authentication services to the Authentication context

The system now manages user credentials and authentication logic within the dedicated Authentication context, moving away from the previous Backoffice/Users structure. This includes a new Doctrine repository for UserCredential entities, a Symfony service for password hashing, and a TokenService for managing JWTs using RSA-256 keys. Additionally, Doctrine mapping and custom types for usernames and hashed passwords have been reorganized and updated to support the new domain model.

src/Authentication/Infrastructure · high confidence

Refactor messaging API to use DTOs and introduce ParticipantResource

The messaging user interface has been refactored to use Data Transfer Objects (DTOs) instead of domain entities and value objects. Specifically, a new \ParticipantResource\ has been introduced to represent participant data in the API, and existing resources (\ConversationResource\, \MessageResource\) now map from their respective DTOs (\ConversationDTO\, \MessageDTO\) rather than domain entities. This change simplifies the API layer by decoupling it from the domain model, and updates processors (\CreateConversationProcessor\, \SendMessageProcessor\) and providers (\ConversationProvider\, \ConversationsProvider\, \MessagesProvider\) to work with these new abstractions.

src/Messaging/UserInterface · medium confidence

Refactor messaging domain to use DTOs and simplify event structures

The messaging domain has been refactored to replace direct entity dependencies with Data Transfer Objects (DTOs) and simplified event structures. Specifically, the \Conversation\ and \Participant\ entities now accept \UserDTO\ instead of \User\ entities, and the \Participant\ entity no longer stores full \User\ objects, instead deriving name and ID from the DTO. Additionally, domain events (\ConversationWasArchivedByParticipant\, \ConversationWasCreated\, \MessageWasSent\) have been stripped of their previous payload-carrying structure (\fromPrimitives\/\toPrimitives\) in favor of a simpler, empty event class structure. Repository interfaces have also changed: \ConversationRepository\ now uses a \search\ method instead of cursor pagination, and \MessageRepository\ uses \searchByConversationId\ with pagination parameters instead of returning a raw collection.

src/Messaging/Domain · high confidence

Refactored domain exception hierarchy and simplified domain events

The codebase now uses a dedicated set of base exception classes in the Common domain, including InvalidFormat, LogicFailed, ResourceNotFound, and ValidationFailed, which replace previous value object classes and provide a structured error handling approach. Additionally, the DomainEvent class has been updated to remove the 'body' payload from its constructor and serialization, simplifying the event structure by only retaining aggregate root ID, event ID, and occurrence timestamp.

src/Common/Domain · medium confidence

Removal of hardcoded proxy headers in public entry point

The public/index.php file no longer forces the HTTP\_X\_FORWARDED\_PORT and HTTP\_X\_FORWARDED\_PROTO server variables to simulate HTTPS on port 443. This change removes a workaround previously used to handle a specific issue with the Kong API Gateway, allowing the application to rely on standard header values provided by the actual reverse proxy or load balancer.

public · medium confidence

Simplified base code and updated security service

The \SecurityService\ was updated to handle authentication state and connected user retrieval. The \DoctrineCursor\ and \DoctrineCursorPagination\ classes were removed to simplify the base code, as cursor-based pagination will be implemented differently in the future. Additionally, \FirstNameType\ and \LastNameType\ were corrected to extend \StringType\ from \App/Common\ instead of the incorrect \Doctrine\ vendor class, and a Psalm annotation was added to \DateTimeType\.

src/Common/Infrastructure · medium confidence

User module migrated from Backoffice to the main application

The User domain, previously located in the Backoffice area, has been moved to the root-level src/User directory. This migration includes updating all associated namespaces, file paths, and configuration mappings to reflect the new location. The change affects the entire user management functionality, including the creation, retrieval, and search of users, as well as the associated API Platform providers and processors.

src/User · high confidence

Test coverage

Added initial test suite for user signup

Added tests for the user signup flow, including a new SignupTest class that verifies the creation of a new user credential and the generation of an authentication token, along with a bootstrap file to configure the test environment.

tests · high confidence

Dependencies

Update PHP dependencies and add security advisories

The project's PHP dependencies have been updated, including upgrades to api-platform/core (3.0.7 to 3.0.8), doctrine/annotations (1.13 to 1.14/1.14.2), doctrine/collections (1.8.0 to 2.1.2), and doctrine/dbal (3.5.1 to 3.5.2). New packages added include ext-openssl, ext-apcu, firebase/php-jwt, and symfony/password-hasher. Additionally, the roave/security-advisories package was added to the dev dependencies to help identify vulnerable dependencies.

(dependencies) · medium 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

Score

  • CAI 47 → 41 (-5.7)
  • Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 100 → 99 (-0.5)
  • Architecture 100 → 83 (-16.6)
  • Maturity 60 → 60 (+0.0)
  • Readiness 21 → 18 (-2.4)
  • Security 69 → 79 (+10.5)
  • Domain Modelling 71 → 77 (+6.0)
  • Accessibility 47 (new)

Resolved (34)

  • 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
  • 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 CVE: [GHSA redacted] (composer.lock)
  • Low CVE: [GHSA redacted] (composer.lock)
  • Low CVE: [GHSA redacted] (composer.lock)
  • 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)
  • Medium CVE: [GHSA redacted] (composer.lock)
  • …and 14 more

New (45)

  • Abandoned package: doctrine/annotations
  • Critical CVE: [GHSA redacted] (composer.lock)
  • Documentation: no installation or build instructions (README.md)
  • Documentation: no usage examples (README.md)
  • Duplicated block (13 lines × 2) (src/Common/Infrastructure/Symfony/Messenger/MessengerCommandBus.php)
  • Duplicated block (6 lines × 2) (src/Messaging/UserInterface/ApiPlatform/Provider/ConversationsProvider.php)
  • Duplicated block (8 lines × 2) (src/Messaging/Infrastructure/Doctrine/Repository/DoctrineConversationRepository.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 CVE: [GHSA redacted] (composer.lock)
  • Leaked secret: hardcoded-credential (.env)
  • Leaked secret: signing-key (.env)
  • Low CVE: [GHSA redacted] (composer.lock)
  • Low CVE: [GHSA redacted] (composer.lock)
  • Low CVE: [GHSA redacted] (composer.lock)
  • Low CVE: [GHSA redacted] (composer.lock)
  • …and 25 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

gbourgeat/clean-architecture-apiplatform 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 22 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 a4831d78c447171fb6a71c8413b97d49000083fb — 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-821afab8930d.