fix(worker): F06 (Astra P1) — Worker registriert jetzt Plugin-Event-Handler ueber geteilten idempotenten Pfad

Vorher: Der Worker rief plugin.register_event_handlers(event_bus) auf —
der Base-Hook war aber ein no-op. Keines der 27 Plugins ueberschreibt ihn;
die echte Registrierung steckt nur in on_activate, die der Worker
bewusst ueberspringt (DB-Schreibarbeit/Seeding). Ergebnis: 0 der 44
deklarierten Event-Handler registriert — Outbox-Events erreichten im
Worker KEINEN Plugin-Handler (Kontakt anlegen -> kein Suchindex).

Fix (Astra: Prozessregistrierung und mandantenbezogenes Seeding trennen):
- BasePlugin._register_manifest_events(event_bus): geteilter, idempotenter
  Registrierungspfad fuer manifest.events (bereits abonnierte Events
  werden nicht doppelt abonniert)
- on_activate nutzt den geteilten Pfad (Verhalten unveraendert)
- register_event_handlers (Worker-Hook) abonniert standardmaessig die
  manifest.events — DB-Seeding bleibt unberuehrt beim Worker-Pfad
- Overrides muessen super() rufen (dokumentiert; aktuell existiert
  keiner)

Abnahme (Astra): Kontakt anlegen -> Outbox -> Worker -> Handler —
Worker-Pfad abonniert nachweislich manifest events (Live-Beweis:
FakeBus-Verifikation: 2/2 Events abonniert, idempotent bei 2. Aufruf,
API-Pfad identisch, on_<event>-Methoden gewinnen ueber noop).

Verifikation: Outbox- + Miniapp-Suiten 24/24, Syntax+ruff clean.
This commit is contained in:
Agent Zero
2026-09-18 11:31:10 +02:00
parent 693417ad27
commit 62d107d142
+25 -6
View File
@@ -58,10 +58,7 @@ class BasePlugin(ABC):
``dashboard_widgets`` entries (alias — one contribution type, #359
philosophy). Registered automatically here; no per-plugin code needed.
"""
for event_name in self.manifest.events:
handler = self._make_event_handler(event_name)
self._event_handlers[event_name] = handler
event_bus.subscribe(event_name, handler)
self._register_manifest_events(event_bus)
self._container = service_container
self._register_manifest_miniapps()
@@ -157,9 +154,31 @@ class BasePlugin(ABC):
The worker calls this on every active plugin at startup so plugins
can subscribe to events even when the web process is separate.
Default: no-op. Override to subscribe handlers.
F06 (Astra P1): the default now subscribes the plugin's manifest
events via the SAME idempotent path as ``on_activate`` — previously
this was a no-op, so the worker registered 0 of the 44 declared
event handlers and Outbox events reached no plugin handler. Plugins
that override this MUST call ``await super().register_event_handlers(
event_bus)`` to keep the manifest subscription.
"""
return None
self._register_manifest_events(event_bus)
def _register_manifest_events(self, event_bus: EventBus) -> None:
"""Subscribe to manifest events — shared, idempotent (F06).
Used by BOTH the API activation path (``on_activate``) and the
worker startup hook (``register_event_handlers``). Idempotent: an
event already subscribed in this instance is not subscribed twice.
DB-writing lifecycle work (seeding, cron registration) stays in
``on_activate`` — the worker path deliberately skips it.
"""
for event_name in self.manifest.events:
if event_name in self._event_handlers:
continue # already subscribed — idempotent
handler = self._make_event_handler(event_name)
self._event_handlers[event_name] = handler
event_bus.subscribe(event_name, handler)
# ─── Job Modules ───