ishaq101's picture
[KM-467] [DED][AI] Orchestration Agent - Init
027123c
raw
history blame
4.45 kB
"""Room management API endpoints."""
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from sqlalchemy.orm import selectinload
from src.db.postgres.connection import get_db
from src.db.postgres.models import Room, ChatMessage, MessageSource
from src.middlewares.logging import get_logger, log_execution
from pydantic import BaseModel
from typing import List, Optional
from datetime import datetime
import uuid
logger = get_logger("room_api")
router = APIRouter(prefix="/api/v1", tags=["Rooms"])
class MessageSourceResponse(BaseModel):
document_id: Optional[str]
filename: Optional[str]
page_label: Optional[str]
class ChatMessageResponse(BaseModel):
id: str
role: str
content: str
created_at: str
sources: List[MessageSourceResponse] = []
class RoomResponse(BaseModel):
id: str
title: str
created_at: str
updated_at: str | None
messages: List[ChatMessageResponse] = []
class CreateRoomRequest(BaseModel):
user_id: str
title: str = "New Chat"
@router.get("/rooms/{user_id}", response_model=List[RoomResponse])
@log_execution(logger)
async def list_rooms(
user_id: str,
db: AsyncSession = Depends(get_db)
):
"""List all rooms for a user."""
result = await db.execute(
select(Room)
.where(Room.user_id == user_id, Room.status == "active")
.order_by(Room.updated_at.desc())
)
rooms = result.scalars().all()
return [
RoomResponse(
id=room.id,
title=room.title,
created_at=room.created_at.isoformat(),
updated_at=room.updated_at.isoformat() if room.updated_at else None
)
for room in rooms
]
@router.get("/room/{room_id}", response_model=RoomResponse)
@log_execution(logger)
async def get_room(
room_id: str,
db: AsyncSession = Depends(get_db)
):
"""Get a specific room with its chat history."""
result = await db.execute(
select(Room)
.where(Room.id == room_id)
.options(selectinload(Room.messages).selectinload(ChatMessage.sources))
)
room = result.scalars().first()
if not room:
raise HTTPException(
status_code=404,
detail="Room not found"
)
messages = sorted(room.messages, key=lambda m: m.created_at)
return RoomResponse(
id=room.id,
title=room.title,
created_at=room.created_at.isoformat(),
updated_at=room.updated_at.isoformat() if room.updated_at else None,
messages=[
ChatMessageResponse(
id=msg.id,
role=msg.role,
content=msg.content,
created_at=msg.created_at.isoformat(),
sources=[
MessageSourceResponse(
document_id=src.document_id,
filename=src.filename,
page_label=src.page_label,
)
for src in msg.sources
],
)
for msg in messages
]
)
@router.delete("/room/{room_id}")
@log_execution(logger)
async def delete_room(
room_id: str,
user_id: str,
db: AsyncSession = Depends(get_db)
):
"""Soft-delete a room by setting its status to inactive."""
result = await db.execute(
select(Room).where(Room.id == room_id)
)
room = result.scalars().first()
if not room:
raise HTTPException(status_code=404, detail="Room not found")
if room.user_id != user_id:
raise HTTPException(status_code=403, detail="Access denied")
room.status = "inactive"
await db.commit()
return {"status": "success", "message": "Room deleted successfully"}
@router.post("/room/create")
@log_execution(logger)
async def create_room(
request: CreateRoomRequest,
db: AsyncSession = Depends(get_db)
):
"""Create a new room."""
room = Room(
id=str(uuid.uuid4()),
user_id=request.user_id,
title=request.title
)
db.add(room)
await db.commit()
await db.refresh(room)
return {
"status": "success",
"message": "Room created successfully",
"data": RoomResponse(
id=room.id,
title=room.title,
created_at=room.created_at.isoformat(),
updated_at=None
)
}