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) ...@@ -9,10 +9,10 @@ Note: identity_key có thể là device_id (guest) hoặc user_id (đã login)
import logging import logging
from typing import Any from typing import Any
from fastapi import APIRouter, HTTPException from fastapi import APIRouter, HTTPException, Request
from pydantic import BaseModel from pydantic import BaseModel
from common.conversation_manager import get_conversation_manager from common.conversation_manager import get_conversation_manager
from common.user_identity import get_user_identity
router = APIRouter(tags=["Chat History"]) router = APIRouter(tags=["Chat History"])
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
...@@ -29,24 +29,22 @@ class ClearHistoryResponse(BaseModel): ...@@ -29,24 +29,22 @@ class ClearHistoryResponse(BaseModel):
@router.get("/api/history/{identity_key}", summary="Get Chat History", response_model=ChatHistoryResponse) @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. Lấy lịch sử chat theo identity_key.
identity_key: Logic: Middleware đã parse token -> Nếu user đã login thì dùng user_id, không thì dùng device_id.
- Guest: device_id (identity_key trong URL chỉ là fallback)
- 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)
""" """
try: 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() 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 next_cursor = None
if history and len(history) > 0: if history and len(history) > 0:
...@@ -54,14 +52,15 @@ async def get_chat_history(identity_key: str, limit: int | None = 50, before_id: ...@@ -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} return {"data": history, "next_cursor": next_cursor}
except Exception as e: 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") raise HTTPException(status_code=500, detail="Failed to fetch chat history")
@router.delete("/api/history/{identity_key}", summary="Clear Chat History", response_model=ClearHistoryResponse) @router.delete("/api/history/{identity_key}", summary="Clear Chat History", response_model=ClearHistoryResponse)
async def clear_chat_history(identity_key: str): 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: try:
manager = await get_conversation_manager() manager = await get_conversation_manager()
......
...@@ -795,13 +795,20 @@ ...@@ -795,13 +795,20 @@
currentCursor = null; currentCursor = null;
} }
// Use deviceId as identity_key for guest, or call API to get user's history // Gọi API với device_id trong URL, nhưng gửi kèm headers để middleware resolve đúng identity
// For now, use deviceId directly (middleware will handle identity resolution) const url = `/api/history/${deviceId}?limit=20${currentCursor ? `&before_id=${currentCursor}` : ''}`;
const identityKey = deviceId;
const url = `/api/history/${identityKey}?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 { try {
const response = await fetch(url); const response = await fetch(url, { headers: headers });
const data = await response.json(); const data = await response.json();
const messages = data.data || data; const messages = data.data || data;
...@@ -820,14 +827,9 @@ ...@@ -820,14 +827,9 @@
}, 100); }, 100);
} else { } else {
// Load more: messages từ API theo DESC (newest first của batch cũ) // 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 chatBox = document.getElementById('chatBox');
const oldHeight = chatBox.scrollHeight; 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++) { for (let i = 0; i < messages.length; i++) {
appendMessage(messages[i], 'top'); 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