Skip to content
CAI
Software that uses CAICheck a score

phexium/framework

63.2

Adequate · 22 September 2026

12.1k

lines of production code

PHP

primary language

6

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is a PHP framework named Phexium that provides a clean architecture foundation with a comprehensive plugin ecosystem for handling commands, queries, events, caching, and database operations. It includes a demo library management application that illustrates these capabilities through book and loan lifecycle management, user authentication, and role-based access control. The framework supports multiple database backends and offers extensive tooling for development, testing, and deployment.

Features

Add HTTP controllers for book management in the demo library

The demo application now includes HTTP controllers (CreateBook, DeleteBook, DetailBook, ListBooks, UpdateBook) that expose book management capabilities via the web. These controllers handle form rendering, validation, and persistence using the command/query bus pattern, and support pagination for the book listing page.

app/demo/src/Library/Presentation/Http · high confidence

Add book management UI with pagination and dual output formats

The demo library now includes a complete set of presentation components for managing books, featuring HTML templates and JSON presenters for listing, creating, updating, and viewing book details. The book listing page supports pagination, allowing users to navigate through the collection, while the create and update forms handle validation errors and pre-fill data. Both HTML views and JSON APIs are now available for these operations, enabling flexible integration for different client needs.

app/demo/src/Library/Presentation · high confidence

Add book query handlers and DTOs for create, detail, list, and update operations

The application now includes query-layer support for managing books, introducing handlers and corresponding request/response DTOs for creating, retrieving details, listing (with pagination), and updating books. The list operation uses a cacheable query with a 1-minute TTL, while the detail query is cacheable with a 5-minute TTL; both rely on the book repository and return structured data. Create and update queries carry form values and errors to support validation feedback, and all handlers implement the typed \_\_invoke() contract.

app/demo/src/Library/Application/Query · high confidence

Add loan management presentation layer with borrowing and paginated listing

The demo application now includes a complete presentation layer for the Loan feature, introducing new Twig templates and corresponding HTML presenters/view-models. Users can now borrow books via a dedicated form that validates book selection and loan period (1–90 days), view a paginated list of all loans with status badges, and manage their personal loans with the ability to return active books. The implementation adds specific presentation components for BorrowBook, ListLoans (with pagination support), and MyLoans, wired to their respective application responses.

app/demo/src/Loan/Presentation · high confidence

Add session middleware to ensure session lifecycle management

A new SessionMiddleware has been introduced in the presentation layer to automatically manage the HTTP session lifecycle. This middleware ensures that the session is started if it has not already begun and is saved after the request is processed, providing consistent session handling for incoming requests.

src/Presentation/Middleware · high confidence

Add user login, logout, and session management UI

The demo application now includes a complete user authentication flow. A new LoginController handles displaying the login form, processing authentication commands, and managing logout sessions. The associated LoginHtmlPresenter formats the user data for the view, and the Login.html.twig template provides the user-facing interface for entering credentials and submitting the login request.

app/demo/src/User/Presentation · high confidence

Added Docker utility scripts for build verification and image updates

New shell scripts have been added to the Docker utility folder to streamline development workflows. The \check-build.sh\ script validates the local Docker environment by verifying that key services (Nginx, PHP-FPM, MySQL, PostgreSQL, Redis) are running and checking specific configurations, such as PHP version and required modules. The \update-base-images.sh\ script automates the process of pulling updated base images for all services defined in the Dockerfiles, ensuring the local development environment stays current with upstream changes.

docker/util · high confidence

Added cache clearing utility for the demo application

A new PHP script (tools/cache/clear.php) has been added to allow users to manually clear the application's cache. This utility loads the demo application's environment and dependency injection container, retrieves the configured cache implementation, and executes a clear operation, providing feedback on whether the cache was successfully cleared or if the operation failed.

tools/cache · high confidence

Added database initialization script and fixture support

A new CLI script (database\_init.php) has been added to the database directory, allowing users to initialize the database schema and load fixtures for SQLite, MySQL, or PostgreSQL. This script relies on new helper classes (FixtureIdGenerator and FixturePasswordHasher) to manage ID generation and password hashing during the fixture loading process, enabling easier setup of demo or test environments.

database · high confidence

Added domain exception classes for the Library module

The Library domain now includes specific exception classes to handle validation and availability errors. BookNotAvailableException provides factory methods for borrowing and returning scenarios, while InvalidAuthorException, InvalidIsbnException, and InvalidTitleException handle validation failures, with the latter specifically checking for invalid ISBN-13 checksums.

app/demo/src/Library/Domain/Exception · high confidence

Added event listeners for book and loan lifecycle events

New event listeners have been added to the application's event handling layer to react to domain events. BookEventHandler logs activity for book creation, updates, and deletion. LoanCreatedEventHandler and LoanReturnedEventHandler automatically update the status of associated books to 'Borrowed' or 'Available' respectively by dispatching UpdateBookStatusCommand, while also logging the loan details.

app/demo/src/Library/Application/EventListener · high confidence

Homepage starter feature with clean architecture

The application now includes a functional homepage that displays a Nelson Mandela greeting and the current date/time. This feature is implemented using a clean architecture pattern: a controller handles the HTTP request, a use case retrieves the data (using a clock interface for the timestamp), and a presenter prepares the view model for a Twig template.

app/starter/src · high confidence

Initial domain model for the library demo application

This change introduces the core domain entities and value objects for the library demo, including Book, Author, Title, and ISBN, along with their associated repository interface, status enum, and domain events. The ISBN value object now explicitly casts the result of preg\_replace to a string and casts digits to int during checksum calculation to ensure type safety.

app/demo/src/Library/Domain · high confidence

Initial repository scaffolding and CI/CD pipeline setup

The repository is initialized with the foundational configuration files required for development and continuous integration. This includes a GitLab CI/CD pipeline (\.gitlab-ci.yml\) that enforces trunk-based development, runs static analysis via PHPStan and deptrac, and executes unit, integration, and acceptance tests with coverage reporting. The project also introduces a Taskfile (\taskfile.yaml\) to standardize development commands, Behat configuration for acceptance testing, and PHP-CS-Fixer rules to enforce coding standards. Additionally, documentation infrastructure is set up using MkDocs (\mkdocs.yml\), and the project structure is defined with a starter application, demo modules, and a bootstrap installer (\installer.php\) for new projects.

(repo-wide) · high confidence

Introduce Cache plugin with multiple storage adapters and TTL support

A new Cache plugin has been added to the system, providing a unified caching layer backed by a \CacheInterface\ that extends PSR-16 \SimpleCache\. The implementation includes three storage adapters: \FileCache\ for persistent storage using xxh128-hashed file paths, \InMemoryCache\ for temporary runtime caching, and \RedisCache\ for distributed caching with strict serialization controls to prevent PHP Object Injection. All adapters support Time-To-Live (TTL) configuration via integer seconds or \DateInterval\, and share a \CacheMultipleOperationsTrait\ to handle batch get/set/delete operations.

src/Plugin/Cache · high confidence

Introduce Clock plugin with multiple time-source adapters

The new Clock plugin provides a \ClockInterface\ (extending PSR-20) and four adapter implementations: \SystemClock\ for real-time, \FrozenClock\ for deterministic testing with a fixed timestamp, \MonotonicClock\ to guarantee strictly increasing time values, and \OffsetClock\ which allows advancing or rewinding time by months, days, hours, minutes, and seconds. This enables consumers to abstract away system time dependencies for more predictable behavior in tests or time-shifted scenarios.

src/Plugin/Clock · high confidence

Introduce Command Bus plugin with Sync and Transactional adapters

A new Command Bus plugin has been added to the system, providing a standardized way to dispatch commands to their respective handlers. The plugin includes a \CommandBusInterface\ that defines the dispatch contract, and two concrete adapters: \SyncCommandBus\ for immediate, synchronous execution, and \TransactionalCommandBus\ which wraps command dispatch in a database transaction (beginning, committing, or rolling back as needed). Handler resolution follows a naming convention where a command class \XCommand\ maps to a handler class \XHandler\ in the same namespace, requiring the handler to be registered in the DI container and implement \CommandHandlerInterface\.

src/Plugin/CommandBus · high confidence

Introduce File and Null logger adapters

Added a new logging plugin featuring a FileLogger adapter that writes timestamped log entries to a specified file with configurable minimum severity levels, and a NullLogger adapter that discards all log messages. Both adapters implement the new LoggerInterface, which extends PSR-3 for compatibility.

src/Plugin/Logger · high confidence

Introduce HTTP controllers for the loan management demo

This change adds the HTTP presentation layer for the loan feature, introducing four new controllers: BorrowBookController, ListLoansController, MyLoansController, and ReturnBookController. These controllers handle user interactions such as borrowing books, listing loans, viewing personal loans, and returning books. The implementation enforces authentication by requiring a valid user ID from the session for borrowing, returning, and viewing personal loans, while the loan listing endpoint is publicly accessible with pagination support. Each controller integrates with the application's command and query buses to execute domain logic and uses Twig for rendering HTML responses.

app/demo/src/Loan/Presentation/Http · high confidence

Introduce Loan domain model and repository interfaces

The demo application now includes the core domain layer for the loan feature, defining the Loan entity with status tracking (Active/Returned), overdue detection, and return logic. This change adds domain events (LoanCreatedEvent, LoanReturnedEvent), value objects (LoanPeriod with 1–90 day validation), and specific exceptions (BookNotAvailableException, InvalidLoanPeriodException, etc.). It also establishes the LoanRepository interface with methods for querying loans by user or ID, along with read models (LoanWithDetails) and specifications (UserIdSpecification) to support data retrieval.

app/demo/src/Loan/Domain · high confidence

Introduce PSR-14 compliant event dispatcher plugin with League adapter

This change adds a new event dispatcher plugin that implements PSR-14 compliance via a \LeagueDispatcher\ adapter, wiring the \League\\Event\ library to the framework's internal \DispatcherInterface\ and \ListenerRegistryInterface\. The \LeagueListenerRegistry\ now handles listener subscription through a \subscribeTo\ method that validates callables and wraps them in \LeagueListener\ instances, while the \ListenerInterface\ has been simplified to a marker interface without a typed \\_\_invoke\ contract, aligning the plugin's port layer with the standard provider/dispatcher separation.

src/Plugin/Dispatcher · high confidence

Introduce Password Hasher Plugin with Bcrypt, Argon2, and Plaintext adapters

A new password hashing plugin has been added to the system, providing a unified interface for securing user credentials. The plugin includes adapters for Bcrypt, Argon2id, and Argon2i algorithms, allowing for configurable security parameters such as memory cost, time cost, and threads for Argon2 variants, and cost for Bcrypt. Additionally, a Plaintext adapter is included, which stores passwords with a '$plain$' prefix, primarily useful for development or testing environments where immediate verification without hashing overhead is required. This change enables developers to choose the appropriate hashing strategy based on their security requirements and environment.

src/Plugin/PasswordHasher · high confidence

Introduce Phexium CLI installation tool

The \tools/install\ directory now contains a new Phexium CLI installer that automates the setup of a new project. It fetches the framework from the upstream GitLab repository, allows the user to select between 'starter' and 'demo' templates, and configures the environment with Docker and Composer. The tool enforces a minimum PHP version of 8.4, checks for required system commands (git, task, docker), and supports database options including SQLite and InMemory.

tools/install · high confidence

Introduce Presentation layer with immutable response builder and controller abstractions

This change introduces the new \Phexium\\Presentation\ namespace, providing a structured presentation layer for the application. It adds \AbstractController\ and \AbstractApiController\ base classes that simplify common HTTP response patterns (such as JSON success, created, and error responses) by delegating to a new \ResponseBuilder\. The \ResponseBuilder\ is an immutable, readonly class that implements \ResponseBuilderInterface\, allowing controllers to construct HTTP responses with status codes, headers, and bodies (JSON, HTML, or raw) in a fluent manner. Additionally, the layer includes \PresenterInterface\ and \PresenterAbstract\ for view-model generation, \ControllerInterface\, and \PresentationContextInterface\ for permission checks, establishing a clear separation between controller logic and response formatting.

src/Presentation · high confidence

Introduce Query Bus plugin port interfaces and exception handling

The Query Bus plugin now exposes its core port definitions in the \src/Plugin/QueryBus/Port\ directory. This includes the \QueryBusInterface\, which defines the contract for dispatching queries and receiving responses, and the \UnexpectedQueryResponseException\ class to handle type mismatches during query execution. These changes establish the structural boundary for the plugin's integration with the application's query layer.

src/Plugin/QueryBus/Port · high confidence

Introduce RBAC authorization plugin with role-based permission checks

This change adds a new authorization plugin that implements Role-Based Access Control (RBAC). It introduces an \AuthorizationInterface\ defining methods to check permissions (\can\, \canAny\, \canAll\) and retrieve permission lists, alongside a \SubjectInterface\ for identifying users or roles. The \RbacAuthorizationService\ provides the concrete implementation, allowing the system to verify if a subject holds specific permissions based on a configured set of roles, while \StringSubject\ offers a simple adapter for string-based identifiers.

src/Plugin/Authorization · high confidence

Introduce Specification pattern for composable domain filters

The domain layer now includes a Specification pattern in src/Domain/Specification, providing a unified way to define and compose filtering logic for both SQL queries and in-memory evaluation. The implementation adds a SpecificationInterface with toSql() and toInMemoryFilter() methods, along with abstract base classes (UnaryAbstract, BinaryAbstract) to support logical composition. Concrete classes cover unary operations (UnaryNotSpecification, UnaryIdentitySpecification), binary boolean operators (BinaryAndSpecification, BinaryOrSpecification, BinaryXorSpecification, BinaryNandSpecification, BinaryNorSpecification, BinaryImpliesSpecification), and constant predicates (AlwaysTrueSpecification, AlwaysFalseSpecification). This allows developers to build complex, reusable filter expressions that can be applied consistently across database and application layers.

src/Domain/Specification · high confidence

Introduce SqlDriver plugin with multi-database support

Added a new SqlDriver plugin that provides a unified interface for database operations across InMemory, SQLite, MySQL, and PostgreSQL. The implementation includes an SqlDriverInterface defining methods for CRUD operations (save, findById, deleteById, exists) and querying (findAll, findBy, findOneBy, countBy). Concrete adapters handle database-specific SQL generation, such as upsert strategies for MySQL (ON DUPLICATE KEY UPDATE) and PostgreSQL (ON CONFLICT DO UPDATE), while an abstract base class handles common PDO logic and an in-memory adapter provides a pure-PHP implementation for testing or lightweight use cases.

src/Plugin/SqlDriver · high confidence

Introduce Sync Query Bus and Cached Query Bus adapters

The Query Bus plugin now includes a Sync adapter (SyncQueryBus) that resolves and invokes query handlers via a container, along with a CachedQueryBus decorator that wraps the inner bus to cache responses for CacheableQueryInterface instances using a configurable TTL and cache backend.

src/Plugin/QueryBus/Adapter · high confidence

Introduce User domain model with value objects and events

The demo application now includes a complete User domain layer within the \app/demo/src/User/Domain\ directory. This adds core domain entities and value objects, including \User\, \Email\, \Password\, \HashedPassword\, and \UserGroup\ (with Admin/User roles). It also introduces domain events for authentication lifecycle (\UserAuthenticatedEvent\, \UserLoggedOutEvent\) and a specification-based \EmailSpecification\ for querying. These components are built using the \Phexium\ framework's value object and event abstractions, enforcing strict typing and immutability via PHP 8.4 features like \readonly\ classes.

app/demo/src/User/Domain · high confidence

Introduce application bootstrap and dependency injection configuration

The application now includes a dedicated configuration directory containing the bootstrap script, dependency injection container definitions, routing, and event subscription files. The bootstrap process initializes the Slim application, loads environment variables, configures middleware (including session handling and error reporting), and wires up the DI container. The container definition provides concrete implementations for core services such as command/query buses, transaction management, session storage, logging, and database access, with behavior controlled by environment variables (e.g., selecting SQLite vs. In-Memory repositories or Native vs. Odan sessions). A separate test container overrides specific services like the clock and logger for testing purposes.

app/starter/config · high confidence

Introduce centralized PdoFactory plugin for database connections

A new PdoFactory plugin has been added to centralize the creation of PDO database connections. This change introduces a main factory class that delegates to specific internal implementations for MySQL, PostgreSQL, and SQLite based on the configured database type. Users can now rely on this unified interface to obtain database connections, with the system automatically selecting the correct driver and DSN configuration (including default ports and character sets) from the environment variables.

src/Plugin/PdoFactory · high confidence

Introduce database-agnostic book repository infrastructure

The demo application now includes a structured infrastructure layer for book persistence, featuring an abstract base repository that delegates data access to specific SQL drivers. This change adds concrete repository implementations for MySQL, PostgreSQL, SQLite, and an in-memory adapter, along with a dedicated mapper to handle serialization between domain objects and database rows, enabling the application to switch database backends without altering domain logic.

app/demo/src/Library/Infrastructure · high confidence

Introduce demo application configuration and bootstrap files

The demo application now includes a dedicated configuration directory containing bootstrap, container, routes, events, and permissions files. This setup initializes the Slim application with dependency injection, configures middleware (session, user context, error handling), defines route mappings for books, loans, and authentication, and registers event listeners. The container configuration supports multiple database backends (SQLite, MySQL, PostgreSQL, In-Memory) and cache types (memory, file, Redis) via environment variables, while also setting up test-specific bindings for clock, logging, and password hashing.

app/demo/config · high confidence

Introduce domain Collection system with typed and functional capabilities

The \src/Domain/Collection\ area now provides a new domain-level collection abstraction. \AbstractCollection\ serves as the base implementation, offering standard iteration, counting, and navigation, while \AbstractTypedCollection\ extends it to enforce element type safety via the \Assert\ library during construction and addition. The system supports functional operations (map, filter, reduce, each), search (find, every, some, contains), and transformation (slice, take, sort, reverse, unique) through dedicated traits. It also implements \ArrayAccess\ for bracket-style access with validation, and provides static factory methods (\fromArray\, \fromMap\) for instantiation.

src/Domain/Collection · high confidence

Introduce domain exception abstraction with context and serialization

Added an abstract base class and interface for domain exceptions that standardize error handling by exposing a context array and a structured serialization method. This allows domain errors to carry additional contextual data and be easily converted into arrays for logging or API responses, while adhering to PHP 8.4 standards through the use of readonly properties and the \#\[Override\] attribute.

src/Domain/Exception · high confidence

Introduce extensible mailer plugin with PHPMailer adapter and value objects

The mailer plugin now provides a structured API for sending emails, featuring value objects for messages, email addresses, attachments, and headers, along with a fluent MessageBuilder for constructing emails. It includes a concrete PhpMailerAdapter that integrates with the PHPMailer library to handle SMTP configuration, recipients, content, and attachments, while also providing Null and InMemory adapters for scenarios where actual delivery is not required or for testing purposes.

src/Plugin/Mailer · high confidence

Introduce query caching and handler naming conventions in the Query Bus plugin

The Query Bus plugin now includes internal support for caching query responses and resolving handlers via a standard naming convention. A new QueryCacheKeyGenerator creates cache keys using the xxh128 hash algorithm on serialized query objects, enabling the CachedQueryBus decorator to store and retrieve results. Additionally, the QueryHandlerNamingConvention class provides a consistent way to map query classes to their corresponding handler classes by replacing the 'Query' suffix with 'Handler'.

src/Plugin/QueryBus/Internal · high confidence

Introduce session plugin with native and Odan adapters

The session plugin now provides a unified session management interface via \SessionInterface\ and \FlashInterface\, allowing applications to manage session data and flash messages through a consistent API. Two adapter implementations are included: \NativeSession\ and \NativeFlash\, which wrap PHP's native \$\_SESSION\ and cookie handling with zero external dependencies, and \OdanSession\ and \OdanFlash\, which adapt the Odan Session library for users preferring that abstraction. This change enables flexible session handling strategies within the plugin system.

src/Plugin/Session · high confidence

Introduce synchronous event bus plugin with PSR-14 listener support

A new EventBus plugin is available, providing a synchronous adapter (SyncEventBus) that implements the EventBusInterface. This adapter delegates event dispatching to a PSR-14 compliant dispatcher and manages listener subscriptions via a ListenerRegistry, enabling immediate, in-process event handling with debug logging for dispatched domain events.

src/Plugin/EventBus · high confidence

Introduce transaction plugin with in-memory and SQL adapters

A new transaction plugin has been added, providing a \TransactionInterface\ that allows applications to manage database transactions. The plugin includes an \InMemoryTransaction\ adapter for testing or non-persistent scenarios, and SQL adapters for MySQL, PostgreSQL, and SQLite that wrap PDO connections to support \begin\, \commit\, and \rollback\ operations.

src/Plugin/Transaction · high confidence

Introduce user authentication and session management commands and handlers

The demo application now includes the application-layer components for user login and logout. This adds command handlers for authenticating users (verifying credentials and dispatching an authentication event) and logging out users (dispatching a logout event). Event listeners are provided to manage the user session: storing user details in the session upon authentication and clearing the session upon logout. Additionally, a simple login query handler is included to return a response based on the provided email.

app/demo/src/User/Application · high confidence

Introduces application-layer use-case and command/query abstractions

The application layer now provides a structured set of interfaces to standardize how business logic is invoked and how data is returned. This includes a generic UseCase pattern (UseCaseInterface, UseCaseRequestInterface, UseCaseResponseInterface) and specific contracts for the Command and Query buses (CommandInterface, CommandHandlerInterface, QueryInterface, QueryHandlerInterface, QueryResponseInterface). Additionally, a CacheableQueryInterface is introduced, allowing queries to define their own cache TTL, enabling caching support for specific read operations.

src/Application · high confidence

Introduction of centralized datetime format constants

A new DateTimeFormat constant class has been added to the domain layer, providing standardized format strings for SQL datetime, date, and time values. This change centralizes date-time formatting definitions, ensuring consistent usage across the application for database interactions.

src/Domain/Constant · high confidence

Introduction of domain event abstraction with unique identification

The domain layer now includes a new \DomainEventInterface\ and an abstract \DomainEventAbstract\ base class to standardize how domain events are structured. This change introduces a unique \eventId\ (via \IdInterface\) to every event, enabling deduplication capabilities, alongside standard metadata like \occurredOn\ and \aggregateId\. The implementation enforces modern PHP 8.4 standards by using readonly properties and the \\#\[Override\]\ attribute, ensuring a consistent and type-safe foundation for all future domain events.

src/Domain/Event · high confidence

Library book management commands and handlers

The demo application now includes a complete set of command objects and their corresponding handlers for managing books within the library domain. Users can create, update, delete, and change the status of books through dedicated command classes (CreateBookCommand, UpdateBookCommand, DeleteBookCommand, UpdateBookStatusCommand) and their respective handlers. These handlers implement the command bus pattern using the \_\_invoke() method, interacting with the BookRepository to persist changes and dispatching domain events (BookCreatedEvent, BookUpdatedEvent, BookDeletedEvent) via the EventBus. The UpdateBookStatusHandler specifically handles status transitions between 'Borrowed' and 'Available' states.

app/demo/src/Library/Application/Command · high confidence

Loan application commands and queries implemented

The demo loan application now supports borrowing and returning books, as well as listing loans. Borrowing a book checks availability and creates a loan with a calculated due date, while returning a book validates ownership and marks the loan as returned. Users can view their personal loans or browse all available books. Additionally, the system provides a paginated list of all loans with details such as borrower, book, status, and due dates.

app/demo/src/Loan/Application · high confidence

New API controllers for creating, listing, and viewing books

This change introduces three new API endpoints within the demo library's presentation layer: creating a book (CreateBookController), listing books with pagination support (ListBooksController), and retrieving details for a specific book (DetailBookController). These controllers handle HTTP requests by dispatching commands and queries through the application's bus system, utilizing specific JSON presenters to format responses and managing errors such as unexpected query responses or validation failures.

app/demo/src/Library/Presentation/Api · high confidence

New ID generator plugin with multiple format adapters

The system now includes a new ID generator plugin located in src/Plugin/IdGenerator that provides adapters for generating and parsing UUID v4, UUID v7, ULID, and Timestamp IDs. This plugin introduces an IdGeneratorInterface port and specific adapter implementations (UuidV4Generator, UuidV7Generator, UlidGenerator, TimestampIdGenerator) that leverage the Ramsey/Uuid library for UUID generation and custom logic for timestamp-based IDs, allowing users to generate unique identifiers in various standard formats.

src/Plugin/IdGenerator · high confidence

New Phexium CLI installer and coverage report header customization

Developers can now use the new \tools/phexium.php\ CLI tool to install the Phexium framework into their current directory via the \install\ command. Additionally, a new \tools/coverage-customize-header.php\ script allows customizing the header of php-code-coverage HTML reports by injecting links to the official documentation and GitLab repository.

tools · high confidence

New demo application scaffolding with database schemas and presentation layer

The repository now includes a new demo application under app/demo, providing a complete library management example. This addition introduces database schema definitions for MySQL, PostgreSQL, and SQLite, along with YAML fixtures for initial data seeding. The application's presentation layer includes request objects for creating and updating books and borrowing loans, validators for book fields, and services for rendering status badges. A public entry point and a landing page linking to both the starter and demo applications are also included.

(repo-wide) · high confidence

New domain ID value objects (UUID, ULID, TimestampId)

The \src/Domain/Id\ directory now provides a set of value objects for domain identifiers, including \UuidV4\, \UuidV7\, \Ulid\, and \TimestampId\, all implementing the new \IdInterface\. These classes offer a consistent API for creating IDs from strings or integers, retrieving their raw values, and comparing them for equality. The UUID and ULID implementations leverage the \ramsey/uuid\ and \tuupola/base32\ libraries to handle validation and encoding, while \TimestampId\ provides a simple integer-based identifier.

src/Domain/Id · high confidence

New domain abstractions and value objects

The domain layer now includes base abstractions for value objects (AbstractIntValueObject, AbstractStringValueObject) and entities (EntityAbstract), along with corresponding interfaces (ValueObjectInterface, EntityInterface) and an enum abstraction (EnumInterface, EnumTrait). A new Pagination value object has been added to handle page calculations, including a safe offset calculation using max(). These changes provide standardized ways to define immutable value objects, compare entities by ID, and manage pagination logic within the domain.

src/Domain · high confidence

Behavioural changes

Homepage now displays a personalized greeting and message of the day

The homepage presentation layer has been restructured to use a dedicated use case and presenter. When a user visits the homepage, the system now passes their email (if authenticated) to a use case that generates a personalized greeting (e.g., "Welcome, [e-mail redacted]") or a generic welcome message. The presenter formats the current date and time and passes these along with a static "Message of the day" to the Twig template. The template conditionally displays the message and current time in an info alert only if the user is authenticated, while always showing the greeting and navigation links to log in or browse books.

app/demo/src/Homepage · high confidence

Introduce RBAC middleware and user context for permission-based navigation

The demo application now enforces role-based access control through a new \RbacPermissionMiddleware\ that validates permissions via a \UserContext\ attached to the request. This context is populated by a \UserContextMiddleware\ and \UserContextProvider\, which load user data from the session and check permissions against the underlying authorization service. On the presentation layer, the shared Twig header template now conditionally renders navigation links (such as 'My Loans', 'Borrow', and 'All Loans') based on the authenticated user's status and specific permissions (e.g., \loan.view\_all\), while Twig extensions (\ConnectedUserExtension\, \PermissionExtension\) expose these checks to templates.

app/demo/src/Shared · high confidence

New typed database driver implementations for the User repository

The demo application now includes concrete User repository implementations for MySQL, PostgreSQL, SQLite, and in-memory storage. These classes extend a new AbstractUserRepository that centralizes data access logic using a SqlDriverInterface, allowing the application to switch between different database backends by injecting the corresponding driver (MysqlDriver, PostgresqlDriver, SqliteDriver, or InMemoryDriver) along with a UserMapper for data transformation.

app/demo/src/User/Infrastructure · high confidence

Nginx service containerized with hardened configuration and multi-environment support

The Nginx service is now delivered via a dedicated Dockerfile based on Alpine 3.23, replacing previous external orchestration for health checks. This update introduces a hardened security posture by disabling server tokens, enforcing TLS 1.2/1.3, and restricting access to hidden files. It also adds support for distinct virtual hosts for 'demo' and 'starter' environments, enabling PHP-FPM processing for these specific applications while maintaining a default root for general static content.

docker/service/nginx · high confidence

Restructured loan repository infrastructure with pagination and SQL details support

The loan repository implementation has been refactored into a layered structure: an abstract base repository handles standard CRUD operations, while a new abstract SQL repository and concrete implementations for MySQL, PostgreSQL, and SQLite provide optimized queries for retrieving loans with book and user details. The in-memory repository has been updated to support pagination via offset and limit parameters and now exposes a reset method for test isolation. A dedicated mapper handles serialization between domain objects and database rows, and the in-memory driver is now held as a typed reference to improve type safety.

app/demo/src/Loan/Infrastructure · high confidence

Standardized runtime directories under var/

The application now uses a standardized directory structure for runtime data, with dedicated folders for cache, database, and log files located under the var/ root. This change ensures that temporary and persistent data are isolated from the source code, simplifying deployment and maintenance by keeping these directories version-controlled via .gitkeep files.

var · high confidence

Test coverage

Acceptance tests for CleanShelf demo application; Added acceptance and unit tests for the starter application homepage; Added acceptance test traits for the AppDemo application; Added fake cache implementation for testing; Added fake command and query test fixtures; Added fake implementations for event dispatcher testing; Added fake presentation test doubles; Added fake service implementations for testing; Added test doubles for CommandBus and Transaction plugins; Added test doubles for domain events and event listeners; Added test fakes and spies for the session plugin; Added test fixture object mothers for Book, Loan, and User; Added test fixtures for QueryBus plugin; Added test fixtures for Specification pattern; Added test fixtures for domain abstractions; Added test helper for HTTP request handling; Added test infrastructure for coverage merging and slow-test detection; Added unit and integration tests for Plugin components; Added unit and integration tests for the Library and Loan components; Added unit tests for Presentation component classes; Added unit tests for domain components.

Dependencies

Initial project setup with core dependencies

This change introduces the initial composer configuration for the Phexium framework, establishing the project's dependency baseline. It adds core runtime packages including Slim 4 for HTTP routing, Twig 3 for templating, PHP-DI 7 for dependency injection, and PHPMailer 7 for email handling, alongside supporting libraries like beberlei/assert and vlucas/phpdotenv. Development dependencies are also configured, including Pest 4 and PHPUnit for testing, PHPStan 2 for static analysis, and Deptrac for architecture validation.

(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 63 → 63 (+0.3)
  • Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 99 → 99 (+0.1)
  • Architecture 100 → 84 (-15.7)
  • Maturity 64 → 60 (-3.7)
  • Readiness 50 → 56 (+6.2)
  • Security 67 → 78 (+11.7)
  • Domain Modelling 100 → 100 (+0.0)
  • Accessibility 68 (new)

Resolved (33)

  • A robots.txt file exists but it is a thin 'User-agent: * Allow: / Sitemap' file with no human-relevant information, serving only as an sitemap pointer rather than adding value. (docs/robots.txt)
  • 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 (10 lines × 2) (app/demo/src/Homepage/Presentation/Http/HomeController.php)
  • Duplicated block (11 lines × 2) (tools/install/Installer.php)
  • Duplicated block (14 lines × 2) (app/demo/src/Library/Presentation/Http/DetailBookController.php)
  • Duplicated block (15 lines × 2) (app/demo/src/Library/Presentation/Http/CreateBookController.php)
  • Duplicated block (15 lines × 2) (src/Plugin/Cache/Adapter/FileCache.php)
  • Duplicated block (9 lines × 2) (app/demo/src/Library/Presentation/Api/ListBooksController.php)
  • Duplicated block (9 lines × 4) (app/demo/src/Loan/Presentation/Http/BorrowBookController.php)
  • Low CVE: [GHSA redacted] (composer.lock)
  • Low: security finding (details withheld)
  • Low: security finding (details withheld)
  • Medium CVE: [GHSA redacted] (composer.lock)
  • Medium IaC: CKV_DOCKER_3 (docker/service/mailpit/Dockerfile)
  • Medium IaC: CKV_DOCKER_3 (docker/service/mysql/Dockerfile)
  • Medium IaC: CKV_DOCKER_3 (docker/service/nginx/Dockerfile)
  • Medium IaC: CKV_DOCKER_3 (docker/service/php/Dockerfile)
  • Medium IaC: CKV_DOCKER_3 (docker/service/postgres/Dockerfile)
  • …and 13 more

New (41)

  • Critical CVE: [GHSA redacted] (composer.lock)
  • Documentation: no installation or build instructions
  • Documentation: no installation or build instructions (README.md)
  • Documentation: no installation or build instructions (docs/plugins/mailer.md)
  • Documentation: no installation or build instructions (docs/plugins/password-hasher.md)
  • Documentation: no installation or build instructions (docs/plugins/pdo-factory.md)
  • Documentation: no installation or build instructions (docs/plugins/query-bus.md)
  • Documentation: no project overview
  • Duplicated block (11 lines × 2) (tools/install/Installer.php)
  • Duplicated block (12 lines × 2) (app/demo/src/Homepage/Presentation/Http/HomeController.php)
  • Duplicated block (13 lines × 2) (src/Plugin/Cache/Adapter/FileCache.php)
  • Duplicated block (15 lines × 2) (app/demo/src/Library/Presentation/Http/CreateBookController.php)
  • Duplicated block (16 lines × 2) (app/demo/src/Library/Presentation/Http/DetailBookController.php)
  • Duplicated block (7 lines × 2) (src/Domain/AbstractIntValueObject.php)
  • Duplicated block (7 lines × 2) (src/Plugin/Cache/Adapter/FileCache.php)
  • Duplicated block (7 lines × 3) (app/demo/src/Library/Infrastructure/AbstractBookRepository.php)
  • Duplicated block (9 lines × 2) (app/demo/src/Library/Presentation/Api/ListBooksController.php)
  • Duplicated block (9 lines × 2) (src/Plugin/SqlDriver/Adapter/MysqlDriver.php)
  • Duplicated block (9 lines × 4) (app/demo/src/Loan/Presentation/Http/BorrowBookController.php)
  • Low CVE: [GHSA redacted] (composer.lock)
  • …and 21 more

Changes since last survey

  • 6 commits — 5 feature/other, 1 fixes

By area

  • src/Presentation — 2 commits
  • app/demo — 1 commit
  • docs/blog — 1 commit
  • src/Plugin — 1 commit
  • tests/Phexium — 1 commit

Notable commits

  • fix: fix(presentation)!: make ResponseBuilder immutable
  • change: docs(blog): add post on who can dispatch on the CQRS bus
  • change: feat(presentation)!: add withRaw() to the response builder
  • change: refactor(presentation)!: add Body suffix to withHtml and withJson
  • change: refactor(presentation): delegate withHtml and withJson to withRaw
  • change: refactor: replace sprintf with string interpolation

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

Survey your own repository

phexium/framework 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 ba8058ae0a3dba85685d2b8286e2250bfae5c07e — 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.