# api/decision_api.py
from fastapi import APIRouter, HTTPException, Form, Query
from fastapi.responses import HTMLResponse, RedirectResponse
from typing import Dict, Any, Optional
import logging
from services.analytics_service import analytics_service
logger = logging.getLogger(__name__)
decision_router = APIRouter()
@decision_router.get("/approve/{decision_id}")
async def approve_decision(decision_id: str):
"""
โ
Approve sponsor decision - sends contract to influencer
"""
try:
logger.info(f"๐ Processing approval for decision: {decision_id}")
result = await analytics_service.process_sponsor_decision(
decision_id=decision_id,
decision="approve"
)
if result["status"] == "success":
return HTMLResponse(content=f"""
Decision Approved
โ
Decision Approved!
Contract has been sent to the influencer
Decision ID: {decision_id}
Action: {result.get('action', 'N/A')}
Influencer Email: {result.get('influencer_email', 'N/A')}
The influencer will receive a contract email with all the negotiated terms.
""")
else:
# Handle error cases with user-friendly HTML instead of exceptions
return HTMLResponse(content=f"""
Decision Processing Issue
โ ๏ธ Decision Cannot Be Processed
{result.get('message', 'Unknown error occurred')}
Decision ID: {decision_id}
Possible reasons:
- This decision link has already been used
- The decision has expired (48-hour limit)
- The server was restarted, clearing temporary data
If you need to make a decision on this collaboration, please contact the campaign manager directly.
""", status_code=200) # Use 200 instead of 400 for better user experience
except Exception as e:
logger.error(f"โ Error processing approval: {str(e)}")
# Return user-friendly error page instead of throwing exception
return HTMLResponse(content=f"""
System Error
โ System Error
Unable to process your decision at this time
Decision ID: {decision_id}
Please try again later or contact support if the issue persists.
Error: {str(e)}
""", status_code=500)
@decision_router.get("/reject/{decision_id}")
async def reject_decision_form(decision_id: str):
"""
โ Show rejection form for sponsor to provide message
"""
return HTMLResponse(content=f"""
Reject Decision
โ Reject Collaboration
Note: This will send a polite rejection email to the influencer.
Decision ID: {decision_id}
""")
@decision_router.post("/reject/{decision_id}")
async def reject_decision(decision_id: str, message: str = Form("")):
"""
โ Process rejection decision - sends regret email to influencer
"""
try:
logger.info(f"๐ Processing rejection for decision: {decision_id}")
result = await analytics_service.process_sponsor_decision(
decision_id=decision_id,
decision="reject",
sponsor_message=message if message.strip() else None
)
if result["status"] == "success":
return HTMLResponse(content=f"""
Decision Rejected
โ Decision Rejected
Regret email has been sent to the influencer
Decision ID: {decision_id}
Action: {result.get('action', 'N/A')}
Influencer Email: {result.get('influencer_email', 'N/A')}
The influencer has been politely notified that we won't be proceeding with this collaboration.
""")
else:
# Handle error cases with user-friendly HTML instead of exceptions
return HTMLResponse(content=f"""
Decision Processing Issue
โ ๏ธ Decision Cannot Be Processed
{result.get('message', 'Unknown error occurred')}
Decision ID: {decision_id}
Possible reasons:
- This decision link has already been used
- The decision has expired (48-hour limit)
- The server was restarted, clearing temporary data
If you need to make a decision on this collaboration, please contact the campaign manager directly.
""", status_code=200)
except Exception as e:
logger.error(f"โ Error processing rejection: {str(e)}")
# Return user-friendly error page instead of throwing exception
return HTMLResponse(content=f"""
System Error
โ System Error
Unable to process your decision at this time
Decision ID: {decision_id}
Please try again later or contact support if the issue persists.
Error: {str(e)}
""", status_code=500)
@decision_router.get("/pending")
async def get_pending_decisions():
"""
๐ Get all pending sponsor decisions
"""
try:
pending = analytics_service.get_pending_decisions()
return {
"status": "success",
"pending_decisions": pending
}
except Exception as e:
logger.error(f"โ Error getting pending decisions: {str(e)}")
raise HTTPException(status_code=500, detail=f"Failed to get pending decisions: {str(e)}")
@decision_router.post("/test-analytics")
async def test_analytics_workflow(test_data: Dict[str, Any]):
"""
๐งช Test the analytics workflow with sample data
"""
try:
logger.info("๐งช Testing analytics workflow...")
# Sample call data
call_data = {
"conversation_id": "test_conv_12345",
"call_duration_seconds": 180,
"status": "completed",
"negotiation_results": {
"final_rate": test_data.get("final_rate", 2500),
"deliverables": ["1 Instagram post", "3 Instagram stories"],
"timeline": "2 weeks",
"creator_enthusiasm": 8,
"special_terms": ["Usage rights for 6 months"]
},
"influencer_data": {
"name": test_data.get("influencer_name", "Test Influencer"),
"email": test_data.get("influencer_email", "test@example.com"),
"platform": "Instagram"
}
}
# Sample campaign data
campaign_data = {
"campaign_name": test_data.get("campaign_name", "Test Product Launch"),
"brand_name": test_data.get("brand_name", "Test Brand"),
"product_name": "Test Product Pro",
"total_budget": 10000,
"offered_rate": test_data.get("original_rate", 2000)
}
# Test sponsor email
sponsor_email = test_data.get("sponsor_email", "sponsor@testbrand.com")
# Process the completed call
result = await analytics_service.process_completed_call(
call_data=call_data,
campaign_data=campaign_data,
sponsor_email=sponsor_email
)
if result["status"] == "success":
return {
"status": "success",
"message": "Analytics workflow test completed successfully",
"decision_id": result["decision_id"],
"analytics_sent": result["email_sent"],
"test_urls": {
"approve": f"/api/decision/approve/{result['decision_id']}",
"reject": f"/api/decision/reject/{result['decision_id']}"
},
"analytics_report": result["analytics_report"]
}
else:
return {
"status": "error",
"message": result["message"]
}
except Exception as e:
logger.error(f"โ Error testing analytics workflow: {str(e)}")
raise HTTPException(status_code=500, detail=f"Test failed: {str(e)}")