Files
ai_agent/backend/app/api/routes/v1/admin_conversations.py
T
furyhawk 8351e73d39 feat: add Zustand stores for conversation, file preview, sidebar, theme, and knowledge base selection
- Implemented `conversation-store` for managing conversations and messages.
- Created `file-preview-store` to handle file preview state.
- Added `sidebar-store` for sidebar visibility management.
- Developed `theme-store` for theme persistence and management.
- Introduced `kb-selection-store` for managing active knowledge base selections with persistence.

chore: define API and chat types

- Added types for API responses, authentication, chat messages, conversations, and projects.
- Defined interfaces for various entities including users, sessions, and message ratings.

build: configure TypeScript and testing setup

- Set up `tsconfig.json` for TypeScript configuration.
- Created `vitest.config.ts` for testing configuration with Vitest.
- Added `vitest.setup.ts` for global test setup including mocks for Next.js router and media queries.
- Configured Vercel deployment settings in `vercel.json`.
2026-06-11 16:54:43 +08:00

79 lines
2.9 KiB
Python

"""Admin conversation and user browsing routes.
All endpoints require admin role.
Endpoints:
GET /admin/conversations — List all conversations (paginated, filterable)
GET /admin/conversations/{id} — Get any conversation with messages (read-only)
GET /admin/users — List all users with conversation counts
GET /admin/users/{user_id}/conversations — List conversations for a specific user
"""
from typing import Any, Literal
from uuid import UUID
from fastapi import APIRouter, Query
from app.api.deps import ConversationSvc, CurrentAdmin, UserSvc
from app.schemas.conversation import ConversationReadWithMessages
from app.schemas.conversation_share import AdminConversationList, AdminUserList
router = APIRouter()
@router.get("", response_model=AdminConversationList)
async def admin_list_conversations(
service: ConversationSvc,
_: CurrentAdmin,
skip: int = Query(0, ge=0, description="Items to skip"),
limit: int = Query(50, ge=1, le=100, description="Max items to return"),
search: str | None = Query(default=None, description="Search by title"),
user_id: UUID | None = Query(default=None, description="Filter by user ID"),
status: Literal["active", "archived", "all"] = Query(
"active", description="Filter by archival status"
),
sort_by: Literal["title", "owner", "messages", "created_at", "updated_at"] = Query(
"updated_at", description="Sort column"
),
sort_dir: Literal["asc", "desc"] = Query("desc", description="Sort direction"),
) -> Any:
"""List all conversations across all users (admin only)."""
return await service.admin_list_with_users(
skip=skip,
limit=limit,
search=search,
user_id=user_id,
include_archived=status == "all",
archived_only=status == "archived",
sort_by=sort_by,
sort_dir=sort_dir,
)
@router.get("/users", response_model=AdminUserList)
async def admin_list_users(
user_service: UserSvc,
_: CurrentAdmin,
skip: int = Query(0, ge=0),
limit: int = Query(50, ge=1, le=500),
search: str | None = Query(default=None, description="Search by email or name"),
sort_by: Literal["email", "full_name", "conversations", "created_at"] = Query(
"created_at", description="Sort column"
),
sort_dir: Literal["asc", "desc"] = Query("desc", description="Sort direction"),
) -> Any:
"""List all users with conversation counts (admin only)."""
return await user_service.admin_list_with_counts(
skip=skip, limit=limit, search=search, sort_by=sort_by, sort_dir=sort_dir
)
@router.get("/{conversation_id}", response_model=ConversationReadWithMessages)
async def admin_get_conversation(
conversation_id: UUID,
service: ConversationSvc,
_: CurrentAdmin,
) -> Any:
"""Get any conversation with messages (admin read-only access)."""
return await service.get_conversation_with_messages(conversation_id)