diff --git a/apps/api/src/modules/ai/drafts.controller.ts b/apps/api/src/modules/ai/drafts.controller.ts index 6960f08..f742185 100644 --- a/apps/api/src/modules/ai/drafts.controller.ts +++ b/apps/api/src/modules/ai/drafts.controller.ts @@ -21,6 +21,7 @@ type CreateDraftRequest = Request, unknown, CreateAiDraft type UpdateDraftRequest = Request; type ApproveDraftRequest = Request; type DraftByIdRequest = Request; +type DraftListRequest = Request, unknown, unknown, { encounterId?: string }>; const toDraftPayload = (doc: { _id: unknown; @@ -69,6 +70,34 @@ router.post( }, ); +router.get( + "/drafts", + authorize(ALL_ROLES), + async (req: DraftListRequest, res: Response) => { + const clinicId = req.user?.clinicId; + if (!clinicId) { + return res.status(401).json({ + error: "Unauthorized", + message: "Authentication required", + }); + } + + const drafts = await AiDraftModel.find({ + clinicId, + ...(req.query.encounterId ? { encounterId: req.query.encounterId } : {}), + status: "DRAFT", + }) + .sort({ updatedAt: -1 }) + .limit(20) + .lean(); + + return res.json({ + status: "success", + data: drafts.map((draft) => toDraftPayload(draft as Parameters[0])), + }); + }, +); + router.patch( "/drafts/:id", authorize(ALL_ROLES), @@ -185,4 +214,3 @@ router.post( ); export const aiDraftRoutes = router; - diff --git a/apps/web/components/ai/Summarizer.tsx b/apps/web/components/ai/Summarizer.tsx index dac7311..637eb45 100644 --- a/apps/web/components/ai/Summarizer.tsx +++ b/apps/web/components/ai/Summarizer.tsx @@ -1,6 +1,6 @@ "use client"; -import { useMemo, useState } from "react"; +import { useEffect, useMemo, useState } from "react"; import { apiFetch } from "@/lib/api-client"; type Props = { @@ -54,6 +54,33 @@ export const Summarizer = ({ encounterId }: Props) => { [content, draftId, isGenerating, isSaving, mode], ); + useEffect(() => { + const loadDraft = async () => { + try { + const response = await apiFetch(`/ai/drafts?encounterId=${encodeURIComponent(encounterId)}`); + if (!response.ok) { + return; + } + + const payload = (await response.json()) as { + data?: Array<{ id: string; content: string }>; + }; + const existingDraft = payload.data?.[0]; + if (!existingDraft) { + return; + } + + setDraftId(existingDraft.id); + setContent(existingDraft.content); + setMode("draft"); + } catch { + // Ignore draft bootstrap failures. + } + }; + + void loadDraft(); + }, [encounterId]); + const startGeneration = async (useDummyStream = false) => { if (isGenerating || isSaving) { return; @@ -173,6 +200,12 @@ export const Summarizer = ({ encounterId }: Props) => { setIsSaving(true); try { + await apiFetch(`/ai/drafts/${encodeURIComponent(draftId)}`, { + method: "PATCH", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ content: content.trim() }), + }); + const response = await apiFetch(`/ai/drafts/${encodeURIComponent(draftId)}/approve`, { method: "POST", headers: { "Content-Type": "application/json" }, @@ -288,4 +321,3 @@ export const Summarizer = ({ encounterId }: Props) => { ); }; -