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:
@@ -45,6 +45,10 @@ class ChatbotAnalyticsResponse(BaseModel):
|
||||
top_queries: List[TopQuery]
|
||||
languages_used: Dict[str, int]
|
||||
peak_hour: Optional[int] # 0-23
|
||||
unanswered_count: int = 0
|
||||
unanswered_queries: List[TopQuery] = []
|
||||
feedback_positive: int = 0
|
||||
feedback_negative: int = 0
|
||||
|
||||
|
||||
class OverviewAnalyticsResponse(BaseModel):
|
||||
@@ -212,6 +216,13 @@ async def get_analytics_overview(user=Depends(get_current_user)):
|
||||
if rating:
|
||||
all_ratings.append(rating)
|
||||
|
||||
# Feedback counts
|
||||
fb_result = supabase.table("message_feedback").select("feedback", count="exact") \
|
||||
.eq("chatbot_id", cid).execute()
|
||||
total_fb = fb_result.count or 0
|
||||
fb_pos = sum(1 for f in (fb_result.data or []) if f.get("feedback") == "positive")
|
||||
fb_neg = total_fb - fb_pos
|
||||
|
||||
# Average messages per conversation
|
||||
avg_msgs = round(msg_count / conv_count, 1) if conv_count > 0 else 0.0
|
||||
|
||||
@@ -223,7 +234,7 @@ async def get_analytics_overview(user=Depends(get_current_user)):
|
||||
total_messages=msg_count,
|
||||
average_messages_per_conversation=avg_msgs,
|
||||
average_rating=rating,
|
||||
total_ratings=0, # would need a ratings table for precise count
|
||||
total_ratings=total_fb,
|
||||
conversations_today=today_count,
|
||||
conversations_this_week=week_count,
|
||||
conversations_this_month=month_count,
|
||||
@@ -231,6 +242,8 @@ async def get_analytics_overview(user=Depends(get_current_user)):
|
||||
top_queries=top_queries,
|
||||
languages_used=lang_counts,
|
||||
peak_hour=peak,
|
||||
feedback_positive=fb_pos,
|
||||
feedback_negative=fb_neg,
|
||||
))
|
||||
|
||||
# Overall average rating
|
||||
@@ -345,6 +358,48 @@ async def get_chatbot_analytics(chatbot_id: str, user=Depends(get_current_user))
|
||||
|
||||
avg_msgs = round(msg_count / conv_count, 1) if conv_count > 0 else 0.0
|
||||
|
||||
# Feedback counts
|
||||
fb_pos = 0
|
||||
fb_neg = 0
|
||||
if conv_ids and conv_ids != [""]:
|
||||
feedback = supabase.table("message_feedback").select("feedback") \
|
||||
.eq("chatbot_id", chatbot_id).execute()
|
||||
for f in (feedback.data or []):
|
||||
if f["feedback"] == "positive":
|
||||
fb_pos += 1
|
||||
else:
|
||||
fb_neg += 1
|
||||
|
||||
# Unanswered queries (low confidence)
|
||||
unanswered_queries: List[TopQuery] = []
|
||||
unanswered_count = 0
|
||||
if conv_ids and conv_ids != [""]:
|
||||
try:
|
||||
low_conf_msgs = supabase.table("messages").select("id, conversation_id, confidence_score") \
|
||||
.in_("conversation_id", conv_ids[:100]) \
|
||||
.eq("role", "assistant") \
|
||||
.lt("confidence_score", 0.2) \
|
||||
.limit(200).execute()
|
||||
unanswered_count = len(low_conf_msgs.data or [])
|
||||
# For each low-confidence assistant message, find the preceding user message
|
||||
if low_conf_msgs.data:
|
||||
unanswered_q_counts: Dict[str, int] = {}
|
||||
for lm in low_conf_msgs.data[:20]: # limit work
|
||||
prev_user = supabase.table("messages").select("content") \
|
||||
.eq("conversation_id", lm["conversation_id"]) \
|
||||
.eq("role", "user") \
|
||||
.lt("created_at", lm.get("created_at", "9999")) \
|
||||
.order("created_at", desc=True) \
|
||||
.limit(1).execute()
|
||||
if prev_user.data:
|
||||
q = (prev_user.data[0].get("content") or "")[:100].strip()
|
||||
if q:
|
||||
unanswered_q_counts[q] = unanswered_q_counts.get(q, 0) + 1
|
||||
top_unanswered = sorted(unanswered_q_counts.items(), key=lambda x: -x[1])[:5]
|
||||
unanswered_queries = [TopQuery(query=q, count=n) for q, n in top_unanswered]
|
||||
except Exception:
|
||||
pass # unanswered queries is optional
|
||||
|
||||
return ChatbotAnalyticsResponse(
|
||||
chatbot_id=chatbot_id,
|
||||
chatbot_name=cb.get("name", "Untitled"),
|
||||
@@ -353,7 +408,7 @@ async def get_chatbot_analytics(chatbot_id: str, user=Depends(get_current_user))
|
||||
total_messages=msg_count,
|
||||
average_messages_per_conversation=avg_msgs,
|
||||
average_rating=cb.get("average_rating"),
|
||||
total_ratings=0,
|
||||
total_ratings=fb_pos + fb_neg,
|
||||
conversations_today=today_count,
|
||||
conversations_this_week=week_count,
|
||||
conversations_this_month=month_count,
|
||||
@@ -361,4 +416,56 @@ async def get_chatbot_analytics(chatbot_id: str, user=Depends(get_current_user))
|
||||
top_queries=top_queries,
|
||||
languages_used=lang_counts,
|
||||
peak_hour=peak,
|
||||
unanswered_count=unanswered_count,
|
||||
unanswered_queries=unanswered_queries,
|
||||
feedback_positive=fb_pos,
|
||||
feedback_negative=fb_neg,
|
||||
)
|
||||
|
||||
|
||||
@router.get("/chatbot/{chatbot_id}/gaps", response_model=List[TopQuery])
|
||||
async def get_knowledge_gaps(chatbot_id: str, user=Depends(get_current_user)):
|
||||
"""Returns top queries where the bot had low confidence (knowledge gaps). Starter+ only."""
|
||||
plan = _get_user_plan(user.id)
|
||||
_check_analytics_access(plan)
|
||||
|
||||
supabase = get_supabase()
|
||||
company = supabase.table("companies").select("id").eq("owner_id", user.id).execute()
|
||||
if not company.data:
|
||||
raise HTTPException(status_code=404, detail="Company not found")
|
||||
|
||||
chatbot = supabase.table("chatbots").select("id") \
|
||||
.eq("id", chatbot_id).eq("company_id", company.data[0]["id"]).execute()
|
||||
if not chatbot.data:
|
||||
raise HTTPException(status_code=404, detail="Chatbot not found")
|
||||
|
||||
# Find conversations
|
||||
convs = supabase.table("conversations").select("id").eq("chatbot_id", chatbot_id).execute()
|
||||
conv_ids = [c["id"] for c in (convs.data or [])]
|
||||
if not conv_ids:
|
||||
return []
|
||||
|
||||
# Low confidence assistant messages
|
||||
low_conf = supabase.table("messages").select("id, conversation_id, created_at") \
|
||||
.in_("conversation_id", conv_ids[:100]) \
|
||||
.eq("role", "assistant") \
|
||||
.lt("confidence_score", 0.2) \
|
||||
.limit(100).execute()
|
||||
|
||||
if not low_conf.data:
|
||||
return []
|
||||
|
||||
q_counts: Dict[str, int] = {}
|
||||
for msg in low_conf.data[:30]:
|
||||
prev = supabase.table("messages").select("content") \
|
||||
.eq("conversation_id", msg["conversation_id"]) \
|
||||
.eq("role", "user") \
|
||||
.order("created_at", desc=True) \
|
||||
.limit(1).execute()
|
||||
if prev.data:
|
||||
content = (prev.data[0].get("content") or "")[:100].strip()
|
||||
if content:
|
||||
q_counts[content] = q_counts.get(content, 0) + 1
|
||||
|
||||
sorted_gaps = sorted(q_counts.items(), key=lambda x: -x[1])[:10]
|
||||
return [TopQuery(query=q, count=n) for q, n in sorted_gaps]
|
||||
|
||||
Reference in New Issue
Block a user