|
|
from typing import List |
|
|
from uuid import UUID |
|
|
|
|
|
from fastapi import APIRouter |
|
|
|
|
|
from app.api.messages.schemas import Message |
|
|
from app.api.messages.services import MessageService |
|
|
from app.api.participants.schemas import Participant |
|
|
from app.api.participants.services import ParticipantService |
|
|
from app.api.topics.schemas import ( |
|
|
AddMessageRequest, |
|
|
Topic, |
|
|
TopicCreate, |
|
|
TopicMessageResponse, |
|
|
TopicResponse, |
|
|
) |
|
|
from app.api.topics.services import TopicService |
|
|
from app.core.config import ( |
|
|
HTTP_STATUS_CREATED, |
|
|
MESSAGES_FILE, |
|
|
PARTICIPANTS_FILE, |
|
|
TOPICS_FILE, |
|
|
UNKNOWN_PARTICIPANT_NAME, |
|
|
) |
|
|
from app.core.file_manager import FileManager |
|
|
from app.core.link import Link, TopicLink |
|
|
|
|
|
|
|
|
router = APIRouter() |
|
|
message_service = MessageService(FileManager(MESSAGES_FILE), FileManager(TOPICS_FILE), FileManager(PARTICIPANTS_FILE)) |
|
|
topic_service = TopicService(FileManager(TOPICS_FILE), message_service=message_service) |
|
|
participant_service = ParticipantService(FileManager(PARTICIPANTS_FILE)) |
|
|
|
|
|
|
|
|
def _resolve_participant_name(participant_id: Link, participants: List[Participant]) -> str: |
|
|
for participant in participants: |
|
|
if participant.id == participant_id.value: |
|
|
return f"{participant.first_name} {participant.last_name}".strip() |
|
|
return UNKNOWN_PARTICIPANT_NAME |
|
|
|
|
|
|
|
|
def _topic_to_response(topic: Topic, participants: List[Participant], messages: List[Message]) -> TopicResponse: |
|
|
message_responses = [] |
|
|
for message in sorted(messages, key=lambda item: item.order_in_topic): |
|
|
message_responses.append( |
|
|
TopicMessageResponse( |
|
|
participant_id=message.participant_id, |
|
|
content=message.content, |
|
|
participant_name=_resolve_participant_name(message.participant_id, participants), |
|
|
order_in_topic=message.order_in_topic, |
|
|
) |
|
|
) |
|
|
return TopicResponse( |
|
|
id=topic.id, |
|
|
title=topic.title, |
|
|
description=topic.description, |
|
|
created_at=topic.created_at, |
|
|
participants=topic.participants, |
|
|
messages=message_responses, |
|
|
) |
|
|
|
|
|
|
|
|
@router.get("/", response_model=List[TopicResponse]) |
|
|
async def list_topics() -> List[TopicResponse]: |
|
|
topics = topic_service.list_topics() |
|
|
participants = participant_service.list_participants() |
|
|
messages = message_service.list_messages() |
|
|
messages_by_topic: dict[UUID, List[Message]] = {} |
|
|
for message in messages: |
|
|
messages_by_topic.setdefault(message.topic_id.value, []).append(message) |
|
|
return [ |
|
|
_topic_to_response(topic, participants, messages_by_topic.get(topic.id, [])) |
|
|
for topic in topics |
|
|
] |
|
|
|
|
|
|
|
|
@router.get("/{topic_id}", response_model=TopicResponse) |
|
|
async def get_topic(topic_id: UUID) -> TopicResponse: |
|
|
topic_link = TopicLink(value=topic_id) |
|
|
topic = topic_service.get_topic(topic_link) |
|
|
participants = participant_service.list_participants() |
|
|
topic_messages = message_service.list_messages_by_topic(topic_link) |
|
|
return _topic_to_response(topic, participants, topic_messages) |
|
|
|
|
|
|
|
|
@router.post("/", response_model=TopicResponse, status_code=HTTP_STATUS_CREATED) |
|
|
async def create_topic(payload: TopicCreate) -> TopicResponse: |
|
|
topic = topic_service.create_topic(payload) |
|
|
participants = participant_service.list_participants() |
|
|
topic_messages = message_service.list_messages_by_topic(TopicLink(value=topic.id)) |
|
|
return _topic_to_response(topic, participants, topic_messages) |
|
|
|
|
|
|
|
|
@router.post("/{topic_id}/messages", response_model=TopicResponse, status_code=HTTP_STATUS_CREATED) |
|
|
async def add_message(topic_id: UUID, payload: AddMessageRequest) -> TopicResponse: |
|
|
topic_link = TopicLink(value=topic_id) |
|
|
topic = topic_service.add_message(topic_link, payload) |
|
|
participants = participant_service.list_participants() |
|
|
topic_messages = message_service.list_messages_by_topic(topic_link) |
|
|
return _topic_to_response(topic, participants, topic_messages) |
|
|
|
|
|
|
|
|
@router.get("/{topic_id}/download") |
|
|
async def download_topic(topic_id: UUID) -> dict: |
|
|
topic_link = TopicLink(value=topic_id) |
|
|
topic = topic_service.get_topic(topic_link) |
|
|
participants = participant_service.list_participants() |
|
|
topic_messages = message_service.list_messages_by_topic(topic_link) |
|
|
response = _topic_to_response(topic, participants, topic_messages) |
|
|
return { |
|
|
"id": str(response.id), |
|
|
"title": response.title, |
|
|
"description": response.description, |
|
|
"created_at": response.created_at.isoformat(), |
|
|
"participants": [{"table": p.table, "value": str(p.value)} for p in response.participants], |
|
|
"messages": [ |
|
|
{ |
|
|
"participant_id": {"table": m.participant_id.table, "value": str(m.participant_id.value)}, |
|
|
"content": m.content, |
|
|
"participant_name": m.participant_name, |
|
|
"order_in_topic": m.order_in_topic, |
|
|
} |
|
|
for m in response.messages |
|
|
], |
|
|
} |
|
|
|