"""Integration management endpoints.""" from typing import List import secrets from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select from app.core.database import get_db from app.models.integration import Integration, IntegrationType, IntegrationStatus from app.models.organization import OrganizationMember from app.schemas.integration import IntegrationCreate, IntegrationRead, IntegrationUpdate from app.api.deps import get_current_user, require_role router = APIRouter() @router.get("/", response_model=List[IntegrationRead]) async def list_integrations( org_id: int, member: OrganizationMember = Depends(require_role("analyst")), db: AsyncSession = Depends(get_db) ): """List integrations for organization.""" result = await db.execute( select(Integration).where(Integration.organization_id == org_id) ) return result.scalars().all() @router.post("/", response_model=IntegrationRead, status_code=status.HTTP_201_CREATED) async def create_integration( org_id: int, integration_in: IntegrationCreate, member: OrganizationMember = Depends(require_role("admin")), db: AsyncSession = Depends(get_db) ): """Create a new integration.""" # Generate webhook secret webhook_secret = secrets.token_hex(32) integration = Integration( organization_id=org_id, name=integration_in.name, type=integration_in.type, base_url=integration_in.base_url, api_key=integration_in.api_key, webhook_secret=webhook_secret, callback_url=integration_in.callback_url, auto_analyze=integration_in.auto_analyze, config=integration_in.config or {}, status=IntegrationStatus.ACTIVE ) db.add(integration) await db.commit() await db.refresh(integration) return integration @router.get("/{integration_id}", response_model=IntegrationRead) async def get_integration( org_id: int, integration_id: int, member: OrganizationMember = Depends(require_role("analyst")), db: AsyncSession = Depends(get_db) ): """Get integration details.""" result = await db.execute( select(Integration) .where(Integration.id == integration_id) .where(Integration.organization_id == org_id) ) integration = result.scalar_one_or_none() if not integration: raise HTTPException(status_code=404, detail="Integration not found") return integration @router.patch("/{integration_id}", response_model=IntegrationRead) async def update_integration( org_id: int, integration_id: int, integration_update: IntegrationUpdate, member: OrganizationMember = Depends(require_role("admin")), db: AsyncSession = Depends(get_db) ): """Update integration.""" result = await db.execute( select(Integration) .where(Integration.id == integration_id) .where(Integration.organization_id == org_id) ) integration = result.scalar_one_or_none() if not integration: raise HTTPException(status_code=404, detail="Integration not found") for field, value in integration_update.dict(exclude_unset=True).items(): setattr(integration, field, value) return integration @router.delete("/{integration_id}", status_code=status.HTTP_204_NO_CONTENT) async def delete_integration( org_id: int, integration_id: int, member: OrganizationMember = Depends(require_role("admin")), db: AsyncSession = Depends(get_db) ): """Delete integration.""" result = await db.execute( select(Integration) .where(Integration.id == integration_id) .where(Integration.organization_id == org_id) ) integration = result.scalar_one_or_none() if not integration: raise HTTPException(status_code=404, detail="Integration not found") await db.delete(integration) @router.post("/{integration_id}/test") async def test_integration( org_id: int, integration_id: int, member: OrganizationMember = Depends(require_role("admin")), db: AsyncSession = Depends(get_db) ): """Test integration connection.""" result = await db.execute( select(Integration) .where(Integration.id == integration_id) .where(Integration.organization_id == org_id) ) integration = result.scalar_one_or_none() if not integration: raise HTTPException(status_code=404, detail="Integration not found") # TODO: Implement actual connection test based on integration type return {"status": "ok", "message": "Connection successful"}