feat: save insurance PDFs (eligibility/claims/preauth) to Cloud Storage instead of Postgres blobs

New saves go into the patient's Cloud Storage folder under category subfolders
(Eligibility/Claims/PreAuth/Claim Status/Attachments) via a new
storage.savePdfToCloudStorage helper, instead of the legacy PdfGroup/PdfFile
Postgres blob tables. Old records and their read paths are left untouched for
backward compatibility; PDF list/content/delete endpoints and viewers now
transparently handle both legacy numeric ids and new "cloud:<id>" ids.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-08 00:20:37 -04:00
co-authored by Claude Sonnet 5
parent 1190bc0494
commit 99cdfa702a
36 changed files with 496 additions and 296 deletions
@@ -142,14 +142,14 @@ export default function InsuranceStatusPage() {
// PDF preview modal state
const [previewOpen, setPreviewOpen] = useState(false);
const [previewPdfId, setPreviewPdfId] = useState<number | null>(null);
const [previewPdfId, setPreviewPdfId] = useState<number | string | null>(null);
const [previewFallbackFilename, setPreviewFallbackFilename] = useState<
string | null
>(null);
// Dual PDF modal state (used by MH Eligibility & History)
const [dualPreviewOpen, setDualPreviewOpen] = useState(false);
const [dualEligibilityPdfId, setDualEligibilityPdfId] = useState<number | null>(null);
const [dualEligibilityPdfId, setDualEligibilityPdfId] = useState<number | string | null>(null);
const [dualEligibilityFilename, setDualEligibilityFilename] = useState<string | null>(null);
const [dualMemberDetailsPdfId, setDualMemberDetailsPdfId] = useState<number | null>(null);
const [dualMemberDetailsFilename, setDualMemberDetailsFilename] = useState<string | null>(null);
@@ -158,7 +158,7 @@ export default function InsuranceStatusPage() {
// CMSP PDF modal state (used by CMSP Eligibility & History & Remaining)
const [cmspPreviewOpen, setCmspPreviewOpen] = useState(false);
const [cmspEligibilityPdfId, setCmspEligibilityPdfId] = useState<number | null>(null);
const [cmspEligibilityPdfId, setCmspEligibilityPdfId] = useState<number | string | null>(null);
const [cmspEligibilityFilename, setCmspEligibilityFilename] = useState<string | null>(null);
const [cmspMemberDetailsPdfId, setCmspMemberDetailsPdfId] = useState<number | null>(null);
const [cmspMemberDetailsFilename, setCmspMemberDetailsFilename] = useState<string | null>(null);
@@ -381,7 +381,7 @@ export default function InsuranceStatusPage() {
void tryAppointmentFromChatbot();
if (jobResult.pdfFileId) {
setPreviewPdfId(Number(jobResult.pdfFileId));
setPreviewPdfId(jobResult.pdfFileId);
setPreviewFallbackFilename(jobResult.pdfFilename ?? `eligibility_${memberId}.pdf`);
setPreviewOpen(true);
}
@@ -466,7 +466,7 @@ export default function InsuranceStatusPage() {
setSelectedPatient(null);
if (jobResult.pdfFileId) {
setPreviewPdfId(Number(jobResult.pdfFileId));
setPreviewPdfId(jobResult.pdfFileId);
setPreviewFallbackFilename(jobResult.pdfFilename ?? `eligibility_${memberId}.pdf`);
setPreviewOpen(true);
}
@@ -579,7 +579,7 @@ export default function InsuranceStatusPage() {
// Open all PDFs side by side in the modal
if (jobResult.pdfFileId || jobResult.memberDetailsPdfFileId || jobResult.historyPdfFileId) {
setDualEligibilityPdfId(jobResult.pdfFileId ? Number(jobResult.pdfFileId) : null);
setDualEligibilityPdfId(jobResult.pdfFileId ?? null);
setDualEligibilityFilename(jobResult.pdfFilename ?? `eligibility_${memberId}.pdf`);
setDualMemberDetailsPdfId(jobResult.memberDetailsPdfFileId ? Number(jobResult.memberDetailsPdfFileId) : null);
setDualMemberDetailsFilename(jobResult.memberDetailsPdfFilename ?? `eligibility_member_details_${memberId}.pdf`);
@@ -649,7 +649,7 @@ export default function InsuranceStatusPage() {
// Open 4-panel modal
if (jobResult.pdfFileId || jobResult.memberDetailsPdfFileId || jobResult.historyPdfFileId || jobResult.accumulatorPdfFileId) {
setCmspEligibilityPdfId(jobResult.pdfFileId ? Number(jobResult.pdfFileId) : null);
setCmspEligibilityPdfId(jobResult.pdfFileId ?? null);
setCmspEligibilityFilename(jobResult.pdfFilename ?? `cmsp_eligibility_${memberId}.pdf`);
setCmspMemberDetailsPdfId(jobResult.memberDetailsPdfFileId ? Number(jobResult.memberDetailsPdfFileId) : null);
setCmspMemberDetailsFilename(jobResult.memberDetailsPdfFilename ?? `cmsp_member_details_${memberId}.pdf`);