fix(server): plan 4 — thread the discovery UnitOfWork through PluginRuntimeService too

Complements the just-landed discovery atomicity fix (DiscoveryRepos.uow):
PluginRuntimeService's own discoveryRepos getter still built the bundle
without a uow field. Threads its already-injected, @Optional() uow through
so its own onApplicationBootstrap/reload/dev-link discovery calls also get
the transactional DI5-DI8 refresh, not just PluginRegistryService's.

No throwing guard here, unlike PluginRegistryService's: several hand-built
partial-DI-graph test instances of this class (boot-registry-order.test.ts,
in a sibling task's held file window) construct it with uow omitted and
exercise onApplicationBootstrap's discovery call directly. Discovery must
never refuse outright just because a test built a partial graph, so it
degrades to the pre-existing untransacted sequence when uow is absent
(DiscoveryRepos.uow's own docstring covers this), the same "boot must
never block app init" defensiveness this file already applies elsewhere.
This commit is contained in:
jubnl
2026-09-24 06:18:33 +02:00
parent 3e37474a2c
commit dba42c3aab
@@ -315,8 +315,17 @@ export class PluginRuntimeService implements OnApplicationBootstrap, OnModuleDes
// Plan 3j Task 3: `discoverPlugins` composes `DiscoveryRepos` from the repositories
// this class already injects for its own PR-numbered statements — no new params.
// Plan 4 Task 8a: `uow` (already injected, `@Optional()`, for `setOperatorEgressHosts`
// above) is threaded through too, so `upsert`'s DI5–DI8 delete/re-insert pairs run
// in one transaction — `DiscoveryRepos.uow`'s own docstring covers why this is
// optional rather than a throwing guard like `setOperatorEgressHosts`'s: several
// hand-built partial-DI-graph test instances of this class (e.g.
// `boot-registry-order.test.ts`) exercise `onApplicationBootstrap`'s discovery
// call with no `uow`, and discovery — unlike a write an admin is actively waiting
// on — must never refuse outright; it degrades to the pre-existing untransacted
// sequence instead.
private get discoveryRepos(): DiscoveryRepos {
return { plugins: this.plugins, actions: this.pluginActions, settingsFields: this.pluginSettingsFields, errorLog: this.pluginErrorLog };
return { plugins: this.plugins, actions: this.pluginActions, settingsFields: this.pluginSettingsFields, errorLog: this.pluginErrorLog, uow: this.uow };
}
// onApplicationBootstrap, NOT onModuleInit: boot activation builds each plugin's