The tenant is the only entity that declares its own administration UI in the engine
Fixes #3625074.
The engine states the rule in OrchestraUiHooks::entityTypeAlter(): an entity stays UI-agnostic and orchestra_ui attaches the screens. The status follows it, the workflow declares nothing — the tenant named a list builder, three form classes and four link templates on its own attribute, and the engine shipped the routes, the Tenants menu link and the Add tenant action link with them.
The move
TenantForm,TenantDeleteForm,TenantListBuilder→orchestra_ui, attached in the alter it already runs for the status.- The four routes, the menu link, the action link and the edit tab move verbatim — every path, title and access requirement unchanged, including the delete route taking
_entity_accessrather than the permission its neighbors take. TenantAccessControlHandlerstays: it is access, and it is the rule that forbids deleting the default tenant.TenantRetentionForm/TenantReadAccessFormstay with their routes, exactly as the four per-workflow forms do — reachable by URL and permission without an interface module, which is the split the workflow tabs already make.- 19 catalog entries moved with their French, 3 that both projects source copied back, 1 the engine no longer writes dropped.
check-translations.phpexits 0.
This is not a pure refactor. With orchestra_ui, nothing moves. Without it, a site loses the tenant administration pages — which is the point, not a side effect.
What the audit found
A route another module names. orchestra_domain depends on the engine alone and redirected to entity.orchestra_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, and every existing test passed. On a site with domain-based tenancy and no interface module, saving the domains form answered with a RouteNotFoundException instead of a page. It now redirects to its own route, the way the engine's per-tenant forms do. The test generates the URL rather than reading the route name, because the name was what was wrong:
with the old redirect: RouteNotFoundException: Route "entity.orchestra_tenant.collection" does not exist.
with the fix: 1/1 classes passedThree engine tests asserted an interface the engine no longer ships. RouteAccessTest and RetentionUiTest walk the tenant pages, so they install orchestra_ui. The list-builder assertion moved to orchestra_ui, since the engine should not test a list builder it does not provide; the rule behind it stays asserted in the engine.
A duplicate test. The one added with the move asserted what TenantDeletionTest already asserts more fully — access for the default and another tenant, the predelete guard throwing, the tenant surviving. Removed, along with the trait and user schema it needed, and the helper left unused by the extraction.
Namespace siblings. TenantListBuilder read five classes with no use statement because they sat in the same namespace.
Verified
TenantFormTest, TenantDeletionTest, TenantDomainsFormTest, TenantUsageTest, TenantDomainCleanupTest, StatusAdminRouteTest, WorkflowOperationsTest all pass. phpcs over 968 files is back to the 3 pre-existing orchestra_bpmn_io/js files. On a running site the entity resolves its handlers and link templates from orchestra_ui, toUrl('edit-form') works, the config-translation overview still derives from the moved template, and the tenant edit form keeps its 4 tabs.