Automated Action 2adbcd0535 Complete multi-tenant SaaS platform with external integrations
- Implemented comprehensive multi-tenant data isolation using database-level security
- Built JWT authentication system with role-based access control (Super Admin, Org Admin, User, Viewer)
- Created RESTful API endpoints for user and organization operations
- Added complete audit logging for all data modifications with IP tracking
- Implemented API rate limiting and input validation with security middleware
- Built webhook processing engine with async event handling and retry logic
- Created external API call handlers with circuit breaker pattern and error handling
- Implemented data synchronization between external services and internal data
- Added integration health monitoring and status tracking
- Created three mock external services (User Management, Payment, Communication)
- Implemented idempotency for webhook processing to handle duplicates gracefully
- Added comprehensive security headers and XSS/CSRF protection
- Set up Alembic database migrations with proper SQLite configuration
- Included extensive documentation and API examples

Architecture features:
- Multi-tenant isolation at database level
- Circuit breaker pattern for external API resilience
- Async background task processing
- Complete audit trail with user context
- Role-based permission system
- Webhook signature verification
- Request validation and sanitization
- Health monitoring endpoints

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-27 21:14:30 +00:00

82 lines
2.6 KiB
Python

from fastapi import APIRouter, Depends, Request
from sqlalchemy.orm import Session
from typing import Dict, Any
from app.core.deps import get_db, require_roles
from app.models.user import User, UserRole
from app.integrations.webhooks.handlers import WebhookHandler
from app.services.webhook import WebhookService
from app.middleware.rate_limit import limiter
router = APIRouter()
@router.post("/user/{organization_id}")
@limiter.limit("30/minute")
async def receive_user_webhook(
request: Request,
organization_id: int,
payload: Dict[str, Any],
db: Session = Depends(get_db)
):
"""Receive webhook from user management service"""
handler = WebhookHandler(db)
return await handler.handle_user_webhook(request, organization_id, payload)
@router.post("/payment/{organization_id}")
@limiter.limit("30/minute")
async def receive_payment_webhook(
request: Request,
organization_id: int,
payload: Dict[str, Any],
db: Session = Depends(get_db)
):
"""Receive webhook from payment service"""
handler = WebhookHandler(db)
return await handler.handle_payment_webhook(request, organization_id, payload)
@router.post("/communication/{organization_id}")
@limiter.limit("30/minute")
async def receive_communication_webhook(
request: Request,
organization_id: int,
payload: Dict[str, Any],
db: Session = Depends(get_db)
):
"""Receive webhook from communication service"""
handler = WebhookHandler(db)
return await handler.handle_communication_webhook(request, organization_id, payload)
@router.get("/stats")
async def get_webhook_stats(
current_user: User = Depends(require_roles([UserRole.ORG_ADMIN, UserRole.SUPER_ADMIN])),
db: Session = Depends(get_db)
):
"""Get webhook processing statistics for current organization"""
webhook_service = WebhookService(db)
return webhook_service.get_webhook_stats(current_user.organization_id)
@router.post("/process")
async def trigger_webhook_processing(
current_user: User = Depends(require_roles([UserRole.ORG_ADMIN, UserRole.SUPER_ADMIN])),
db: Session = Depends(get_db)
):
"""Manually trigger webhook processing (for testing/debugging)"""
webhook_service = WebhookService(db)
pending_webhooks = webhook_service.get_pending_webhooks(limit=10)
processed_count = 0
for webhook in pending_webhooks:
if webhook.organization_id == current_user.organization_id:
success = webhook_service.process_webhook_event(webhook)
if success:
processed_count += 1
return {
"message": f"Processed {processed_count} webhook events",
"total_pending": len(pending_webhooks)
}