mirror of
http://88.130.71.182:3000/BlitTech/contexta_be.git
synced 2026-06-12 23:23:21 +00:00
updates Mar6
This commit is contained in:
162
app/routers/inbox.py
Normal file
162
app/routers/inbox.py
Normal file
@@ -0,0 +1,162 @@
|
||||
from fastapi import APIRouter, HTTPException, Depends, Query
|
||||
from app.database import get_supabase
|
||||
from app.dependencies import get_current_user
|
||||
from app.config import PLAN_LIMITS
|
||||
from app.models import InboxConversation, InboxMessage
|
||||
from typing import List, Optional
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
router = APIRouter(prefix="/inbox", tags=["Inbox"])
|
||||
|
||||
|
||||
def _check_inbox_access(user_id: str, supabase):
|
||||
sub = supabase.table("subscriptions").select("plan").eq("user_id", user_id).eq("status", "active").execute()
|
||||
plan = sub.data[0]["plan"] if sub.data else "free"
|
||||
if plan not in ("starter", "business", "agency", "enterprise"):
|
||||
raise HTTPException(status_code=402, detail="Conversation inbox requires Starter plan or higher")
|
||||
return plan
|
||||
|
||||
|
||||
def _get_user_company_id(user_id: str, supabase) -> str:
|
||||
result = supabase.table("companies").select("id").eq("owner_id", user_id).execute()
|
||||
if not result.data:
|
||||
raise HTTPException(status_code=404, detail="Company not found")
|
||||
return result.data[0]["id"]
|
||||
|
||||
|
||||
@router.get("/conversations", response_model=List[InboxConversation])
|
||||
async def list_inbox_conversations(
|
||||
chatbot_id: Optional[str] = Query(None),
|
||||
page: int = Query(1, ge=1),
|
||||
limit: int = Query(20, ge=1, le=100),
|
||||
user=Depends(get_current_user),
|
||||
):
|
||||
"""List conversations for all (or one) of the user's chatbots."""
|
||||
supabase = get_supabase()
|
||||
_check_inbox_access(user.id, supabase)
|
||||
company_id = _get_user_company_id(user.id, supabase)
|
||||
|
||||
# Get user's chatbots
|
||||
chatbots_query = supabase.table("chatbots").select("id, name").eq("company_id", company_id)
|
||||
if chatbot_id:
|
||||
chatbots_query = chatbots_query.eq("id", chatbot_id)
|
||||
chatbots_result = chatbots_query.execute()
|
||||
chatbot_map = {c["id"]: c["name"] for c in (chatbots_result.data or [])}
|
||||
|
||||
if not chatbot_map:
|
||||
return []
|
||||
|
||||
chatbot_ids = list(chatbot_map.keys())
|
||||
offset = (page - 1) * limit
|
||||
|
||||
# Query conversations
|
||||
convs = supabase.table("conversations").select("*") \
|
||||
.in_("chatbot_id", chatbot_ids) \
|
||||
.order("created_at", desc=True) \
|
||||
.range(offset, offset + limit - 1) \
|
||||
.execute()
|
||||
|
||||
results = []
|
||||
for conv in (convs.data or []):
|
||||
cid = conv["id"]
|
||||
|
||||
# Get first user message for preview
|
||||
first_msg = supabase.table("messages").select("content") \
|
||||
.eq("conversation_id", cid) \
|
||||
.eq("role", "user") \
|
||||
.order("created_at", desc=False) \
|
||||
.limit(1) \
|
||||
.execute()
|
||||
|
||||
first_message_text = first_msg.data[0]["content"] if first_msg.data else None
|
||||
|
||||
results.append(InboxConversation(
|
||||
id=cid,
|
||||
chatbot_id=conv["chatbot_id"],
|
||||
chatbot_name=chatbot_map.get(conv["chatbot_id"], "Unknown"),
|
||||
session_id=conv.get("session_id"),
|
||||
language=conv.get("language", "en"),
|
||||
message_count=conv.get("message_count", 0),
|
||||
first_message=first_message_text,
|
||||
created_at=conv.get("created_at"),
|
||||
))
|
||||
|
||||
return results
|
||||
|
||||
|
||||
@router.get("/conversations/{conversation_id}")
|
||||
async def get_inbox_conversation(
|
||||
conversation_id: str,
|
||||
user=Depends(get_current_user),
|
||||
):
|
||||
"""Get a full conversation thread with all messages."""
|
||||
supabase = get_supabase()
|
||||
_check_inbox_access(user.id, supabase)
|
||||
company_id = _get_user_company_id(user.id, supabase)
|
||||
|
||||
# Verify ownership
|
||||
conv = supabase.table("conversations").select("*, chatbots(company_id, name)") \
|
||||
.eq("id", conversation_id) \
|
||||
.execute()
|
||||
|
||||
if not conv.data:
|
||||
raise HTTPException(status_code=404, detail="Conversation not found")
|
||||
|
||||
c = conv.data[0]
|
||||
chatbot_data = c.get("chatbots") or {}
|
||||
if chatbot_data.get("company_id") != company_id:
|
||||
raise HTTPException(status_code=403, detail="Not authorized")
|
||||
|
||||
# Get messages
|
||||
msgs = supabase.table("messages").select("*") \
|
||||
.eq("conversation_id", conversation_id) \
|
||||
.order("created_at", desc=False) \
|
||||
.execute()
|
||||
|
||||
messages = [
|
||||
InboxMessage(
|
||||
id=m["id"],
|
||||
role=m["role"],
|
||||
content=m["content"],
|
||||
sources=m.get("sources"),
|
||||
confidence_score=m.get("confidence_score"),
|
||||
is_handoff=m.get("is_handoff", False),
|
||||
created_at=m.get("created_at"),
|
||||
)
|
||||
for m in (msgs.data or [])
|
||||
]
|
||||
|
||||
return {
|
||||
"conversation_id": conversation_id,
|
||||
"chatbot_name": chatbot_data.get("name", "Unknown"),
|
||||
"language": c.get("language", "en"),
|
||||
"session_id": c.get("session_id"),
|
||||
"created_at": c.get("created_at"),
|
||||
"messages": [m.model_dump() for m in messages],
|
||||
}
|
||||
|
||||
|
||||
@router.delete("/conversations/{conversation_id}")
|
||||
async def delete_inbox_conversation(
|
||||
conversation_id: str,
|
||||
user=Depends(get_current_user),
|
||||
):
|
||||
"""Delete a conversation and all its messages."""
|
||||
supabase = get_supabase()
|
||||
_check_inbox_access(user.id, supabase)
|
||||
company_id = _get_user_company_id(user.id, supabase)
|
||||
|
||||
# Verify ownership
|
||||
conv = supabase.table("conversations").select("*, chatbots(company_id)") \
|
||||
.eq("id", conversation_id).execute()
|
||||
|
||||
if not conv.data:
|
||||
raise HTTPException(status_code=404, detail="Conversation not found")
|
||||
|
||||
chatbot_data = conv.data[0].get("chatbots") or {}
|
||||
if chatbot_data.get("company_id") != company_id:
|
||||
raise HTTPException(status_code=403, detail="Not authorized")
|
||||
|
||||
supabase.table("conversations").delete().eq("id", conversation_id).execute()
|
||||
return {"success": True}
|
||||
Reference in New Issue
Block a user