johnnickell/fight-common

A shared PHP library for Hexagonal Architecture, CQRS, and reusable domain primitives

Maintainers

Package info

github.com/johnnickell/fight-common

pkg:composer/johnnickell/fight-common

Transparency log

Statistics

Installs: 164

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

1.1.0 2026-06-04 15:42 UTC

README

Tests PHP 8.5+ License: MIT Version PHPStan

A shared PHP library for projects implementing Hexagonal (Ports & Adapters) / Clean Architecture. Provides foundational building blocks including value objects, typed collections, CQRS messaging, a composable validation system, and infrastructure adapters.

Documentation · Quick Start · Changelog

Requirements

  • PHP 8.5+
  • Docker (for local tooling)

Installation

composer require johnnickell/fight-common

Optional adapters require additional packages — install only what you need:

composer require doctrine/orm           # Doctrine data types and unit of work
composer require doctrine/dbal          # Database health check and nonce replay prevention
composer require symfony/http-kernel    # HTTP middleware and JSend response
composer require lcobucci/jwt           # JWT encoder and decoder
composer require guzzlehttp/guzzle      # HTTP client adapter

Architecture

Dependencies flow inward only. The Domain has no external dependencies. The Application layer depends on Domain interfaces only. Adapters depend on both.

Domain      ← pure business logic, no framework dependencies
Application ← orchestrates domain via interfaces
Adapter     ← concrete infrastructure implementations

What's Inside

Domain

Value Objects — immutable, self-validating objects that model domain concepts:

  • StringObject, MbStringObject, JsonObject — string and JSON primitives
  • EmailAddress, Uri, Url — internet value types with RFC-compliant validation
  • Uuid, UniqueId, MessageId — identifier types with multiple creation strategies

Specifications — composable business rules:

$rule = $isActive->and($hasVerifiedEmail)->and($isNotBanned->not());
$rule->isSatisfiedBy($user); // true or false

Collections — fully typed collection hierarchy:

  • ArrayList — ordered list with sort, slice, pagination, and predicate search
  • HashSet — set operations: union, intersection, difference, complement
  • HashTable — key-value map with typed keys and values
  • SortedSet / SortedTable — ordered structures backed by a Red-Black tree with floor, ceiling, rank, and range operations
  • ArrayStack, LinkedStack, ArrayQueue, LinkedQueue, LinkedDeque — typed stack and queue structures

Messaging — CQRS message contracts:

  • CommandMessage, QueryMessage, EventMessage with Meta support
  • Serializable to/from array and JSON

Repository — pagination and result set contracts:

  • Pagination — page, perPage, orderings
  • ResultSet — paginated records with total count and page metadata

Application

Validation — rule-based field validation:

$service->validate([
    ['field' => 'email',    'label' => 'Email',    'rules' => 'required|email'],
    ['field' => 'username', 'label' => 'Username', 'rules' => 'required|min_length[3]|max_length[20]'],
], $input);

CQRS BusesCommandBus and QueryBus with pipeline middleware support.

Observability — application-layer ports for health checks, metrics, and audit logging:

  • HealthAggregator / HealthCheck — compose N checks into a HealthReport (overall status, per-check results)
  • MetricsCollectorincrement, gauge, histogram with tag support; bus middleware auto-instruments handlers
  • AuditLog / AuditRepository — structured business-fact records (actor, action, timestamp, context); queryable by actor, action, or time range

SerializersJsonSerializer and PhpSerializer for message serialization.

Container — PSR-11 compatible service container with singleton and factory registration.

Adapters

Adapter Requires
Doctrine data types (Uuid, Uri, Url, StringObject, JsonObject, etc.) doctrine/dbal
DoctrineUnitOfWork doctrine/orm
SimpleEventDispatcher, ServiceAwareEventDispatcher
RoutingCommandBus, RoutingQueryBus
MetricsCommandFilter, MetricsQueryFilter
HealthReporter, DatabaseHealthCheck doctrine/dbal
HttpEndpointHealthCheck any HttpClient adapter
NullMetricsCollector, NullAuditLog
StatsDMetricsCollector ext-sockets
LoggingAuditLog any PSR-3 logger
HmacAuthenticator, HmacRequestService, HmacWebhookDispatcher
InMemoryNonceRepository
DoctrineNonceRepository doctrine/dbal
PhpPasswordHasher, PhpPasswordValidator
JwtEncoder, JwtDecoder lcobucci/jwt
JsonRequestMiddleware, JSendResponse symfony/http-foundation
SymfonyFilesystem symfony/filesystem
EventSubscriberCompilerPass symfony/dependency-injection

Development

All tooling runs inside a PHP 8.5 Docker container via scripts in ./bin/. Never use vendor/bin/ directly.

./bin/phpunit                  # complete suite with disposable MySQL/PostgreSQL and coverage
./bin/phpunit --fast            # fast suite; excludes server-database tests and is not submit evidence
./bin/phpunit --filter foo     # filter the complete suite by test name
./bin/rector process src/      # run code modernization
./bin/deptrac                  # enforce inward architecture and complete classification
./bin/composer require pkg     # manage dependencies

The complete PHPUnit command creates disposable MySQL 8.4.11 and PostgreSQL 17 containers, injects their DSNs, and removes the containers and isolated network on success, failure, or interruption. Missing or unreachable complete-suite database infrastructure is a failure, never a skipped test. Use --fast only for deliberately focused local feedback; it is not submit or release evidence.

Coverage

100% code coverage is required and enforced by PHPUnit configuration. All test classes must declare #[CoversClass].

License

MIT