dersonsena/clean-arch-pokemon
57.9
Adequate · 22 September 2026
5k
lines of production code
PHP
primary language
7
measurements over time
What this system is
This is a PHP-based web application built on the Slim framework, designed to manage player profiles, battle systems, and an in-game market. It implements domain-driven design principles with distinct bounded contexts for players, battles, and market items, each containing their own domain models, use cases, and repository adapters. The system supports core game mechanics such as initiating battles, managing player inventories and Pokédex entries, and processing item purchases with strict validation and error handling.
How it got here
2020 — Initial project scaffolding and domain modeling
20 changes.
The period marks the initial setup of the project's development environment and the creation of core domain models for players, battles, and the market system. It establishes the foundational architecture, including repository interfaces, factory classes, and use cases, while defining the database schema and application configuration.
2021 — Marketplace and domain feature implementation
11 changes.
This period focused on implementing the core functionality for the Market and Battle domains, including HTTP actions, repository adapters, and use cases for creating, updating, and deleting items. The work also established shared infrastructure for database drivers, HTTP clients, and templating, alongside foundational helper classes and unit tests to support these new features.
Features
Added DeleteItem use case for removing market items
Introduced a new DeleteItem use case that allows users to remove items from the market. The implementation includes the main DeleteItem class, which coordinates with the ItemRepository to delete an item by its ID, and defines InputBoundary and OutputBoundary DTOs to handle the deletion request and the resulting item data.
src/Market/UseCases/DeleteItem · high confidence
Added StartBattle use case to initiate player battles
The application now supports starting a battle between two players. This change introduces the StartBattle use case, which validates input for trainer and challenger details, retrieves the respective Pokémon, and initiates the battle state. The implementation includes input/output boundary classes to handle the request and response data, a validator to ensure required fields like trainer ID and Pokémon aliases are present and meet length requirements, and the main StartBattle class that orchestrates the interaction with player, battle, and Pokédex repositories to establish the battle.
src/Battle/UseCases/StartBattle · high confidence
Added domain entities for the market system
Introduced new domain classes to support the market feature: the Cart and CartItem entities manage the user's shopping cart, while the Item entity represents marketable goods with properties like name, price, and salability. Additionally, a Category value object was added to categorize items, specifically supporting 'DEFAULT' and 'POKEBALL' types.
src/Market/Domain · high confidence
Added domain factories for Cart, CartItem, and Item
New factory classes (CartFactory, CartItemFactory, ItemFactory) were added to the Market domain to handle the creation and population of Cart, CartItem, and Item domain objects. These factories manage type casting and object instantiation, such as converting price and quantity values to floats and integers, and mapping category strings to ValueObjects, providing a consistent way to construct these domain entities.
src/Market/Domain/Factory · medium confidence
Added domain factories for Player, Bag, and Party
Introduced new factory classes (PlayerFactory, BagFactory, PartyFactory) in the Player domain to handle object creation and data mapping. PlayerFactory specifically manages the creation of Player entities, including the initialization of associated Bag and Party objects, and handles type casting for fields like id, xp, and money.
src/Player/Domain/Factory · high confidence
Added domain layer base classes and value objects
Introduced a new domain layer in the shared package, starting with a base Entity class that provides common functionality like ID management, bulk property assignment via a fill method, and serialization to arrays or JSON. Additionally, a Gender value object was added to enforce valid gender constants (MALE, FEMALE) with validation.
src/Shared/Domain · high confidence
Added domain models for the battle system
Introduced the core domain entities for the battle system, including the \Battle\ class to track match state, a \BattleFactory\ for object creation, and value objects for \BattleStatus\ and \BattlePokemon\. These components provide the foundational data structures for managing battle sessions, including trainer assignments, XP/money tracking, and status updates.
src/Battle/Domain · high confidence
Added new domain exception classes for player and Pokemon limits
Two new exception classes were introduced to the Player domain: PlayerNotFoundException, which extends AppValidationException to handle missing player scenarios, and PokemonLimitExceededException, which extends DomainException to enforce Pokemon collection limits. These changes support the application's validation and error handling logic for these specific domain rules.
src/Player/Domain/Exceptions · high confidence
Added profile page templates in Blade and Twig
New profile page views have been introduced for both the Blade and Twig templating engines. These templates render a profile page displaying the user's first and last names, providing a consistent UI structure across different template implementations.
views · medium confidence
Added shared helper classes for DTOs, enums, and strings
New shared helper classes have been introduced to standardize common patterns across the application. The \DTO\ class provides a base for data transfer objects, automatically mapping snake\_case keys to camelCase properties and offering a \build\ factory method and \toArray\ serialization. The \Enum\ abstract class offers a reusable base for enumerations with an \items()\ reflection method. Additionally, a \StringHelper\ utility was added, featuring a \slugify\ method for generating URL-friendly slugs from text.
src/Shared/Helpers · high confidence
Added use cases for creating and updating market items
Introduced the CreateItem and UpdateItem use cases, each with their respective input and output boundary classes. The CreateItem use case handles item creation by validating input, creating an item via the ItemFactory, and persisting it through the ItemRepository. The UpdateItem use case follows a similar pattern, allowing for the modification of existing items. Both use cases are now available for interacting with the market's item management functionality.
src/Market/UseCases/CreateItem · high confidence
Adds infrastructure implementations for database drivers, HTTP clients, caching, validation, and payload presentation
The \src/Shared/Infra\ directory now includes concrete implementations for several core interfaces: \MySQLDriver\ and \PostgresDriver\ for database access, \GuzzleHttpClient\ for HTTP requests, \PRedisClient\ for caching, \RespectValidation\ for data validation, and \TwigEngine\ for template rendering. Additionally, the \Presentation\ subdirectory introduces \CsvPresenter\, \JsonPresenter\, and \XmlPresenter\ to handle different response formats, orchestrated by a new \PresenterFactory\ that selects the appropriate presenter based on the request's \Accept\ header.
src/Shared/Infra · high confidence
HTTP adapters for Market item operations
Added HTTP action classes to handle Market item operations, including CreateItemAction, UpdateItemAction, DeleteItemAction, GetItemAction, ItemsListAction, and PurchaseAction. These new files implement the HTTP layer for creating, updating, deleting, retrieving, and listing market items, as well as processing purchases.
src/Market/Adapters/Http · high confidence
Implemented repository adapters for market items and purchases
Added new repository implementations for the Market bounded context. The \ItemRepository\ provides standard CRUD operations (create, read, update, delete) for market items, utilizing query builders for database interactions. The \MarketRepository\ introduces a \purchase\ method that handles the transactional logic for buying items, including validating player funds, inserting cart data, and updating player inventory. These changes enable the application to persist and retrieve market-related data and process purchases.
src/Market/Adapters/Repository · high confidence
Initial application configuration and routing setup
The application is now configured with a central config file defining external API endpoints, template presentation settings, database connection parameters, and cache system settings. A dependency injection container is established to wire up repositories, adapters, and shared services like the HTTP client, database driver, and cache system. Additionally, HTTP routes are defined for player profiles, the Pokédex search, market item management (CRUD operations), and the start battle action, mapping HTTP requests to their respective action classes.
config · high confidence
Initial database schema and seed data for core game entities
The database now includes initial migration files and seeders to establish the foundational tables for players, battles, Pokémon, the Pokédex, and the shopping system (cart, cart items, and mart items). This provides the necessary data structure and initial test data for these core game mechanics.
db · high confidence
Initial project scaffolding with PHP, Docker, and testing infrastructure
The repository is initialized with a complete development environment setup. This includes a Docker Compose configuration that provisions MySQL 5.7, PostgreSQL 11, PgAdmin 4, and Redis 4.0 as backend services. The project also introduces PHINX for database migrations, PHPUnit for unit testing, and standard configuration files (.editorconfig, .env.sample, .gitignore) to support the Slim Framework application.
(repo-wide) · high confidence
Initial public entry point for Slim framework application
The public/index.php file has been added to serve as the entry point for the application, initializing the Slim framework with a configured dependency injection container. This setup loads environment variables, defines application constants (including debug and cache settings), and wires up error handling and routing configurations.
public · high confidence
Introduce HTTP actions and repository adapters for Battle and Player domains
New HTTP action classes are added to handle incoming requests for starting a battle and retrieving player profile information. The Battle domain now includes a StartAction that maps HTTP payloads to a StartBattle use case, while the Player domain introduces ProfileAction and ProfilePageAction to serve profile data and templates. Additionally, new repository adapters (BattleRepository, PlayerRepository) are implemented to persist and retrieve battle and player data, supporting the new use cases.
src/Battle/Adapters, src/Player/Adapters · medium confidence
Introduce Pokedex domain models and repository interfaces
The Pokedex module now includes domain entities for Pokedex, Pokemon, and Type, along with their respective repository interfaces and concrete implementations. This establishes the data structures and persistence contracts required to track a player's Pokedex, including marking Pokémon as seen or captured, and searching for Pokémon by various criteria.
src/Pokedex · high confidence
Introduce purchase use case with input/output boundaries and validation
The purchase feature is now implemented with a dedicated use case class that orchestrates the buying process. It includes an InputBoundary to capture player and item data, an OutputBoundary to return player state, and a PurchaseValidator that enforces strict type and presence checks on item IDs, prices, quantities, and totals. This structure ensures that all purchase requests are validated before interacting with repositories, providing a clear, typed interface for the purchase workflow.
src/Market/UseCases/Purchase · high confidence
Introduce shared exception hierarchy and specific error types
Adds a new exception handling structure in the shared layer, including an abstract AppException base class and an AppExceptionBase interface that defines standard error types (INTERNAL\_ERROR, INVALID\_INTEGRATION, INVALID\_INPUT). This enables consistent error handling across the application. Additionally, specific exception classes are introduced: AppValidationException for invalid input errors, RuntimeException for unexpected internal errors, and InvalidGenderException for gender validation failures.
src/Shared/Exceptions · high confidence
Introduces BattleRepository interface for battle use cases
A new interface, BattleRepository, has been added to define the contract for battle-related operations. This interface specifies a start method that accepts two BattlePokemon instances and returns a Battle object, establishing the expected behavior for battle use cases.
src/Battle/UseCases/Contracts · high confidence
Introduces core Player domain entities
The Player domain now includes new entity classes: Player, Bag, and Party. The Player entity tracks name, avatar, gender, XP, and money, and manages references to the Bag and Party. The Bag entity stores items and pokeballs, while the Party entity manages a collection of Pokemons with a limit of 8. These changes establish the foundational data structures for player state and inventory management.
src/Player/Domain · high confidence
Introduces structured database query builders and HTTP action handlers
The application now provides a structured way to build and execute SQL queries for MySQL and PostgreSQL databases, alongside standardized HTTP action handlers for JSON and template responses. Developers can now use the new \SelectStatement\, \InsertStatement\, \UpdateStatement\, and \DeleteStatement\ interfaces to construct database operations, with specific implementations for MySQL and PostgreSQL. Additionally, the \PayloadAction\ and \TemplateAction\ abstract classes standardize how HTTP requests are processed and how responses (JSON or HTML templates) are rendered, simplifying the creation of new API endpoints and web pages.
src/Shared/Adapters · high confidence
Behavioural changes
Introduced PlayerRepository interface for player data access
Added a new PlayerRepository interface in the UseCases/Contracts directory, defining methods for retrieving player data, debiting money, adding items to a bag, and fetching profile information. This establishes a contract for player-related use cases to interact with the data layer.
src/Player/UseCases/Contracts · high confidence
Introduces repository contracts for market items and market operations
New interface contracts are added to define data access for market-related entities. The \ItemRepository\ interface specifies methods for retrieving, inserting, updating, and deleting market items. The \MarketRepository\ interface defines operations for purchasing items, retrieving individual items, and fetching lists of market items. These contracts establish the API for market use cases.
src/Market/UseCases/Contracts · high confidence
MySQL container configuration updated with custom settings
A new custom MySQL configuration file (custom-my.cnf) has been added to the Docker environment, introducing specific performance and timeout adjustments. This includes increasing the maximum allowed packet size to 512M, setting InnoDB log buffer and file sizes to 32M and 2047M respectively, and configuring network timeouts and name resolution settings for the MySQL service.
.docker · high confidence
New domain exceptions for the purchase flow
Four new exception classes have been added to the market domain to handle specific failure scenarios during a purchase. CreatePurchaseException and InsufficientMoneyException extend AppException to handle general and monetary failures, while InvalidItemCategoryException extends DomainException to handle invalid item categories. Additionally, MartItemNotFoundException extends AppValidationException to handle missing items. These changes introduce new error handling paths for the purchase use case.
src/Market/Domain/Exceptions · medium confidence
Test coverage
Added unit tests for the MySQL Select query builder
Added unit tests for the MySQL Select query builder, covering SQL generation for select, from, where, order by, group by, and limit clauses. Also added a bootstrap file to configure the test environment and autoload the composer dependencies.
tests · high confidence
Dependencies
Initial project setup with PHP 7.4+ and core dependencies
The project is initialized with a composer.json defining PHP 7.4+ and a set of core dependencies including Slim 4.x, Guzzle 7.x, PHPUnit 9.3, and various utility libraries (e.g., vlucas/phpdotenv, robmorgan/phinx, predis/predis). This establishes the foundational environment for the application.
(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
Score
- CAI 53 → 58 (+5.0)
- Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.
Lenses
- Code Health 98 → 98 (+0.4)
- Architecture 100 → 82 (-18.5)
- Maturity 65 → 65 (+0.0)
- Readiness 26 → 38 (+12.1)
- Security 82 → 89 (+7.6)
Resolved (26)
- Coverage not included — suite not readable by the collector
- Critical CVE: [GHSA redacted] (composer.lock)
- Critical CVE: [GHSA redacted] (composer.lock)
- Dependency hygiene not measured — dependency manifest found but not parsed for hygiene
- Duplicated block (10 lines × 2) (src/Market/Domain/Factory/CartItemFactory.php)
- Duplicated block (10 lines × 3) (src/Market/Domain/Factory/ItemFactory.php)
- Duplicated block (11 lines × 2) (src/Shared/Adapters/QueryBuilder/MySQL/Delete.php)
- Duplicated block (13 lines × 2) (src/Shared/Adapters/Http/PayloadAction.php)
- Duplicated block (13 lines × 2) (src/Shared/Adapters/QueryBuilder/MySQL/Select.php)
- Duplicated block (13 lines × 2) (src/Shared/Adapters/QueryBuilder/MySQL/Update.php)
- Duplicated block (13 lines × 2) (src/Shared/Infra/Drivers/MySQLDriver.php)
- Duplicated block (14 lines × 2) (src/Shared/Adapters/QueryBuilder/MySQL/Insert.php)
- Duplicated block (14 lines × 2) (src/Shared/Adapters/QueryBuilder/MySQL/Insert.php)
- High CVE: [GHSA redacted] (composer.lock)
- High CVE: [GHSA redacted] (composer.lock)
- High CVE: [GHSA redacted] (composer.lock)
- LLM evaluation failed
- Medium CVE: [GHSA redacted] (composer.lock)
- Medium CVE: [GHSA redacted] (composer.lock)
- Medium CVE: [GHSA redacted] (composer.lock)
- …and 6 more
New (41)
- Critical CVE: [GHSA redacted] (composer.lock)
- Critical CVE: [GHSA redacted] (composer.lock)
- Documentation: no usage examples (README.md)
- Duplicated block (11 lines × 4) (src/Shared/Adapters/QueryBuilder/MySQL/Delete.php)
- Duplicated block (13 lines × 3) (src/Pokedex/Adapters/Repository/PokemonRepository.php)
- Duplicated block (14 lines × 2) (src/Shared/Adapters/Http/PayloadAction.php)
- Duplicated block (19 lines × 2) (src/Shared/Adapters/QueryBuilder/MySQL/Update.php)
- Duplicated block (20 lines × 2) (src/Shared/Adapters/QueryBuilder/MySQL/Insert.php)
- Duplicated block (20 lines × 2) (src/Shared/Infra/Drivers/MySQLDriver.php)
- Duplicated block (25 lines × 2) (src/Shared/Adapters/QueryBuilder/MySQL/Insert.php)
- Duplicated block (36 lines × 2) (src/Shared/Adapters/QueryBuilder/MySQL/Select.php)
- Duplicated block (41 lines × 3) (src/Market/UseCases/CreateItem/OutputBoundary.php)
- Duplicated block (7 lines × 2) (src/Shared/Adapters/QueryBuilder/MySQL/Select.php)
- Duplicated block (7 lines × 2) (src/Shared/Adapters/QueryBuilder/MySQL/Update.php)
- Duplicated block (9 lines × 2) (src/Market/Domain/Factory/CartItemFactory.php)
- Duplicated block (9 lines × 2) (src/Shared/Adapters/QueryBuilder/MySQL/Select.php)
- Duplicated block (9 lines × 2) (src/Shared/Adapters/QueryBuilder/MySQL/Select.php)
- Duplicated block (9 lines × 3) (src/Market/Domain/Factory/ItemFactory.php)
- High CVE: [GHSA redacted] (composer.lock)
- High CVE: [GHSA redacted] (composer.lock)
- …and 21 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
dersonsena/clean-arch-pokemon 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 c187b9dafff57a34b2683634ae71b907859be0e0 — 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.