Orchestra stores the domain-to-tenant binding as a third-party setting on the domain module's own config entity. That is Orchestra data written into a module that knows nothing about Orchestra, and it is the reason this submodule needs two predelete sweeps instead of one. The binding belongs on the tenant.

Problem/Motivation

A tenant and a domain currently name each other, in two different config entities:

  • domain.record.*.third_party_settings.orchestra_domain.tenant, which says a request served on that domain acts in that tenant. Written by an Orchestra field this submodule alters onto the domain add/edit form, read by DomainTenantResolver.
  • orchestra.orchestra_tenant.*.third_party_settings.orchestra_domain, which says where a tenant receives people and where its operators work. Written by the tenant's own Domains form, read by DomainNotificationContext.

The second is a submodule extending its own project's entity, which is what third-party settings are for. The first is not: it puts Orchestra's data in domain.record.*.yml, so a Domain Access site exports Orchestra configuration inside Domain's, and uninstalling Orchestra Domain leaves it behind.

It also costs a hook. Because the value lives on an entity Orchestra does not own, a deleted tenant has to be swept out of every domain record that named it (orchestraTenantPredelete()). Nothing would need sweeping if the value sat on the tenant, because a tenant's own settings go when the tenant does.

Proposed resolution

Move the binding to the tenant, beside the two settings the submodule already keeps there, so that everything Orchestra Domain knows about a tenant is in one place and all of it is on Orchestra's own entity.

  • Add a list of the domains whose requests act in the tenant, with its config schema, edited on the tenant's existing Domains form. Many domains resolve to one tenant, so the list lives on the tenant.
  • DomainTenantResolver resolves through that list rather than reading the negotiated domain's setting, and declares the tenant list's cache tags rather than the domain's. This read is per-request, so the change is measured rather than assumed.
  • Remove the Orchestra field from the domain add/edit form and its entity builder, remove orchestraTenantPredelete(), and remove the domain.record.* entry from the config schema. A domain record goes back to holding only Domain's configuration.
  • Keep domainPredelete(): a domain is never Orchestra's, so its deletion still has to clear the names a tenant holds, now including the new list.

Remaining tasks

None beyond the change itself.

User interface changes

The Orchestra tenant select disappears from the domain add/edit form. The tenant's Domains form gains the domains that resolve to it, so one form answers every question this submodule asks about a tenant.

API changes

None. TenantResolverInterface and the tagged-resolver contract are unchanged; only where this resolver reads from changes.

Data model changes

The binding moves from the domain record to the tenant. The project is pre-1.0, so the old setting is removed outright rather than migrated: a site already running an alpha re-states its bindings on the tenant's Domains form.

Release notes snippet

Orchestra Domain no longer writes to domain records. The domain-to-tenant binding is set on the tenant's Domains form, alongside its public and workspace domains.

AI-Generated: Yes (Claude Code was used to help draft this issue summary and to write the code and tests on the merge request. I reviewed and ran the work myself before posting it.)

Issue fork orchestra-3622940

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 committed 5c3f3e6c on 1.x
    task: #3622940 Keep Orchestra out of domain records: bind the domain to...
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.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.