From 62d107d1423053ea38b01505a8c5261bf863696f Mon Sep 17 00:00:00 2001 From: Agent Zero Date: Fri, 18 Sep 2026 11:31:10 +0200 Subject: [PATCH] =?UTF-8?q?fix(worker):=20F06=20(Astra=20P1)=20=E2=80=94?= =?UTF-8?q?=20Worker=20registriert=20jetzt=20Plugin-Event-Handler=20ueber?= =?UTF-8?q?=20geteilten=20idempotenten=20Pfad?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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_-Methoden gewinnen ueber noop). Verifikation: Outbox- + Miniapp-Suiten 24/24, Syntax+ruff clean. --- app/plugins/base.py | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/app/plugins/base.py b/app/plugins/base.py index 745201c..560f5bf 100644 --- a/app/plugins/base.py +++ b/app/plugins/base.py @@ -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 ───