2026-04-08 11:19:33 +00:00
|
|
|
from typing import Optional
|
2026-04-03 16:25:53 +00:00
|
|
|
|
2026-04-08 11:19:33 +00:00
|
|
|
from fastapi import APIRouter, BackgroundTasks, Depends, File, Form, Header, UploadFile
|
2026-04-03 16:25:53 +00:00
|
|
|
|
2026-04-08 11:19:33 +00:00
|
|
|
from app.core.auth import get_current_user, get_optional_current_user
|
|
|
|
|
from app.models.models import (
|
|
|
|
|
BatchSpeakerTagUpdateRequest,
|
|
|
|
|
BatchTranscriptUpdateRequest,
|
|
|
|
|
CreateMeetingRequest,
|
|
|
|
|
SpeakerTagUpdateRequest,
|
|
|
|
|
UpdateMeetingRequest,
|
|
|
|
|
)
|
|
|
|
|
import app.services.meeting_service as meeting_service
|
2026-04-03 16:25:53 +00:00
|
|
|
|
|
|
|
|
|
2026-04-08 11:19:33 +00:00
|
|
|
router = APIRouter()
|
2026-04-03 16:25:53 +00:00
|
|
|
|
2026-04-08 11:19:33 +00:00
|
|
|
GenerateSummaryRequest = meeting_service.GenerateSummaryRequest
|
|
|
|
|
AccessPasswordRequest = meeting_service.AccessPasswordRequest
|
|
|
|
|
VerifyPasswordRequest = meeting_service.VerifyPasswordRequest
|
2026-04-03 16:25:53 +00:00
|
|
|
|
|
|
|
|
|
2026-01-19 11:03:08 +00:00
|
|
|
@router.get("/meetings")
|
|
|
|
|
def get_meetings(
|
|
|
|
|
current_user: dict = Depends(get_current_user),
|
|
|
|
|
user_id: Optional[int] = None,
|
|
|
|
|
page: int = 1,
|
|
|
|
|
page_size: Optional[int] = None,
|
|
|
|
|
search: Optional[str] = None,
|
|
|
|
|
tags: Optional[str] = None,
|
|
|
|
|
filter_type: str = "all"
|
|
|
|
|
):
|
2026-04-08 11:19:33 +00:00
|
|
|
return meeting_service.get_meetings(current_user, user_id, page, page_size, search, tags, filter_type)
|
2026-04-03 16:25:53 +00:00
|
|
|
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
@router.get("/meetings/stats")
|
|
|
|
|
def get_meetings_stats(
|
|
|
|
|
current_user: dict = Depends(get_current_user),
|
|
|
|
|
user_id: Optional[int] = None
|
|
|
|
|
):
|
2026-04-08 11:19:33 +00:00
|
|
|
return meeting_service.get_meetings_stats(current_user, user_id)
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.get("/meetings/{meeting_id}")
|
|
|
|
|
def get_meeting_details(meeting_id: int, current_user: dict = Depends(get_current_user)):
|
2026-04-08 11:19:33 +00:00
|
|
|
return meeting_service.get_meeting_details(meeting_id, current_user)
|
2026-04-03 16:25:53 +00:00
|
|
|
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
@router.get("/meetings/{meeting_id}/transcript")
|
|
|
|
|
def get_meeting_transcript(meeting_id: int, current_user: Optional[dict] = Depends(get_optional_current_user)):
|
2026-04-08 11:19:33 +00:00
|
|
|
return meeting_service.get_meeting_transcript(meeting_id, current_user)
|
|
|
|
|
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
@router.post("/meetings")
|
|
|
|
|
def create_meeting(meeting_request: CreateMeetingRequest, current_user: dict = Depends(get_current_user)):
|
2026-04-08 11:19:33 +00:00
|
|
|
return meeting_service.create_meeting(meeting_request, current_user)
|
|
|
|
|
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
@router.put("/meetings/{meeting_id}")
|
|
|
|
|
def update_meeting(meeting_id: int, meeting_request: UpdateMeetingRequest, current_user: dict = Depends(get_current_user)):
|
2026-04-08 11:19:33 +00:00
|
|
|
return meeting_service.update_meeting(meeting_id, meeting_request, current_user)
|
|
|
|
|
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
@router.delete("/meetings/{meeting_id}")
|
|
|
|
|
def delete_meeting(meeting_id: int, current_user: dict = Depends(get_current_user)):
|
2026-04-08 11:19:33 +00:00
|
|
|
return meeting_service.delete_meeting(meeting_id, current_user)
|
|
|
|
|
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
@router.get("/meetings/{meeting_id}/edit")
|
|
|
|
|
def get_meeting_for_edit(meeting_id: int, current_user: dict = Depends(get_current_user)):
|
2026-04-08 11:19:33 +00:00
|
|
|
return meeting_service.get_meeting_for_edit(meeting_id, current_user)
|
|
|
|
|
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
@router.post("/meetings/upload-audio")
|
|
|
|
|
async def upload_audio(
|
|
|
|
|
audio_file: UploadFile = File(...),
|
|
|
|
|
meeting_id: int = Form(...),
|
|
|
|
|
auto_summarize: str = Form("true"),
|
2026-04-08 11:19:33 +00:00
|
|
|
prompt_id: Optional[int] = Form(None),
|
|
|
|
|
model_code: Optional[str] = Form(None),
|
2026-01-19 11:03:08 +00:00
|
|
|
background_tasks: BackgroundTasks = None,
|
|
|
|
|
current_user: dict = Depends(get_current_user)
|
|
|
|
|
):
|
2026-04-08 11:19:33 +00:00
|
|
|
return await meeting_service.upload_audio(
|
|
|
|
|
audio_file,
|
|
|
|
|
meeting_id,
|
|
|
|
|
auto_summarize,
|
|
|
|
|
prompt_id,
|
|
|
|
|
model_code,
|
|
|
|
|
background_tasks,
|
|
|
|
|
current_user,
|
2026-01-19 11:03:08 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.get("/meetings/{meeting_id}/audio")
|
|
|
|
|
def get_audio_file(meeting_id: int, current_user: Optional[dict] = Depends(get_optional_current_user)):
|
2026-04-08 11:19:33 +00:00
|
|
|
return meeting_service.get_audio_file(meeting_id, current_user)
|
|
|
|
|
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
@router.get("/meetings/{meeting_id}/audio/stream")
|
|
|
|
|
async def stream_audio_file(
|
|
|
|
|
meeting_id: int,
|
|
|
|
|
range: Optional[str] = Header(None, alias="Range")
|
|
|
|
|
):
|
2026-04-08 11:19:33 +00:00
|
|
|
return await meeting_service.stream_audio_file(meeting_id, range)
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.get("/meetings/{meeting_id}/transcription/status")
|
|
|
|
|
def get_meeting_transcription_status(meeting_id: int, current_user: dict = Depends(get_current_user)):
|
2026-04-08 11:19:33 +00:00
|
|
|
return meeting_service.get_meeting_transcription_status(meeting_id, current_user)
|
|
|
|
|
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
@router.post("/meetings/{meeting_id}/transcription/start")
|
2026-04-02 11:07:41 +00:00
|
|
|
def start_meeting_transcription(
|
|
|
|
|
meeting_id: int,
|
|
|
|
|
background_tasks: BackgroundTasks,
|
|
|
|
|
current_user: dict = Depends(get_current_user)
|
|
|
|
|
):
|
2026-04-08 11:19:33 +00:00
|
|
|
return meeting_service.start_meeting_transcription(meeting_id, background_tasks, current_user)
|
|
|
|
|
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
@router.post("/meetings/{meeting_id}/upload-image")
|
|
|
|
|
async def upload_image(meeting_id: int, image_file: UploadFile = File(...), current_user: dict = Depends(get_current_user)):
|
2026-04-08 11:19:33 +00:00
|
|
|
return await meeting_service.upload_image(meeting_id, image_file, current_user)
|
|
|
|
|
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
@router.put("/meetings/{meeting_id}/speaker-tags")
|
|
|
|
|
def update_speaker_tag(meeting_id: int, request: SpeakerTagUpdateRequest, current_user: dict = Depends(get_current_user)):
|
2026-04-08 11:19:33 +00:00
|
|
|
return meeting_service.update_speaker_tag(meeting_id, request, current_user)
|
|
|
|
|
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
@router.put("/meetings/{meeting_id}/speaker-tags/batch")
|
2026-04-08 11:19:33 +00:00
|
|
|
def batch_update_speaker_tags(
|
|
|
|
|
meeting_id: int,
|
|
|
|
|
request: BatchSpeakerTagUpdateRequest,
|
|
|
|
|
current_user: dict = Depends(get_current_user)
|
|
|
|
|
):
|
|
|
|
|
return meeting_service.batch_update_speaker_tags(meeting_id, request, current_user)
|
|
|
|
|
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
@router.put("/meetings/{meeting_id}/transcript/batch")
|
2026-04-08 11:19:33 +00:00
|
|
|
def batch_update_transcript(
|
|
|
|
|
meeting_id: int,
|
|
|
|
|
request: BatchTranscriptUpdateRequest,
|
|
|
|
|
current_user: dict = Depends(get_current_user)
|
|
|
|
|
):
|
|
|
|
|
return meeting_service.batch_update_transcript(meeting_id, request, current_user)
|
|
|
|
|
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
@router.get("/meetings/{meeting_id}/summaries")
|
|
|
|
|
def get_meeting_summaries(meeting_id: int, current_user: dict = Depends(get_current_user)):
|
2026-04-08 11:19:33 +00:00
|
|
|
return meeting_service.get_meeting_summaries(meeting_id, current_user)
|
|
|
|
|
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
@router.get("/meetings/{meeting_id}/summaries/{summary_id}")
|
|
|
|
|
def get_summary_detail(meeting_id: int, summary_id: int, current_user: dict = Depends(get_current_user)):
|
2026-04-08 11:19:33 +00:00
|
|
|
return meeting_service.get_summary_detail(meeting_id, summary_id, current_user)
|
|
|
|
|
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
@router.post("/meetings/{meeting_id}/generate-summary-async")
|
2026-04-08 11:19:33 +00:00
|
|
|
def generate_meeting_summary_async(
|
|
|
|
|
meeting_id: int,
|
|
|
|
|
request: GenerateSummaryRequest,
|
|
|
|
|
background_tasks: BackgroundTasks,
|
|
|
|
|
current_user: dict = Depends(get_current_user)
|
|
|
|
|
):
|
|
|
|
|
return meeting_service.generate_meeting_summary_async(meeting_id, request, background_tasks, current_user)
|
|
|
|
|
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
@router.get("/meetings/{meeting_id}/llm-tasks")
|
|
|
|
|
def get_meeting_llm_tasks(meeting_id: int, current_user: dict = Depends(get_current_user)):
|
2026-04-08 11:19:33 +00:00
|
|
|
return meeting_service.get_meeting_llm_tasks(meeting_id, current_user)
|
|
|
|
|
|
2026-01-19 11:03:08 +00:00
|
|
|
|
2026-03-26 06:55:12 +00:00
|
|
|
@router.get("/llm-models/active")
|
|
|
|
|
def list_active_llm_models(current_user: dict = Depends(get_current_user)):
|
2026-04-08 11:19:33 +00:00
|
|
|
return meeting_service.list_active_llm_models(current_user)
|
|
|
|
|
|
|
|
|
|
|
2026-01-19 11:03:08 +00:00
|
|
|
@router.get("/meetings/{meeting_id}/navigation")
|
|
|
|
|
def get_meeting_navigation(
|
|
|
|
|
meeting_id: int,
|
|
|
|
|
current_user: dict = Depends(get_current_user),
|
|
|
|
|
user_id: Optional[int] = None,
|
|
|
|
|
filter_type: str = "all",
|
|
|
|
|
search: Optional[str] = None,
|
|
|
|
|
tags: Optional[str] = None
|
|
|
|
|
):
|
2026-04-08 11:19:33 +00:00
|
|
|
return meeting_service.get_meeting_navigation(
|
|
|
|
|
meeting_id,
|
|
|
|
|
current_user,
|
|
|
|
|
user_id,
|
|
|
|
|
filter_type,
|
|
|
|
|
search,
|
|
|
|
|
tags,
|
|
|
|
|
)
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.get("/meetings/{meeting_id}/preview-data")
|
2026-03-27 07:43:08 +00:00
|
|
|
def get_meeting_preview_data(meeting_id: int, password: Optional[str] = None):
|
2026-04-08 11:19:33 +00:00
|
|
|
return meeting_service.get_meeting_preview_data(meeting_id, password)
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.put("/meetings/{meeting_id}/access-password")
|
|
|
|
|
def update_meeting_access_password(
|
|
|
|
|
meeting_id: int,
|
|
|
|
|
request: AccessPasswordRequest,
|
|
|
|
|
current_user: dict = Depends(get_current_user)
|
|
|
|
|
):
|
2026-04-08 11:19:33 +00:00
|
|
|
return meeting_service.update_meeting_access_password(meeting_id, request, current_user)
|
2026-01-19 11:03:08 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.post("/meetings/{meeting_id}/verify-password")
|
|
|
|
|
def verify_meeting_password(meeting_id: int, request: VerifyPasswordRequest):
|
2026-04-08 11:19:33 +00:00
|
|
|
return meeting_service.verify_meeting_password(meeting_id, request)
|