feat: add "Choose from Server" attachment picker to claim/preauth forms and chatbot

Native file inputs can't be pointed at a default server folder for security
reasons, so instead the Browse buttons on the Claim/PreAuth/Select Procedures
forms and the AI chatbot's attach button now also offer picking from
previously saved Cloud Storage attachments (e.g. Copy Agent screenshots) via
a new server-side picker modal, scoped per-patient on the claim forms and
unscoped (recent across all patients) in the chatbot.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-14 00:36:43 -04:00
co-authored by Claude Sonnet 5
parent 8b245d00c6
commit 34312b62bc
6 changed files with 332 additions and 11 deletions
@@ -161,6 +161,7 @@ export interface IStorage {
patientId: number,
category: string
): Promise<CloudFile[]>;
listRecentAttachmentFiles(limit?: number): Promise<CloudFile[]>;
}
/* ------------------------------- Implementation ------------------------------- */
@@ -663,6 +664,25 @@ export const cloudStorageStorage: IStorage = {
return files.map(serializeFile) as unknown as CloudFile[];
},
async listRecentAttachmentFiles(limit: number = 20) {
const files = await db.cloudFile.findMany({
where: { folder: { name: "Attachments" }, isComplete: true },
orderBy: { createdAt: "desc" },
take: limit,
select: {
id: true,
name: true,
mimeType: true,
fileSize: true,
folderId: true,
isComplete: true,
createdAt: true,
updatedAt: true,
},
});
return files.map(serializeFile) as unknown as CloudFile[];
},
// --- STREAM ---
async streamFileTo(resStream: NodeJS.WritableStream, fileId: number) {
const file = await db.cloudFile.findUnique({