refactor(memory-api): migrate end user creation to authenticated API endpoint

- Remove unauthenticated end_user_controller and its router registration
- Move end user creation logic to authenticated memory_api_controller endpoint
- Add create_end_user method to MemoryAPIService with workspace authorization
- Fix retrieve_nodes import in read_graph to use correct function reference
- Consolidate end user management under authenticated memory API with API key scoping
This commit is contained in:
Ke Sun
2026-03-26 20:12:11 +08:00
parent 3ed6f49bb0
commit a5bce221bd
5 changed files with 80 additions and 53 deletions

View File

@@ -14,7 +14,6 @@ from . import (
document_controller,
emotion_config_controller,
emotion_controller,
end_user_controller,
file_controller,
file_storage_controller,
home_page_controller,
@@ -99,6 +98,5 @@ manager_router.include_router(file_storage_controller.router)
manager_router.include_router(ontology_controller.router)
manager_router.include_router(skill_controller.router)
manager_router.include_router(i18n_controller.router)
manager_router.include_router(end_user_controller.router)
__all__ = ["manager_router"]

View File

@@ -1,48 +0,0 @@
"""End User 管理接口 - 无需认证"""
from app.core.logging_config import get_business_logger
from app.core.response_utils import success
from app.db import get_db
from app.repositories.end_user_repository import EndUserRepository
from app.schemas.memory_api_schema import (
CreateEndUserRequest,
CreateEndUserResponse,
)
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
router = APIRouter(prefix="/end_users", tags=["End Users"])
logger = get_business_logger()
@router.post("")
async def create_end_user(
data: CreateEndUserRequest,
db: Session = Depends(get_db),
):
"""
Create an end user.
Creates a new end user for the given workspace.
If an end user with the same other_id already exists in the workspace,
returns the existing one.
"""
logger.info(f"Create end user request - other_id: {data.other_id}, workspace_id: {data.workspace_id}")
end_user_repo = EndUserRepository(db)
end_user = end_user_repo.get_or_create_end_user(
app_id=None,
workspace_id=data.workspace_id,
other_id=data.other_id,
)
logger.info(f"End user ready: {end_user.id}")
result = {
"id": str(end_user.id),
"other_id": end_user.other_id or "",
"other_name": end_user.other_name or "",
"workspace_id": str(end_user.workspace_id),
}
return success(data=CreateEndUserResponse(**result).model_dump(), msg="End user created successfully")

View File

@@ -6,6 +6,8 @@ from app.core.response_utils import success
from app.db import get_db
from app.schemas.api_key_schema import ApiKeyAuth
from app.schemas.memory_api_schema import (
CreateEndUserRequest,
CreateEndUserResponse,
ListConfigsResponse,
MemoryReadRequest,
MemoryReadResponse,
@@ -113,3 +115,31 @@ async def list_memory_configs(
logger.info(f"Listed {result['total']} configs for workspace: {api_key_auth.workspace_id}")
return success(data=ListConfigsResponse(**result).model_dump(), msg="Configs listed successfully")
@router.post("/end_users")
@require_api_key(scopes=["memory"])
async def create_end_user(
request: Request,
api_key_auth: ApiKeyAuth = None,
db: Session = Depends(get_db),
):
"""
Create an end user.
Creates a new end user for the authorized workspace.
If an end user with the same other_id already exists, returns the existing one.
"""
body = await request.json()
payload = CreateEndUserRequest(**body)
logger.info(f"Create end user request - other_id: {payload.other_id}, workspace_id: {api_key_auth.workspace_id}")
memory_api_service = MemoryAPIService(db)
result = memory_api_service.create_end_user(
workspace_id=api_key_auth.workspace_id,
other_id=payload.other_id,
)
logger.info(f"End user ready: {result['id']}")
return success(data=CreateEndUserResponse(**result).model_dump(), msg="End user created successfully")

View File

@@ -15,7 +15,7 @@ from app.core.memory.agent.langgraph_graph.nodes.problem_nodes import (
Problem_Extension,
)
from app.core.memory.agent.langgraph_graph.nodes.retrieve_nodes import (
retrieve,
retrieve_nodes,
)
from app.core.memory.agent.langgraph_graph.nodes.summary_nodes import (
Input_Summary,
@@ -53,8 +53,8 @@ async def make_read_graph():
workflow.add_node("Split_The_Problem", Split_The_Problem)
workflow.add_node("Problem_Extension", Problem_Extension)
workflow.add_node("Input_Summary", Input_Summary)
# workflow.add_node("Retrieve", retrieve_nodes)
workflow.add_node("Retrieve", retrieve)
workflow.add_node("Retrieve", retrieve_nodes)
# workflow.add_node("Retrieve", retrieve)
workflow.add_node("Verify", Verify)
workflow.add_node("Retrieve_Summary", Retrieve_Summary)
workflow.add_node("Summary", Summary)

View File

@@ -280,6 +280,53 @@ class MemoryAPIService:
code=BizCode.MEMORY_READ_FAILED
)
def create_end_user(
self,
workspace_id: uuid.UUID,
other_id: str,
) -> Dict[str, Any]:
"""Create or retrieve an end user for the workspace.
Uses get_or_create semantics: if an end user with the same other_id
already exists in the workspace, returns the existing one.
Args:
workspace_id: Workspace ID from API key authorization
other_id: External user identifier
Returns:
Dict with id, other_id, other_name, and workspace_id
Raises:
BusinessException: If creation fails
"""
logger.info(f"Creating end user - other_id: {other_id}, workspace_id: {workspace_id}")
try:
from app.repositories.end_user_repository import EndUserRepository
end_user_repo = EndUserRepository(self.db)
end_user = end_user_repo.get_or_create_end_user(
app_id=None,
workspace_id=workspace_id,
other_id=other_id,
)
logger.info(f"End user ready: {end_user.id}")
return {
"id": str(end_user.id),
"other_id": end_user.other_id or "",
"other_name": end_user.other_name or "",
"workspace_id": str(end_user.workspace_id),
}
except Exception as e:
logger.error(f"Failed to create end user for workspace {workspace_id}: {e}")
raise BusinessException(
message=f"Failed to create end user: {str(e)}",
code=BizCode.INTERNAL_ERROR
)
def list_memory_configs(
self,
workspace_id: uuid.UUID,