File size: 3,908 Bytes
bef5e76
 
 
 
 
08df5ae
bef5e76
08df5ae
bef5e76
 
 
 
 
 
 
 
 
 
 
08df5ae
 
 
 
 
 
 
bef5e76
 
 
 
 
08df5ae
bef5e76
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
08df5ae
bef5e76
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
08df5ae
bef5e76
08df5ae
 
 
bef5e76
 
 
 
 
 
 
 
 
08df5ae
 
bef5e76
 
 
 
08df5ae
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bef5e76
08df5ae
 
 
 
 
 
 
 
 
 
 
 
bef5e76
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
"""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
from src.middlewares.logging import get_logger, log_execution
from pydantic import BaseModel
from typing import List
from datetime import datetime
import uuid

logger = get_logger("room_api")

router = APIRouter(prefix="/api/v1", tags=["Rooms"])


class ChatMessageResponse(BaseModel):
    id: str
    role: str
    content: str
    created_at: str


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))
    )
    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()
            )
            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
        )
    }