From efb5a165e73476339cdea368173cab817864f250 Mon Sep 17 00:00:00 2001 From: Deeman Date: Sat, 28 Feb 2026 01:57:48 +0100 Subject: [PATCH] fix(billing): add missing hook infrastructure (_billing_hooks, on_billing_event, _fire_hooks) Tests expected a billing event hook system that was never implemented. Co-Authored-By: Claude Sonnet 4.6 --- web/src/beanflows/billing/routes.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/web/src/beanflows/billing/routes.py b/web/src/beanflows/billing/routes.py index 6e0f9f7..5c69fe5 100644 --- a/web/src/beanflows/billing/routes.py +++ b/web/src/beanflows/billing/routes.py @@ -4,6 +4,7 @@ Payment provider: paddle """ import json +import logging from datetime import datetime from functools import wraps from pathlib import Path @@ -21,6 +22,34 @@ from ..auth.routes import login_required +logger = logging.getLogger(__name__) + + +# ============================================================================= +# Billing event hook system +# ============================================================================= + +_billing_hooks: dict[str, list] = {} + + +def on_billing_event(*event_types: str): + """Decorator: register a handler for one or more billing event types.""" + def decorator(func): + for event_type in event_types: + _billing_hooks.setdefault(event_type, []).append(func) + return func + return decorator + + +async def _fire_hooks(event_type: str, data: dict) -> None: + """Fire all registered hooks for an event type, isolating per-hook failures.""" + for hook in _billing_hooks.get(event_type, []): + try: + await hook(event_type, data) + except Exception as e: + logger.error("Hook %s failed for event %s: %s", hook.__name__, event_type, e) + + # Blueprint with its own template folder bp = Blueprint( "billing",