Skip to content

Contracts

Alle Interfaces der Jardis-Plattform, ein Package, null Implementierung.

Einführung

In einer hexagonalen Architektur hängt alles an den Interfaces: Domain-Code importiert nur Contracts, Adapter implementieren sie, und zur Bootzeit wird verdrahtet. Wenn diese Interfaces über dutzende Packages verstreut sind, entstehen zirkuläre Abhängigkeiten und Release-Chaos.

jardissupport/contracts löst das radikal: Ein einziges Package enthält alle Interfaces, Enums, Value Objects und Exceptions der gesamten Jardis-Plattform. Keine einzige Implementierung. Jedes Jardis-Package (ob Core, Adapter, Support oder Tools) importiert jardissupport/contracts und findet dort seine Contracts.

  • Null Implementierung — nur Interfaces, Enums und Basis-Exceptions
  • Single Source of Truth — eine Abhängigkeit statt dutzender
  • PSR-first — PSR-3 (Log), PSR-11 (Container), PSR-14 (Events), PSR-16 (Cache), PSR-18 (HTTP) wo Standards existieren
  • Interface Segregation — Reader/Writer-Trennung, granulare Query-Builder-Interfaces

Installation

bash
composer require jardissupport/contracts

GitHub: jardisSupport/contracts

Dieses Package wird automatisch als Abhängigkeit aller Jardis-Packages installiert.

Namespace-Struktur

Alle Interfaces liegen unter JardisSupport\Contract\:

JardisSupport\Contract\
├── Auth\              ← Authentifizierung, RBAC, Sessions, Tokens
├── ClassVersion\      ← Versionierte Klassen-Auflösung
├── Connection\        ← Basis-Lifecycle (connect/disconnect)
├── Data\              ← Hydration, Identity, FieldMapper
├── DbConnection\      ← PDO-Verbindungen, Connection-Pool
├── DbQuery\           ← SQL Query-Builder
├── DbSchema\          ← Schema-Analyse
├── DotEnv\            ← Environment-Variablen
├── EventListener\     ← Event-Listener-Registrierung
├── Filesystem\        ← Dateisystem-Abstraktion
├── Kernel\            ← DDD-Kernel, BoundedContext, Responses
├── Mailer\            ← E-Mail-Versand
├── Messaging\         ← Multi-Transport Messaging
├── Repository\        ← Generic CRUD
├── Scheduling\        ← Cron und Task-Scheduling
├── Secret\            ← Verschlüsselung
├── Validation\        ← Objekt-Validierung
└── Workflow\          ← Multi-Step-Prozesse

Interface-Übersicht nach Domain

Kernel

Das Herz der DDD-Architektur:

InterfaceBeschreibung
DomainKernelInterfaceService-Locator für BoundedContexts — nullable PSR-Services + Jardis-Services
BoundedContextInterfacehandle(className, ...params): mixed — Pass-Through-Resolver, erbt Payload+Version. context(className, payload, version): mixed — frischer BC-Einstieg, akzeptiert nur BC-Subklassen
ContextResponseInterfaceMutable Carrier für Daten, Events, Errors und Sub-Ergebnisse
DomainResponseInterfaceImmutable Final-Response mit HTTP-ähnlichem Status

Auth

Interface / EnumBeschreibung
AuthenticatorInterfaceauthenticate(Credential): AuthResult
GuardInterfacecheck(session, permission): bool, authorize(session, permission): void
SessionInterfaceAuthentifizierte Session mit Identity und Metadata
PasswordHasherInterfacehash(), verify()
TokenStoreInterfaceToken-Persistenz: store(), find(), revoke(), revokeAllForSubject()
HashedTokenInterfaceGespeicherter Token-Hash
CredentialInterfaceLogin-Credential (Password, ApiKey, Token)
CredentialTypeEnum: Password, ApiKey, Token
TokenTypeEnum: Access, Refresh, ApiKey, Verification, PasswordReset

Data

InterfaceBeschreibung
HydrationInterfaceEntity-Hydration, Change-Tracking, Clone, Diff, toArray
IdentityInterfaceUUID v4/v5/v7, NanoID
FieldMapperInterfaceBidirektionale Key-Übersetzung

Repository

Interface / KlasseBeschreibung
RepositoryInterfaceinsert(), update(), delete(), findById(), findByQuery(), exists()
PkStrategyEnum: AUTOINCREMENT, INTEGER, NONE
PersistExceptionException bei Write-Fehlern
RecordNotFoundExceptionException bei fehlendem Record

DbConnection

InterfaceBeschreibung
DbConnectionInterfacePDO-Wrapper mit Transactions und Reconnect
ConnectionPoolInterfaceRead/Write-Splitting mit Health-Checks
DatabaseConfigInterfaceDSN, Credentials, Options

DbQuery

Granulare Interfaces für den SQL-Builder:

InterfaceBeschreibung
DbQueryBuilderInterfaceSELECT (CTE, Window, Subquery, Union, ...)
DbInsertBuilderInterfaceINSERT
DbUpdateBuilderInterfaceUPDATE + WHERE
DbDeleteBuilderInterfaceDELETE + WHERE
DbWhereConditionInterfaceWHERE, AND, OR, JSON-Conditions
DbQueryConditionBuilderInterfaceVergleichsoperatoren
DbJoinInterfaceINNER/LEFT JOIN
DbOrderLimitInterfaceORDER BY, LIMIT, OFFSET
DbWindowBuilderInterfaceWindow Functions
DbSqlGeneratorInterfacetoSql(), getBindings()

Filesystem

InterfaceBeschreibung
FilesystemInterfaceKombiniert Reader + Writer
FilesystemReaderInterfaceread(), readStream(), exists(), size(), mimeType(), listContents()
FilesystemWriterInterfacewrite(), writeStream(), delete(), copy(), move(), createDirectory()
FilesystemServiceInterfaceFactory für Filesystem-Instanzen
FileInfoInterfaceDTO für Verzeichnislisting

Messaging

Interface / KlasseBeschreibung
MessagingServiceInterfaceFacade: publish() + consume()
MessagePublisherInterfacePublisher
MessageConsumerInterfaceConsumer
MessageHandlerInterfaceCallback-Contract
MessageExceptionBasis-Exception
ConnectionExceptionBroker-Verbindungsfehler
PublishExceptionPublish-Fehler
ConsumerExceptionConsume-Fehler

Weitere Domains

DomainInterfaces
SchedulingScheduleInterface, ScheduledTaskInterface, CronExpressionInterface, ConstraintInterface, ScheduleViolation
ValidationValidatorInterface, ValueValidatorInterface, ValidationResult
WorkflowWorkflowInterface, WorkflowBuilderInterface, WorkflowNodeBuilderInterface, WorkflowConfigInterface, WorkflowContextInterface, WorkflowResultInterface
MailerMailerInterface, MailMessageInterface, MailTransportInterface, MailerExceptionInterface
DotEnvDotEnvInterface
SecretSecretResolverInterface, SecretResolutionException
ClassVersionClassVersionInterface, ClassVersionConfigInterface
ConnectionConnectionInterface (Basis-Lifecycle)
EventListenerEventListenerRegistryInterface (Lücke in PSR-14: Listener-Registrierung)

Design-Prinzipien

PSR-first

DomainKernelInterface injiziert direkt PSR-Interfaces:

  • PSR-3 LoggerInterface für Logging
  • PSR-11 ContainerInterface für Service-Auflösung
  • PSR-14 EventDispatcherInterface für Events
  • PSR-16 CacheInterface für Caching
  • PSR-18 ClientInterface für HTTP

Jardis-Contracts existieren nur, wo kein PSR-Standard greift.

Nullable Services

Alle Infrastructure-Services im Kernel sind nullable:

php
$cache = $kernel->cache();           // ?CacheInterface
$logger = $kernel->logger();          // ?LoggerInterface
$mailer = $kernel->mailer();          // ?MailerInterface

Domain-Code muss Verfügbarkeit prüfen. Kein Service ist garantiert.

Reader/Writer-Trennung

php
// Read-only BoundedContext bekommt nur den Reader
public function __construct(
    private readonly FilesystemReaderInterface $storage,
) {}

// Full-Access Service bekommt beides
public function __construct(
    private readonly FilesystemInterface $storage,
) {}

Enum-basierte Strategien

php
use JardisSupport\Contract\Repository\PrimaryKey\PkStrategy;

$repository->insert('users', 'id', $values, PkStrategy::NONE);

Statt String-Konstanten verwenden alle Strategien und Typen PHP 8.1+ Enums.

Abhängigkeitsrichtung

JardisTools   → JardisAdapter → JardisSupport → JardisCore
                    |                |               |
          JardisSupport\Contract ←←←←←←←←←←←←←←←←←←

Alle Pfeile zeigen nach innen zum Contract-Package. Domain-Code importiert niemals Adapter-Code direkt.