feat(fase3): add conversation transfer and note API routes

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Claude AI
2026-01-29 10:56:35 +00:00
parent 5746ad42e5
commit e0ff66504b
2 changed files with 104 additions and 1 deletions

View File

@@ -15,8 +15,11 @@ from app.models.whatsapp import (
from app.schemas.whatsapp import (
WhatsAppAccountCreate, WhatsAppAccountResponse,
ConversationResponse, ConversationDetailResponse,
SendMessageRequest, MessageResponse, InternalEventRequest
SendMessageRequest, MessageResponse, InternalEventRequest,
TransferToQueueRequest, TransferToAgentRequest,
ResolveConversationRequest, InternalNoteRequest
)
from app.services.assignment import AssignmentService
router = APIRouter(prefix="/api/whatsapp", tags=["whatsapp"])
settings = get_settings()
@@ -362,3 +365,86 @@ async def flow_send_message(
db.commit()
return {"success": True, "message_id": str(message.id)}
@router.post("/conversations/{conversation_id}/transfer-to-queue")
def transfer_to_queue(
conversation_id: UUID,
request: TransferToQueueRequest,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
):
service = AssignmentService(db)
if service.transfer_to_queue(conversation_id, request.queue_id):
return {"success": True}
raise HTTPException(status_code=400, detail="Transfer failed")
@router.post("/conversations/{conversation_id}/transfer-to-agent")
def transfer_to_agent(
conversation_id: UUID,
request: TransferToAgentRequest,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
):
service = AssignmentService(db)
if service.transfer_to_agent(conversation_id, request.agent_id):
return {"success": True}
raise HTTPException(status_code=400, detail="Transfer failed")
@router.post("/conversations/{conversation_id}/transfer-to-bot")
def transfer_to_bot(
conversation_id: UUID,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
):
service = AssignmentService(db)
if service.transfer_to_bot(conversation_id):
return {"success": True}
raise HTTPException(status_code=400, detail="Transfer failed")
@router.post("/conversations/{conversation_id}/resolve")
def resolve_conversation(
conversation_id: UUID,
request: ResolveConversationRequest,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
):
service = AssignmentService(db)
if service.resolve_conversation(
conversation_id,
request.csat_score,
request.csat_feedback
):
return {"success": True}
raise HTTPException(status_code=400, detail="Failed to resolve")
@router.post("/conversations/{conversation_id}/notes")
def add_internal_note(
conversation_id: UUID,
request: InternalNoteRequest,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user),
):
conversation = db.query(Conversation).filter(
Conversation.id == conversation_id
).first()
if not conversation:
raise HTTPException(status_code=404, detail="Conversation not found")
message = Message(
conversation_id=conversation.id,
direction=MessageDirection.OUTBOUND,
type=MessageType.TEXT,
content=request.content,
sent_by=current_user.id,
is_internal_note=True,
status=MessageStatus.DELIVERED,
)
db.add(message)
db.commit()
db.refresh(message)
return {"success": True, "message_id": str(message.id)}

View File

@@ -74,3 +74,20 @@ class InternalEventRequest(BaseModel):
type: str
accountId: str
data: dict
class TransferToQueueRequest(BaseModel):
queue_id: UUID
class TransferToAgentRequest(BaseModel):
agent_id: UUID
class ResolveConversationRequest(BaseModel):
csat_score: Optional[int] = None
csat_feedback: Optional[str] = None
class InternalNoteRequest(BaseModel):
content: str