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:
@@ -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
10
app/handlers/__init__.py
Normal 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"]
|
||||
@@ -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
|
||||
|
||||
# =========================================================================
|
||||
@@ -34,7 +34,12 @@ All subscription models are defined in `models/database/subscription.py`:
|
||||
| `BillingService` | `app/services/billing_service.py` | Subscription operations, checkout, portal |
|
||||
| `SubscriptionService` | `app/services/subscription_service.py` | Limit checks, usage tracking |
|
||||
| `StripeService` | `app/services/stripe_service.py` | Core Stripe API operations |
|
||||
| `StripeWebhookHandler` | `app/services/stripe_webhook_handler.py` | Webhook event processing |
|
||||
|
||||
### Handlers
|
||||
|
||||
| Handler | Location | Purpose |
|
||||
|---------|----------|---------|
|
||||
| `StripeWebhookHandler` | `app/handlers/stripe_webhook.py` | Webhook event processing |
|
||||
|
||||
### API Endpoints
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from app.services.stripe_webhook_handler import StripeWebhookHandler
|
||||
from app.handlers.stripe_webhook import StripeWebhookHandler
|
||||
from models.database.subscription import (
|
||||
BillingHistory,
|
||||
StripeWebhookEvent,
|
||||
@@ -59,7 +59,7 @@ class TestStripeWebhookHandlerCheckout:
|
||||
"""Initialize handler instance before each test."""
|
||||
self.handler = StripeWebhookHandler()
|
||||
|
||||
@patch("app.services.stripe_webhook_handler.stripe.Subscription.retrieve")
|
||||
@patch("app.handlers.stripe_webhook.stripe.Subscription.retrieve")
|
||||
def test_handle_checkout_completed_success(
|
||||
self, mock_stripe_retrieve, db, test_vendor, test_subscription, mock_checkout_event
|
||||
):
|
||||
|
||||
Reference in New Issue
Block a user