fix(memory): fix timezone and add generate_cache API endpoint


- Fix episodic memory time filter to use UTC (datetime.fromtimestamp with tz=timezone.utc)
  to match Neo4j stored UTC timestamps
- Add POST /v1/memory/analytics/generate_cache endpoint for cache generation via API Key

Modified files:
- api/app/services/memory_explicit_service.py
- api/app/controllers/service/user_memory_api_controller.py
This commit is contained in:
miao
2026-04-23 19:32:13 +08:00
parent 7ac0eff0b8
commit 4619b40d03
2 changed files with 40 additions and 7 deletions

View File

@@ -9,6 +9,7 @@
5./analytics/memory_insight - 记忆洞察接口
6./analytics/interest_distribution - 兴趣分布接口
7./analytics/end_user_info - 终端用户信息接口
8./analytics/generate_cache - 缓存生成接口
路由前缀: /memory
@@ -19,7 +20,7 @@
from typing import Optional
from fastapi import APIRouter, Depends, Header, Query, Request
from fastapi import APIRouter, Depends, Header, Query, Request, Body
from sqlalchemy.orm import Session
from app.core.api_key_auth import require_api_key
@@ -27,6 +28,7 @@ from app.core.api_key_utils import get_current_user_from_api_key, validate_end_u
from app.core.logging_config import get_business_logger
from app.db import get_db
from app.schemas.api_key_schema import ApiKeyAuth
from app.schemas.memory_storage_schema import GenerateCacheRequest
# 包装内部服务 controller
from app.controllers import user_memory_controllers, memory_agent_controller
@@ -194,4 +196,35 @@ async def get_end_user_info(
end_user_id=end_user_id,
current_user=current_user,
db=db,
)
)
# ==================== 缓存生成 ====================
@router.post("/analytics/generate_cache")
@require_api_key(scopes=["memory"])
async def generate_cache(
request: Request,
api_key_auth: ApiKeyAuth = None,
db: Session = Depends(get_db),
message: str = Body(None, description="Request body"),
language_type: str = Header(default=None, alias="X-Language-Type"),
):
"""Trigger cache generation (user summary + memory insight) for an end user or all workspace users."""
body = await request.json()
cache_request = GenerateCacheRequest(**body)
current_user = get_current_user_from_api_key(db, api_key_auth)
if cache_request.end_user_id:
validate_end_user_in_workspace(db, cache_request.end_user_id, api_key_auth.workspace_id)
return await user_memory_controllers.generate_cache_api(
request=cache_request,
language_type=language_type,
current_user=current_user,
db=db,
)

View File

@@ -201,12 +201,12 @@ class MemoryExplicitService(MemoryBaseService):
where_clauses = ["s.end_user_id = $end_user_id"]
params = {"end_user_id": end_user_id}
# 时间戳筛选(毫秒时间戳转为 ISO 字符串,使用 Neo4j datetime() 精确比较)
# 时间戳筛选(毫秒时间戳转为 UTC ISO 字符串,使用 Neo4j datetime() 精确比较)
if start_date is not None and end_date is not None:
from datetime import datetime
start_dt = datetime.fromtimestamp(start_date / 1000)
end_dt = datetime.fromtimestamp(end_date / 1000)
# 开始时间取当天 00:00:00结束时间取当天 23:59:59.999999
from datetime import datetime, timezone
start_dt = datetime.fromtimestamp(start_date / 1000, tz=timezone.utc)
end_dt = datetime.fromtimestamp(end_date / 1000, tz=timezone.utc)
# 开始时间取当天 UTC 00:00:00结束时间取当天 UTC 23:59:59.999999
start_iso = start_dt.strftime("%Y-%m-%dT") + "00:00:00.000000"
end_iso = end_dt.strftime("%Y-%m-%dT") + "23:59:59.999999"