import uuid from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from api.database import get_session from api.models.topic import Topic, TopicStatus from api.schemas.topic import TopicCreate, TopicRead, TopicUpdate, TopicWithWorkstreams router = APIRouter(prefix="/topics", tags=["topics"]) @router.get("/", response_model=list[TopicRead]) async def list_topics( status: TopicStatus | None = None, session: AsyncSession = Depends(get_session), ) -> list[Topic]: q = select(Topic) if status: q = q.where(Topic.status == status) q = q.order_by(Topic.created_at) result = await session.execute(q) return list(result.scalars().all()) @router.post("/", response_model=TopicRead, status_code=status.HTTP_201_CREATED) async def create_topic( body: TopicCreate, session: AsyncSession = Depends(get_session), ) -> Topic: topic = Topic(**body.model_dump()) session.add(topic) await session.commit() await session.refresh(topic) return topic @router.get("/{topic_id}", response_model=TopicWithWorkstreams) async def get_topic( topic_id: uuid.UUID, session: AsyncSession = Depends(get_session), ) -> Topic: topic = await session.get(Topic, topic_id) if topic is None: raise HTTPException(status_code=404, detail="Topic not found") return topic @router.patch("/{topic_id}", response_model=TopicRead) async def update_topic( topic_id: uuid.UUID, body: TopicUpdate, session: AsyncSession = Depends(get_session), ) -> Topic: topic = await session.get(Topic, topic_id) if topic is None: raise HTTPException(status_code=404, detail="Topic not found") for field, value in body.model_dump(exclude_unset=True).items(): setattr(topic, field, value) await session.commit() await session.refresh(topic) return topic @router.delete("/{topic_id}", response_model=TopicRead) async def archive_topic( topic_id: uuid.UUID, session: AsyncSession = Depends(get_session), ) -> Topic: topic = await session.get(Topic, topic_id) if topic is None: raise HTTPException(status_code=404, detail="Topic not found") topic.status = TopicStatus.archived await session.commit() await session.refresh(topic) return topic