0012. Require one fully accessible side to manage a sync rule¶
Date: 2026-07-31 Status: Accepted
Context¶
ADR-0007 split a PlatformSupport user's
reach in two: connections to a system they operate are fully accessible, every other connection of
the same tenant is status-only. A SyncRule joins two connections
(ADR-0010 guarantees both belong to the same
tenant), so that split does not decide the question by itself — a rule can have one fully accessible
side, two, or none, and ADR-0007 says nothing about which of those permits a change.
Requiring both sides looks like the safer reading. It is not a workable one.
SystemConnection::fullyAccessibleBy() matches only systems whose driver returns true from
SystemDriver::canHaveSupportUsers(), i.e. internal consuming platforms
(ADR-0008). Every rule the platform
derives on activation spans shop ↔ internal product, and a shop adapter can never have support
members. A support user therefore never holds full access to both sides of a real rule.
Decision¶
A sync rule is visible when its tenant is reachable, and changeable — created, activated, deactivated, deleted — when at least one of its two connections is fully accessible.
Two scopes on SyncRule state this once: accessibleBy(User) for visibility (checking the source
connection alone, since ADR-0010 guarantees a shared tenant) and manageableBy(User) for changes.
SyncRulePolicy reads view from the first and update/delete from the second, and the admin
panel's query and row actions read from the same two scopes rather than restating the rule.
create is the exception: it receives no rule to inspect, so there the bar is only "holds
sync_rules.create and has at least one fully accessible connection". Whether a specific pair is
allowed is decided when the rule is saved, by the form's validation and by SyncRule::booted().
Consequences¶
A support user of one internal platform can change a rule that also touches a second internal
platform they have no relationship with — for example a User Platform → WooCommerce rule, when
they operate rapidmail and reach the tenant through it. That is the accepted cost: the alternative
reduces rule management to SuperAdmin in practice while presenting itself as a graded permission,
which is worse than a boundary that is honest about where it sits.
Rule content is still constrained independently of who is editing: the direction matrix (ADR-0005) and tenant isolation (ADR-0010) are enforced on save regardless of the actor.