Skip to content

feat(entity-extension): add entity extension system#59

Open
michalbiarda wants to merge 1 commit into
marko-php:developfrom
michalbiarda:feature/entity-extension
Open

feat(entity-extension): add entity extension system#59
michalbiarda wants to merge 1 commit into
marko-php:developfrom
michalbiarda:feature/entity-extension

Conversation

@michalbiarda
Copy link
Copy Markdown

Summary

  • Any module can now add columns to an existing entity's table without touching the original entity class
  • Extensions are auto-discovered from src/EntityExtension/ directories across vendor/modules/app at boot
  • Hydrated transparently from the same DB row; accessed via $entity->extension(MyExtension::class) with full IDE type inference via @template

What was built

  • EntityExtension abstract base class + #[ExtensionOf] attribute to declare which entity a class extends
  • EntityExtensionRegistry singleton + EntityExtensionDiscovery scanner — registered and populated in module.php boot
  • ExtensionMetadata + EntityExtensionMetadataFactory — parses extension classes; validates no #[Table], no primary key, no relationships
  • EntityMetadata::$extensions field (backward-compatible last param) — EntityMetadataFactory merges extensions and detects column/property name conflicts loud at boot
  • Entity::extension() / setExtension() — typed accessor with @template T of EntityExtension for IDE inference
  • EntityHydrator — hydrates extension objects from the same DB row; silently skips extensions whose columns are absent (safe during rolling deploys)
  • Repository — INSERT/UPDATE/batch include extension columns; null/default/loud-error policy enforced at save time
  • SchemaBuilder — extension columns included in table schema for migration diffs
  • packages/database/README.md updated with full developer workflow

Test plan

  • 47 new tests added across 10 new/modified test files
  • Full suite: 4956 passing

🤖 Generated with Claude Code

Any module can now add columns to an existing entity's table without
modifying the entity class. Extensions are auto-discovered from
src/EntityExtension/ directories, merged into the entity schema at boot,
and hydrated transparently from the same DB row. Access via the typed
extension() accessor which IDEs resolve through @template.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions github-actions Bot added the enhancement New feature or request label May 11, 2026
@michalbiarda
Copy link
Copy Markdown
Author

@markshust This adds a basic Entity extensibility and could later be updated with more complex extensions (using joins, etc.).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant