Skip to content

Refactor entity factories to use factory functions - #6452

Draft
VPS-Obi wants to merge 3 commits into
replace-entity-repositories-with-entity-managerfrom
remove-string-entity-references
Draft

VPS-Obi wants to merge 3 commits into
replace-entity-repositories-with-entity-managerfrom
remove-string-entity-references

Conversation

@VPS-Obi

@VPS-Obi VPS-Obi commented Sep 24, 2026

Copy link
Copy Markdown
Contributor

Problem

Entity creation in the codebase was using conditional logic at the module level to create different entity classes based on configuration (e.g., with or without scope). This pattern made it difficult to:

  1. Define relations between entities that reference each other, since the entity class wasn't available until after the conditional block
  2. Maintain consistent entity creation patterns across different entity types
  3. Pass entity classes as dependencies to services that need them

Solution

Refactor entity creation to use factory functions that encapsulate the conditional logic and return the concrete entity class. This allows:

  1. Relations to be defined after entity creation using the returned class reference
  2. Entity classes to be injected as dependencies via NestJS providers
  3. Consistent patterns across createFileEntity, createFolderEntity, createPageTreeNodeEntity, and createPageTreeNodeFullTextEntity

Key changes:

  • File entity: Wrapped conditional logic in createConcreteFileEntity(), moved relation definitions to after entity creation using the returned DamFile class
  • Folder entity: Wrapped conditional logic in createConcreteFolderEntity(), removed @OneToMany decorator for files relation (now defined in file entity)
  • Page tree node entity: Created new createPageTreeNodeEntity() factory function that handles scope and category configuration
  • Page tree node full text entity: Created createPageTreeNodeFullTextEntity() factory function to accept PageTreeNode as a parameter
  • Module updates: Added entity class providers to DI containers so services can inject entity classes instead of using string references
  • Service updates: Updated all entityManager.find/findOneOrFail/findAndCount calls to use entity class references instead of string names

This is a major breaking change for applications that directly extend PageTreeNodeBase — they must now use createPageTreeNodeEntity() instead.

Changeset

See .changeset/cms-api-create-page-tree-node-entity.md for migration guide details.

https://claude.ai/code/session_016mE6dC24agzeytj4aohiLy

String entity names bypass type inference and silently break when an
entity is renamed or not registered. The entity classes are created by
the application (or by a factory inside the module), so they are now
provided via DI tokens (`DAM_FILE_ENTITY`, `DAM_FOLDER_ENTITY`,
`REDIRECT_ENTITY`, `PAGE_TREE_NODE_ENTITY` and the `BREVO_*_ENTITY`
tokens) and injected where needed. Resolver factories use the entity
classes they already receive.

The string-based `MikroOrmModule.forFeature` registrations in brevo-api
are replaced with classes or removed, since strings only registered
repository providers that are no longer used.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016mE6dC24agzeytj4aohiLy
Relations referencing an entity by name break silently when the entity
is renamed or not registered, and the name has to be kept in sync with
the application's class. The relations now reference the entity
classes:

- Self-references in the file and folder factories use the class
  created by the factory.
- Relations of entities created before the entity they reference are
  defined by the factory of the referenced entity: createFileEntity
  defines Folder.files, DamFileImage.file and the DamMediaAlternative
  relations, createEmailCampaignEntity defines TargetGroup.campaigns.
- The PageTreeNodeFullText view entity is created by PageTreeModule.
- The page tree node entity is created by the new
  createPageTreeNodeEntity factory, since PageTreeNodeBase can't
  reference the application's entity for the parent relation.

The database schema and the GraphQL schema stay unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016mE6dC24agzeytj4aohiLy

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants