import uuid from typing import Optional from fastapi import APIRouter, Depends, Query from sqlalchemy.orm import Session from app.core.error_codes import BizCode from app.core.logging_config import get_api_logger from app.core.response_utils import success, fail from app.db import get_db from app.dependencies import get_current_user from app.models import User from app.models.memory_perceptual_model import PerceptualType from app.schemas.memory_perceptual_schema import ( PerceptualQuerySchema, PerceptualFilter ) from app.schemas.response_schema import ApiResponse from app.services.memory_perceptual_service import MemoryPerceptualService api_logger = get_api_logger() router = APIRouter( prefix="/memory/perceptual", tags=["Perceptual Memory System"], dependencies=[Depends(get_current_user)] ) @router.get("/{end_user_id}/count", response_model=ApiResponse) def get_memory_count( end_user_id: uuid.UUID, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): """Retrieve perceptual memory statistics for a user group. Args: end_user_id: ID of the user group (usually end_user_id in this context) current_user: Current authenticated user db: Database session Returns: ApiResponse: Response containing memory count statistics """ api_logger.info(f"Fetching perceptual memory statistics: user={current_user.username}, end_user_id={end_user_id}") try: service = MemoryPerceptualService(db) count_stats = service.get_memory_count(end_user_id) api_logger.info(f"Memory statistics fetched successfully: total={count_stats.get('total', 0)}") return success( data=count_stats, msg="Memory statistics retrieved successfully" ) except Exception as e: api_logger.error(f"Failed to fetch memory statistics: end_user_id={end_user_id}, error={str(e)}") return fail( code=BizCode.INTERNAL_ERROR, msg="Failed to fetch memory statistics", ) @router.get("/{end_user_id}/last_visual", response_model=ApiResponse) def get_last_visual_memory( end_user_id: uuid.UUID, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): """Retrieve the most recent VISION-type memory for a user. Args: end_user_id: ID of the user group current_user: Current authenticated user db: Database session Returns: ApiResponse: Metadata of the latest visual memory """ api_logger.info(f"Fetching latest visual memory: user={current_user.username}, end_user_id={end_user_id}") try: service = MemoryPerceptualService(db) visual_memory = service.get_latest_visual_memory(end_user_id) if visual_memory is None: api_logger.info(f"No visual memory found: end_user_id={end_user_id}") return success( data=None, msg="No visual memory available" ) api_logger.info(f"Latest visual memory retrieved successfully: file={visual_memory.get('file_name')}") return success( data=visual_memory, msg="Latest visual memory retrieved successfully" ) except Exception as e: api_logger.error(f"Failed to fetch latest visual memory: end_user_id={end_user_id}, error={str(e)}") return fail( code=BizCode.INTERNAL_ERROR, msg="Failed to fetch latest visual memory", ) @router.get("/{end_user_id}/last_listen", response_model=ApiResponse) def get_last_memory_listen( end_user_id: uuid.UUID, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): """Retrieve the most recent AUDIO-type memory for a user. Args: end_user_id: ID of the user group current_user: Current authenticated user db: Database session Returns: ApiResponse: Metadata of the latest audio memory """ api_logger.info(f"Fetching latest audio memory: user={current_user.username}, end_user_id={end_user_id}") try: service = MemoryPerceptualService(db) audio_memory = service.get_latest_audio_memory(end_user_id) if audio_memory is None: api_logger.info(f"No audio memory found: end_user_id={end_user_id}") return success( data=None, msg="No audio memory available" ) api_logger.info(f"Latest audio memory retrieved successfully: file={audio_memory.get('file_name')}") return success( data=audio_memory, msg="Latest audio memory retrieved successfully" ) except Exception as e: api_logger.error(f"Failed to fetch latest audio memory: end_user_id={end_user_id}, error={str(e)}") return fail( code=BizCode.INTERNAL_ERROR, msg="Failed to fetch latest audio memory", ) @router.get("/{end_user_id}/last_text", response_model=ApiResponse) def get_last_text_memory( end_user_id: uuid.UUID, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): """Retrieve the most recent TEXT-type memory for a user. Args: end_user_id: ID of the user group current_user: Current authenticated user db: Database session Returns: ApiResponse: Metadata of the latest text memory """ api_logger.info(f"Fetching latest text memory: user={current_user.username}, end_user_id={end_user_id}") try: # 调用服务层获取最近的文本记忆 service = MemoryPerceptualService(db) text_memory = service.get_latest_text_memory(end_user_id) if text_memory is None: api_logger.info(f"No text memory found: end_user_id={end_user_id}") return success( data=None, msg="No text memory available" ) api_logger.info(f"Latest text memory retrieved successfully: file={text_memory.get('file_name')}") return success( data=text_memory, msg="Latest text memory retrieved successfully" ) except Exception as e: api_logger.error(f"Failed to fetch latest text memory: end_user_id={end_user_id}, error={str(e)}") return fail( code=BizCode.INTERNAL_ERROR, msg="Failed to fetch latest text memory", ) @router.get("/{end_user_id}/timeline", response_model=ApiResponse) def get_memory_time_line( end_user_id: uuid.UUID, perceptual_type: Optional[PerceptualType] = Query(None, description="感知类型过滤"), page: int = Query(1, ge=1, description="页码"), page_size: int = Query(10, ge=1, le=100, description="每页大小"), current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): """Retrieve a timeline of perceptual memories for a user group. Args: end_user_id: ID of the user group perceptual_type: Optional filter for perceptual type page: Page number for pagination page_size: Number of items per page current_user: Current authenticated user db: Database session Returns: ApiResponse: Timeline data of perceptual memories """ api_logger.info( f"Fetching perceptual memory timeline: user={current_user.username}, " f"end_user_id={end_user_id}, type={perceptual_type}, page={page}" ) try: query = PerceptualQuerySchema( filter=PerceptualFilter(type=perceptual_type), page=page, page_size=page_size ) service = MemoryPerceptualService(db) timeline_data = service.get_time_line(end_user_id, query) api_logger.info( f"Perceptual memory timeline retrieved successfully: total={timeline_data.total}, " f"returned={len(timeline_data.memories)}" ) return success( data=timeline_data.model_dump(), msg="Perceptual memory timeline retrieved successfully" ) except Exception as e: api_logger.error( f"Failed to fetch perceptual memory timeline: end_user_id={end_user_id}, " f"error={str(e)}" ) return fail( code=BizCode.INTERNAL_ERROR, msg="Failed to fetch perceptual memory timeline", )