from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session from typing import List from uuid import UUID from app.core.database import get_db from app.core.security import get_current_user from app.models.user import User, UserRole from app.models.flow import Flow, TriggerType from app.schemas.flow import FlowCreate, FlowUpdate, FlowResponse, FlowListResponse router = APIRouter(prefix="/api/flows", tags=["flows"]) def require_admin(current_user: User = Depends(get_current_user)): if current_user.role != UserRole.ADMIN: raise HTTPException(status_code=403, detail="Admin required") return current_user @router.get("", response_model=List[FlowListResponse]) def list_flows( db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): flows = db.query(Flow).order_by(Flow.updated_at.desc()).all() return flows @router.post("", response_model=FlowResponse) def create_flow( request: FlowCreate, db: Session = Depends(get_db), current_user: User = Depends(require_admin), ): flow = Flow( name=request.name, description=request.description, trigger_type=request.trigger_type, trigger_value=request.trigger_value, nodes=[], edges=[], variables={}, ) db.add(flow) db.commit() db.refresh(flow) return flow @router.get("/{flow_id}", response_model=FlowResponse) def get_flow( flow_id: UUID, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): flow = db.query(Flow).filter(Flow.id == flow_id).first() if not flow: raise HTTPException(status_code=404, detail="Flow not found") return flow @router.put("/{flow_id}", response_model=FlowResponse) def update_flow( flow_id: UUID, request: FlowUpdate, db: Session = Depends(get_db), current_user: User = Depends(require_admin), ): flow = db.query(Flow).filter(Flow.id == flow_id).first() if not flow: raise HTTPException(status_code=404, detail="Flow not found") update_data = request.model_dump(exclude_unset=True) for field, value in update_data.items(): setattr(flow, field, value) flow.version += 1 db.commit() db.refresh(flow) return flow @router.delete("/{flow_id}") def delete_flow( flow_id: UUID, db: Session = Depends(get_db), current_user: User = Depends(require_admin), ): flow = db.query(Flow).filter(Flow.id == flow_id).first() if not flow: raise HTTPException(status_code=404, detail="Flow not found") db.delete(flow) db.commit() return {"success": True} @router.post("/{flow_id}/activate") def activate_flow( flow_id: UUID, db: Session = Depends(get_db), current_user: User = Depends(require_admin), ): flow = db.query(Flow).filter(Flow.id == flow_id).first() if not flow: raise HTTPException(status_code=404, detail="Flow not found") if flow.trigger_type in [TriggerType.WELCOME, TriggerType.FALLBACK]: db.query(Flow).filter( Flow.trigger_type == flow.trigger_type, Flow.id != flow_id ).update({"is_active": False}) flow.is_active = True db.commit() return {"success": True} @router.post("/{flow_id}/deactivate") def deactivate_flow( flow_id: UUID, db: Session = Depends(get_db), current_user: User = Depends(require_admin), ): flow = db.query(Flow).filter(Flow.id == flow_id).first() if not flow: raise HTTPException(status_code=404, detail="Flow not found") flow.is_active = False db.commit() return {"success": True}