diff --git a/server/reflector/db/search.py b/server/reflector/db/search.py index 66a25ccf..caa21c65 100644 --- a/server/reflector/db/search.py +++ b/server/reflector/db/search.py @@ -23,7 +23,7 @@ from pydantic import ( from reflector.db import get_database from reflector.db.rooms import rooms -from reflector.db.transcripts import SourceKind, transcripts +from reflector.db.transcripts import SourceKind, TranscriptStatus, transcripts from reflector.db.utils import is_postgresql from reflector.logger import logger from reflector.utils.string import NonEmptyString, try_parse_non_empty_string @@ -161,7 +161,7 @@ class SearchResult(BaseModel): room_name: str | None = None source_kind: SourceKind created_at: datetime - status: str = Field(..., min_length=1) + status: TranscriptStatus = Field(..., min_length=1) rank: float = Field(..., ge=0, le=1) duration: NonNegativeFloat | None = Field(..., description="Duration in seconds") search_snippets: list[str] = Field( diff --git a/server/reflector/views/rooms.py b/server/reflector/views/rooms.py index cc00f3c0..38b611d6 100644 --- a/server/reflector/views/rooms.py +++ b/server/reflector/views/rooms.py @@ -215,14 +215,10 @@ async def rooms_create_meeting( except (asyncpg.exceptions.UniqueViolationError, sqlite3.IntegrityError): # Another request already created a meeting for this room # Log this race condition occurrence - logger.info( - "Race condition detected for room %s - fetching existing meeting", - room.name, - ) logger.warning( - "Whereby meeting %s was created but not used (resource leak) for room %s", - whereby_meeting["meetingId"], + "Race condition detected for room %s and meeting %s - fetching existing meeting", room.name, + whereby_meeting["meetingId"], ) # Fetch the meeting that was created by the other request @@ -232,7 +228,9 @@ async def rooms_create_meeting( if meeting is None: # Edge case: meeting was created but expired/deleted between checks logger.error( - "Meeting disappeared after race condition for room %s", room.name + "Meeting disappeared after race condition for room %s", + room.name, + exc_info=True, ) raise HTTPException( status_code=503, detail="Unable to join meeting - please try again" diff --git a/server/reflector/views/transcripts.py b/server/reflector/views/transcripts.py index 9acfcbf8..ed2445ae 100644 --- a/server/reflector/views/transcripts.py +++ b/server/reflector/views/transcripts.py @@ -350,8 +350,6 @@ async def transcript_update( transcript = await transcripts_controller.get_by_id_for_http( transcript_id, user_id=user_id ) - if not transcript: - raise HTTPException(status_code=404, detail="Transcript not found") values = info.dict(exclude_unset=True) updated_transcript = await transcripts_controller.update(transcript, values) return updated_transcript diff --git a/server/tests/test_search.py b/server/tests/test_search.py index 0f5c8923..82890080 100644 --- a/server/tests/test_search.py +++ b/server/tests/test_search.py @@ -58,7 +58,7 @@ async def test_empty_transcript_title_only_match(): "id": test_id, "name": "Empty Transcript", "title": "Empty Meeting", - "status": "completed", + "status": "ended", "locked": False, "duration": 0.0, "created_at": datetime.now(timezone.utc), @@ -109,7 +109,7 @@ async def test_search_with_long_summary(): "id": test_id, "name": "Test Long Summary", "title": "Regular Meeting", - "status": "completed", + "status": "ended", "locked": False, "duration": 1800.0, "created_at": datetime.now(timezone.utc), @@ -165,7 +165,7 @@ async def test_postgresql_search_with_data(): "id": test_id, "name": "Test Search Transcript", "title": "Engineering Planning Meeting Q4 2024", - "status": "completed", + "status": "ended", "locked": False, "duration": 1800.0, "created_at": datetime.now(timezone.utc), @@ -221,7 +221,7 @@ We need to implement PostgreSQL tsvector for better performance.""", test_result = next((r for r in results if r.id == test_id), None) if test_result: assert test_result.title == "Engineering Planning Meeting Q4 2024" - assert test_result.status == "completed" + assert test_result.status == "ended" assert test_result.duration == 1800.0 assert 0 <= test_result.rank <= 1, "Rank should be normalized to 0-1" @@ -268,7 +268,7 @@ def mock_db_result(): "title": "Test Transcript", "created_at": datetime(2024, 6, 15, tzinfo=timezone.utc), "duration": 3600.0, - "status": "completed", + "status": "ended", "user_id": "test-user", "room_id": "room1", "source_kind": SourceKind.LIVE, @@ -433,7 +433,7 @@ class TestSearchResultModel: room_id="room-456", source_kind=SourceKind.ROOM, created_at=datetime(2024, 6, 15, tzinfo=timezone.utc), - status="completed", + status="ended", rank=0.85, duration=1800.5, search_snippets=["snippet 1", "snippet 2"], @@ -443,7 +443,7 @@ class TestSearchResultModel: assert result.title == "Test Title" assert result.user_id == "user-123" assert result.room_id == "room-456" - assert result.status == "completed" + assert result.status == "ended" assert result.rank == 0.85 assert result.duration == 1800.5 assert len(result.search_snippets) == 2 @@ -474,7 +474,7 @@ class TestSearchResultModel: id="test-id", source_kind=SourceKind.LIVE, created_at=datetime(2024, 6, 15, 12, 30, 45, tzinfo=timezone.utc), - status="completed", + status="ended", rank=0.9, duration=None, search_snippets=[], diff --git a/server/tests/test_search_long_summary.py b/server/tests/test_search_long_summary.py index 8857778b..3f911a99 100644 --- a/server/tests/test_search_long_summary.py +++ b/server/tests/test_search_long_summary.py @@ -25,7 +25,7 @@ async def test_long_summary_snippet_prioritization(): "id": test_id, "name": "Test Snippet Priority", "title": "Meeting About Projects", - "status": "completed", + "status": "ended", "locked": False, "duration": 1800.0, "created_at": datetime.now(timezone.utc), @@ -106,7 +106,7 @@ async def test_long_summary_only_search(): "id": test_id, "name": "Test Long Only", "title": "Standard Meeting", - "status": "completed", + "status": "ended", "locked": False, "duration": 1800.0, "created_at": datetime.now(timezone.utc), diff --git a/www/app/(app)/browse/_components/TranscriptStatusIcon.tsx b/www/app/(app)/browse/_components/TranscriptStatusIcon.tsx index 0eebadc8..20164993 100644 --- a/www/app/(app)/browse/_components/TranscriptStatusIcon.tsx +++ b/www/app/(app)/browse/_components/TranscriptStatusIcon.tsx @@ -7,9 +7,10 @@ import { FaMicrophone, FaGear, } from "react-icons/fa6"; +import { TranscriptStatus } from "../../../lib/transcript"; interface TranscriptStatusIconProps { - status: string; + status: TranscriptStatus; } export default function TranscriptStatusIcon({ diff --git a/www/app/(app)/transcripts/[transcriptId]/_components/TopicList.tsx b/www/app/(app)/transcripts/[transcriptId]/_components/TopicList.tsx index 1f5d1588..534f0c0a 100644 --- a/www/app/(app)/transcripts/[transcriptId]/_components/TopicList.tsx +++ b/www/app/(app)/transcripts/[transcriptId]/_components/TopicList.tsx @@ -5,6 +5,7 @@ import useParticipants from "../../useParticipants"; import { Box, Flex, Text, Accordion } from "@chakra-ui/react"; import { featureEnabled } from "../../../../domainContext"; import { TopicItem } from "./TopicItem"; +import { TranscriptStatus } from "../../../../lib/transcript"; type TopicListProps = { topics: Topic[]; @@ -14,7 +15,7 @@ type TopicListProps = { ]; autoscroll: boolean; transcriptId: string; - status: string; + status: TranscriptStatus | null; currentTranscriptText: any; }; diff --git a/www/app/(app)/transcripts/[transcriptId]/correct/page.tsx b/www/app/(app)/transcripts/[transcriptId]/correct/page.tsx index c885ca6e..1c7705f4 100644 --- a/www/app/(app)/transcripts/[transcriptId]/correct/page.tsx +++ b/www/app/(app)/transcripts/[transcriptId]/correct/page.tsx @@ -9,8 +9,10 @@ import ParticipantList from "./participantList"; import type { components } from "../../../../reflector-api"; type GetTranscriptTopic = components["schemas"]["GetTranscriptTopic"]; import { SelectedText, selectedTextIsTimeSlice } from "./types"; -import { useTranscriptUpdate } from "../../../../lib/apiHooks"; -import useTranscript from "../../useTranscript"; +import { + useTranscriptGet, + useTranscriptUpdate, +} from "../../../../lib/apiHooks"; import { useError } from "../../../../(errors)/errorContext"; import { useRouter } from "next/navigation"; import { Box, Grid } from "@chakra-ui/react"; @@ -25,7 +27,7 @@ export default function TranscriptCorrect({ params: { transcriptId }, }: TranscriptCorrect) { const updateTranscriptMutation = useTranscriptUpdate(); - const transcript = useTranscript(transcriptId); + const transcript = useTranscriptGet(transcriptId); const stateCurrentTopic = useState(); const [currentTopic, _sct] = stateCurrentTopic; const stateSelectedText = useState(); @@ -36,7 +38,7 @@ export default function TranscriptCorrect({ const router = useRouter(); const markAsDone = async () => { - if (transcript.response && !transcript.response.reviewed) { + if (transcript.data && !transcript.data.reviewed) { try { await updateTranscriptMutation.mutateAsync({ params: { @@ -114,7 +116,7 @@ export default function TranscriptCorrect({ }} /> - {transcript.response && !transcript.response?.reviewed && ( + {transcript.data && !transcript.data?.reviewed && (