Problem/Motivation

The engine states its own rule in OrchestraUiHooks::entityTypeAlter(): an entity stays UI-agnostic and orchestra_ui attaches the screens, so a headless site installs the engine and gets no administration it did not ask for. The status entity follows it, and the workflow declares nothing either.

The tenant does not. It declares a list builder, add, edit and delete form classes and four link templates on its own #[ConfigEntityType], and the engine ships the four routes, the Tenants menu link and the Add tenant action link with them. It is the only entity in the project whose administration comes from the engine rather than from the module whose job that is.

Proposed resolution

Move the tenant's administration to orchestra_ui, exactly as the status already does:

  • TenantForm, TenantDeleteForm and TenantListBuilder move, and the entity stops naming them: the handlers and the link templates are attached by OrchestraUiHooks::entityTypeAlter() instead.
  • The four routes, the menu link, the action link and the edit-form local task move with them, verbatim, so no path, title or permission changes.
  • TenantAccessControlHandler stays in the engine. It is access, not interface, and it is what refuses to delete the default tenant.
  • TenantRetentionForm and TenantReadAccessForm stay in the engine with their routes, exactly as the four per-workflow setting forms do. They are settings the engine owns, not the entity's own screens, and they stay reachable by URL and permission on a site with no interface module, which is the same split the workflow tabs already make.
  • The strings in the moved files move to orchestra_ui's catalog, since a catalog is only read for the project that ships the string.

What changes for a site

This is not a pure refactor, and it should not be described as one. A site running the engine with orchestra_ui sees nothing move: same paths, same titles, same permissions. A site running the engine without it loses the tenant administration pages, which is the point of the change rather than a side effect: that site administers a tenant through configuration, as it already does for a status.

What a move like this breaks quietly

Two things, both found by auditing rather than by the diff:

  • Namespace siblings. TenantListBuilder read five classes with no use statement because they sat in the same namespace.
  • A route another module names. orchestra_domain depends on the engine alone and redirected to the tenant collection after saving. That route becomes optional here, and Url::fromRoute() resolves nothing when it is built, so nothing threw until a response was built: saving the domains form answered with a RouteNotFoundException on a site with no interface module. It now redirects to its own route, the way the engine's per-tenant forms do.

Remaining tasks

None beyond the move, the redirect fix and their tests.

AI-Generated: Yes (Claude Code was used to survey where each entity declares its administration, to draft this issue summary, and to write the change and its tests. The redirect defect and the broken tests were found by auditing the change against a running site, and each fix was proven by making the test fail against the unfixed code first.)

Issue fork orchestra-3625074

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

mably created an issue. See original summary.

mably’s picture

Status: Active » Needs review
mably’s picture

Issue summary: View changes

  • mably committed 87cb0c04 on 1.x
    task: #3625074 The tenant is the only entity that declares its own...
mably’s picture

Status: Needs review » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.