Commit 79dfe7d5 authored by Vũ Hoàng Anh's avatar Vũ Hoàng Anh

Fix: History API auto-resolve identity from middleware

parent c7883a99
......@@ -9,10 +9,10 @@ Note: identity_key có thể là device_id (guest) hoặc user_id (đã login)
import logging
from typing import Any
from fastapi import APIRouter, HTTPException
from fastapi import APIRouter, HTTPException, Request
from pydantic import BaseModel
from common.conversation_manager import get_conversation_manager
from common.user_identity import get_user_identity
router = APIRouter(tags=["Chat History"])
logger = logging.getLogger(__name__)
......@@ -29,24 +29,22 @@ class ClearHistoryResponse(BaseModel):
@router.get("/api/history/{identity_key}", summary="Get Chat History", response_model=ChatHistoryResponse)
async def get_chat_history(identity_key: str, limit: int | None = 50, before_id: int | None = None):
async def get_chat_history(request: Request, identity_key: str, limit: int | None = 50, before_id: int | None = None):
"""
Lấy lịch sử chat theo identity_key.
identity_key:
- Guest: device_id
- User đã login: user_id (customer_id từ Canifa)
Response bao gồm:
- message: Nội dung tin nhắn
- is_human: True nếu là user, False nếu là AI
- product_ids: List sản phẩm liên quan (chỉ có với AI messages)
- timestamp: Thời gian
- id: ID tin nhắn (dùng cho pagination)
Logic: Middleware đã parse token -> Nếu user đã login thì dùng user_id, không thì dùng device_id.
(identity_key trong URL chỉ là fallback)
"""
try:
# Tự động resolve identity từ middleware
identity = get_user_identity(request)
resolved_key = identity.history_key # user_id nếu login, device_id nếu không
logger.info(f"GET History: URL key={identity_key} -> Resolved key={resolved_key}")
manager = await get_conversation_manager()
history = await manager.get_chat_history(identity_key, limit=limit, before_id=before_id)
history = await manager.get_chat_history(resolved_key, limit=limit, before_id=before_id)
next_cursor = None
if history and len(history) > 0:
......@@ -54,14 +52,15 @@ async def get_chat_history(identity_key: str, limit: int | None = 50, before_id:
return {"data": history, "next_cursor": next_cursor}
except Exception as e:
logger.error(f"Error fetching chat history for {identity_key}: {e}")
logger.error(f"Error fetching chat history: {e}")
raise HTTPException(status_code=500, detail="Failed to fetch chat history")
@router.delete("/api/history/{identity_key}", summary="Clear Chat History", response_model=ClearHistoryResponse)
async def clear_chat_history(identity_key: str):
"""
Xóa toàn bộ lịch sử chat theo identity_key.
Xóa toàn bộ lịch sử chat theo identity_key.
Logic: Middleware đã parse token -> Nếu user đã login thì dùng user_id, không thì dùng device_id.
"""
try:
manager = await get_conversation_manager()
......
......@@ -795,13 +795,20 @@
currentCursor = null;
}
// Use deviceId as identity_key for guest, or call API to get user's history
// For now, use deviceId directly (middleware will handle identity resolution)
const identityKey = deviceId;
const url = `/api/history/${identityKey}?limit=20${currentCursor ? `&before_id=${currentCursor}` : ''}`;
// Gọi API với device_id trong URL, nhưng gửi kèm headers để middleware resolve đúng identity
const url = `/api/history/${deviceId}?limit=20${currentCursor ? `&before_id=${currentCursor}` : ''}`;
// Build headers for identity resolution (middleware sẽ dùng token để override nếu có)
const headers = {
'Content-Type': 'application/json',
'device_id': deviceId
};
if (accessToken) {
headers['Authorization'] = 'Bearer ' + accessToken;
}
try {
const response = await fetch(url);
const response = await fetch(url, { headers: headers });
const data = await response.json();
const messages = data.data || data;
......@@ -820,14 +827,9 @@
}, 100);
} else {
// Load more: messages từ API theo DESC (newest first của batch cũ)
// Ví dụ: [AI 95, User 95, AI 94, User 94, ...]
// Prepend từ index 0: mỗi lần prepend sẽ đẩy cái trước xuống
// Kết quả: User 94 → AI 94 → User 95 → AI 95 (oldest ở trên)
const chatBox = document.getElementById('chatBox');
const oldHeight = chatBox.scrollHeight;
// Loop thuận: prepend từng message từ đầu mảng
// Element đầu (newest của batch) sẽ bị đẩy xuống bởi các element sau
for (let i = 0; i < messages.length; i++) {
appendMessage(messages[i], 'top');
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment