refactor: move stripe webhook handler to app/handlers/

- Create app/handlers/ directory for event handlers
- Move stripe_webhook_handler.py to app/handlers/stripe_webhook.py
- Update imports in webhooks.py, tests, and docs
- Handlers are distinct from services (event-driven vs request-driven)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-25 21:58:48 +01:00
parent 8a0a5c594a
commit 3b67515bc2
5 changed files with 23 additions and 9 deletions

View File

@@ -14,7 +14,7 @@ from sqlalchemy.orm import Session
from app.core.database import get_db
from app.exceptions import InvalidWebhookSignatureException, WebhookMissingSignatureException
from app.services.stripe_service import stripe_service
from app.services.stripe_webhook_handler import stripe_webhook_handler
from app.handlers.stripe_webhook import stripe_webhook_handler
router = APIRouter(prefix="/webhooks")
logger = logging.getLogger(__name__)

10
app/handlers/__init__.py Normal file
View File

@@ -0,0 +1,10 @@
# app/handlers/__init__.py
"""
Handlers module.
Contains event handlers for webhooks and other external events.
"""
from app.handlers.stripe_webhook import stripe_webhook_handler
__all__ = ["stripe_webhook_handler"]

View File

@@ -1,5 +1,4 @@
# app/services/stripe_webhook_handler.py
# noqa: NAM-002 - This is a webhook handler, not a service
# app/handlers/stripe_webhook.py
"""
Stripe webhook event handler.
@@ -84,14 +83,14 @@ class StripeWebhookHandler:
logger.debug(f"No handler for event type {event_type}")
existing.status = "processed"
existing.processed_at = datetime.now(timezone.utc)
db.commit() # noqa: SVC-006 - Webhook handler controls its own transaction
db.commit()
return {"status": "ignored", "reason": f"no handler for {event_type}"}
try:
result = handler(db, event)
existing.status = "processed"
existing.processed_at = datetime.now(timezone.utc)
db.commit() # noqa: SVC-006 - Webhook handler controls its own transaction
db.commit()
logger.info(f"Successfully processed event {event_id} ({event_type})")
return {"status": "processed", "result": result}
@@ -99,7 +98,7 @@ class StripeWebhookHandler:
logger.error(f"Error processing event {event_id}: {e}")
existing.status = "failed"
existing.error_message = str(e)
db.commit() # noqa: SVC-006 - Webhook handler controls its own transaction
db.commit()
raise
# =========================================================================