From cfb0a5c69fbb85dd25286159fef02d72627873fd Mon Sep 17 00:00:00 2001 From: anaj00 Date: Wed, 17 Jun 2026 12:10:52 +0800 Subject: [PATCH 01/10] feat: enhance signature image handling in form filler and autofill hooks --- .../features/student/forms/FormFillerRenderer.tsx | 7 ++++++- hooks/use-my-autofill.tsx | 13 +++++++++++++ lib/saved-signature-image.ts | 2 -- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/components/features/student/forms/FormFillerRenderer.tsx b/components/features/student/forms/FormFillerRenderer.tsx index 3b01143b..6c8e20b8 100644 --- a/components/features/student/forms/FormFillerRenderer.tsx +++ b/components/features/student/forms/FormFillerRenderer.tsx @@ -110,10 +110,15 @@ export function FormFillerRenderer({ profileFullName, "initiator", ); + const signatureImagePreference = autofillValues.__signature_image_enabled; + const effectiveSignatureImage = + signatureImagePreference === "false" + ? null + : profile.data?.signatureImage; const valuesWithSavedSignatureImages = withSavedSignatureImagesForFields({ values: valuesWithPrefilledSignatures, signatureFields, - signatureImage: profile.data?.signatureImage, + signatureImage: effectiveSignatureImage, }); formFiller.initializeValues(valuesWithSavedSignatureImages); diff --git a/hooks/use-my-autofill.tsx b/hooks/use-my-autofill.tsx index ec2b1858..ba7135b6 100644 --- a/hooks/use-my-autofill.tsx +++ b/hooks/use-my-autofill.tsx @@ -6,6 +6,8 @@ import { ClientField, ClientPhantomField, FormValues, + parseSignatureImageValue, + SIGNATURE_IMAGE_FIELD_PREFIX, } from "@betterinternship/core/forms"; import { useCallback, useMemo } from "react"; import { getFreshHistoryCutoffMsFromStorage } from "@/app/student/forms/fresh-history"; @@ -102,6 +104,17 @@ export const useMyAutofillUpdate = () => { } } + const signatureImageKeys = Object.keys(finalValues).filter((key) => + key.startsWith(SIGNATURE_IMAGE_FIELD_PREFIX), + ); + if (signatureImageKeys.length > 0) { + const usedSignatureImage = signatureImageKeys.some((key) => + parseSignatureImageValue(finalValues[key]), + ); + internshipMoaFieldsToSave.shared.__signature_image_enabled = + usedSignatureImage ? "true" : "false"; + } + // Save for future use await update.mutateAsync({ internship_moa_fields: internshipMoaFieldsToSave, diff --git a/lib/saved-signature-image.ts b/lib/saved-signature-image.ts index a7374f25..61b8b527 100644 --- a/lib/saved-signature-image.ts +++ b/lib/saved-signature-image.ts @@ -17,8 +17,6 @@ export const withSavedSignatureImagesForFields = ({ const nextValues = { ...values }; for (const signatureField of signatureFields) { const imageFieldKey = getSignatureImageFieldKey(signatureField.field); - if (Object.prototype.hasOwnProperty.call(nextValues, imageFieldKey)) - continue; nextValues[imageFieldKey] = signatureImage; } From cc9cc6d57bbb5b4042e2d3a1feb8deb1cdcf2f3c Mon Sep 17 00:00:00 2001 From: anaj00 Date: Sat, 13 Jun 2026 00:29:46 +0800 Subject: [PATCH 02/10] chore: restarted client so new university can render --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index a22efee5..4fb2f6c2 100644 --- a/README.md +++ b/README.md @@ -15,5 +15,4 @@ npm run dev ## Jest Testing ```bash npm run test -``` - +``` \ No newline at end of file From f22ce9fc0c5b1cfb2d769dc2268f98def29e9c8f Mon Sep 17 00:00:00 2001 From: Mo David Date: Wed, 17 Jun 2026 16:02:19 +0800 Subject: [PATCH 03/10] hotfix: unblock https://orca.betterinternship.com from CSP --- next.config.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/next.config.mjs b/next.config.mjs index cafb7acf..bf0ec988 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -2,7 +2,7 @@ const apiUrls = [ process.env.NEXT_PUBLIC_API_URL, process.env.NEXT_PUBLIC_MOA_API_URL, process.env.NEXT_PUBLIC_API_SERVER_URL, - process.env.NEXT_PUBLIC_SUPABASE_URL, + process.env.NEXT_PUBLIC_ORCA_URL, ].filter(Boolean); const connectOrigins = apiUrls From 66b9c89070e84cd75eac33fae20efbd49fe9a641 Mon Sep 17 00:00:00 2001 From: jayylmao <73204320+jayylmao@users.noreply.github.com> Date: Wed, 17 Jun 2026 20:41:39 +0800 Subject: [PATCH 04/10] chore: update vulnerable packages --- package.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 5482d587..d3707cbe 100644 --- a/package.json +++ b/package.json @@ -86,7 +86,7 @@ "number-to-words": "^1.2.4", "pg": "^8.20.0", "pocketbase": "^0.26.1", - "posthog-js": "^1.255.1", + "posthog-js": "^1.386.6", "qrcode.react": "^4.2.0", "react": "^19", "react-countdown": "^2.3.6", @@ -137,5 +137,11 @@ "ts-jest": "^29.4.5", "typescript": "^5", "typescript-eslint": "^8.20.0" + }, + "overrides": { + "js-yaml": ">=4.1.2", + "nanoid": ">=5.0.9", + "nodemailer": ">=9.0.0", + "tar": ">=7.5.16" } } From 82990c3ed830e9942678fc9f0a618883765e9c1f Mon Sep 17 00:00:00 2001 From: Jana Marie Bantolino Date: Fri, 19 Jun 2026 12:43:47 +0800 Subject: [PATCH 05/10] chore: removed console logs --- app/student/forms/myforms.ctx.tsx | 2 -- app/student/forms/page.tsx | 1 - components/forms/FormHistoryView.tsx | 2 -- 3 files changed, 5 deletions(-) diff --git a/app/student/forms/myforms.ctx.tsx b/app/student/forms/myforms.ctx.tsx index 8275438d..6130489d 100644 --- a/app/student/forms/myforms.ctx.tsx +++ b/app/student/forms/myforms.ctx.tsx @@ -75,8 +75,6 @@ export const MyFormsContextProvider = ({ timestamp: f.timestamp, })) ?? []; - console.log("FORMS FORMS FORMS", forms); - // Helper function to check if form has pending instances const hasPendingInstance = (formLabel: string): boolean => { return mappedForms.some( diff --git a/app/student/forms/page.tsx b/app/student/forms/page.tsx index 40733d5a..41b1e673 100644 --- a/app/student/forms/page.tsx +++ b/app/student/forms/page.tsx @@ -41,7 +41,6 @@ export default function FormsPage() { ); useEffect(() => { - console.log("PORFIE", profile.data); if (profile.isPending) return; setHasFormsAccess((currentAccess) => { diff --git a/components/forms/FormHistoryView.tsx b/components/forms/FormHistoryView.tsx index 5ed18c50..fa69c515 100644 --- a/components/forms/FormHistoryView.tsx +++ b/components/forms/FormHistoryView.tsx @@ -37,8 +37,6 @@ export function FormHistoryView({ forms, formLabel }: FormHistoryViewProps) { [forms, formLabel], ); - console.log("here are the forms to be displayed: ", filteredForms); - return (
From 006b5c33396b632c5c92ed530d10f7cb3ab16c19 Mon Sep 17 00:00:00 2001 From: Jana Marie Bantolino Date: Fri, 19 Jun 2026 12:44:27 +0800 Subject: [PATCH 06/10] chore: resolved signature cache, as well as signature behavior --- .../forms/components/FormSigningLayout.tsx | 7 +++ .../student/forms/FormFillerRenderer.tsx | 39 +++++++------ .../student/forms/SignatureFieldRenderer.tsx | 12 +++- lib/saved-signature-image.ts | 6 +- lib/signature-image-submit.ts | 25 +++++--- lib/signed-url.ts | 57 ++++++++++++++++++- package.json | 2 +- 7 files changed, 113 insertions(+), 35 deletions(-) diff --git a/app/student/forms/components/FormSigningLayout.tsx b/app/student/forms/components/FormSigningLayout.tsx index 8c3d2005..6c76701d 100644 --- a/app/student/forms/components/FormSigningLayout.tsx +++ b/app/student/forms/components/FormSigningLayout.tsx @@ -358,6 +358,13 @@ export function FormSigningLayout({ } return filtered; }, [previewValuesResolved, fieldOwnerByName, noEsign]); + useEffect(() => { + const sigEntries = Object.entries(previewValuesForViewer).filter(([k]) => + k.startsWith("__signatureImage"), + ); + if (sigEntries.length) + console.debug("[FormSigningLayout] signature image values", sigEntries); + }, [previewValuesForViewer]); const wetSignatureHiddenFieldNames = useMemo( () => (noEsign ? getSignatureDerivedFieldNames(form.formMetadata) : []), [form.formMetadata, noEsign], diff --git a/components/features/student/forms/FormFillerRenderer.tsx b/components/features/student/forms/FormFillerRenderer.tsx index 6c8e20b8..b8e74971 100644 --- a/components/features/student/forms/FormFillerRenderer.tsx +++ b/components/features/student/forms/FormFillerRenderer.tsx @@ -104,24 +104,27 @@ export function FormFillerRenderer({ const profileFullName = getFullName(profile.data); useEffect(() => { - const valuesWithPrefilledSignatures = - form.formMetadata.setSignatureValueForSigningParty( - formFiller.getFinalValues(autofillValues), - profileFullName, - "initiator", - ); - const signatureImagePreference = autofillValues.__signature_image_enabled; - const effectiveSignatureImage = - signatureImagePreference === "false" - ? null - : profile.data?.signatureImage; - const valuesWithSavedSignatureImages = withSavedSignatureImagesForFields({ - values: valuesWithPrefilledSignatures, - signatureFields, - signatureImage: effectiveSignatureImage, - }); - - formFiller.initializeValues(valuesWithSavedSignatureImages); + (async () => { + const valuesWithPrefilledSignatures = + form.formMetadata.setSignatureValueForSigningParty( + formFiller.getFinalValues(autofillValues), + profileFullName, + "initiator", + ); + const signatureImagePreference = autofillValues.__signature_image_enabled; + const effectiveSignatureImage = + signatureImagePreference === "false" + ? null + : profile.data?.signatureImage; + const valuesWithSavedSignatureImages = + await withSavedSignatureImagesForFields({ + values: valuesWithPrefilledSignatures, + signatureFields, + signatureImage: effectiveSignatureImage, + }); + + formFiller.initializeValues(valuesWithSavedSignatureImages); + })(); }, [ autofillValues, form.formMetadata, diff --git a/components/features/student/forms/SignatureFieldRenderer.tsx b/components/features/student/forms/SignatureFieldRenderer.tsx index bf67713f..d19e19e3 100644 --- a/components/features/student/forms/SignatureFieldRenderer.tsx +++ b/components/features/student/forms/SignatureFieldRenderer.tsx @@ -10,11 +10,13 @@ import { removeSignatureImageBackground } from "@/lib/signature-image-cleanup"; import { createSignatureImageValue, getSignatureImageFieldKey, + isBucketSignatureImagePayload, parseSignatureImageValue, serializeSignatureImageValue, type ClientField, type SignatureImageValue, } from "@betterinternship/core/forms"; +import { BUCKET_PREFIX } from "@/lib/signed-url"; import { ImageUp, PenLine, Trash2, Type, UploadCloud } from "lucide-react"; import { useEffect, useMemo, useRef, useState } from "react"; @@ -83,8 +85,10 @@ export const SignatureFieldRenderer = ({ const getSignatureImageSrc = (signature: SignatureImageValue | null) => { if (!signature) return ""; - if (signature.image.storage === "bucket") { - return signature.image.signedUrl || signature.image.publicUrl || ""; + if (isBucketSignatureImagePayload(signature.image)) { + return ( + signature.image.signedUrl || `${BUCKET_PREFIX}${signature.image.path}` + ); } return signature.image.dataUrl; }; @@ -318,7 +322,9 @@ export const SignatureFieldRenderer = ({ }; const signatureImageSrc = getSignatureImageSrc(signatureImage); - const isSavedSignatureImage = signatureImage?.image.storage === "bucket"; + const isSavedSignatureImage = signatureImage + ? isBucketSignatureImagePayload(signatureImage.image) + : false; return (
diff --git a/lib/saved-signature-image.ts b/lib/saved-signature-image.ts index 61b8b527..b7113c42 100644 --- a/lib/saved-signature-image.ts +++ b/lib/saved-signature-image.ts @@ -2,8 +2,9 @@ import { getSignatureImageFieldKey, type FormValues, } from "@betterinternship/core/forms"; +import { resolveSignatureImageValue } from "@/lib/signed-url"; -export const withSavedSignatureImagesForFields = ({ +export const withSavedSignatureImagesForFields = async ({ values, signatureFields, signatureImage, @@ -14,10 +15,11 @@ export const withSavedSignatureImagesForFields = ({ }) => { if (!signatureImage?.trim()) return values; + const resolvedSignatureImage = await resolveSignatureImageValue(signatureImage); const nextValues = { ...values }; for (const signatureField of signatureFields) { const imageFieldKey = getSignatureImageFieldKey(signatureField.field); - nextValues[imageFieldKey] = signatureImage; + nextValues[imageFieldKey] = resolvedSignatureImage; } return nextValues; diff --git a/lib/signature-image-submit.ts b/lib/signature-image-submit.ts index 0b94e4f5..fcaaa20e 100644 --- a/lib/signature-image-submit.ts +++ b/lib/signature-image-submit.ts @@ -1,8 +1,10 @@ import { FormService } from "@/lib/api/services"; import { + isInlineSignatureImagePayload, parseSignatureImageValue, type FormValues, } from "@betterinternship/core/forms"; +import { resolveSignatureImageValue } from "@/lib/signed-url"; const SIGNATURE_IMAGE_PREFIX = "__signatureImage:"; @@ -28,18 +30,25 @@ export async function withSubmittedSignatureImages(values: FormValues): Promise< for (const [field, value] of Object.entries(values)) { const signatureImage = parseSignatureImageValue(value); - if (!signatureImage || signatureImage.image.storage !== "inline") continue; + if (!signatureImage) continue; - const result = await FormService.uploadSignatureImage({ - source: signatureImage.source, - dataUrl: signatureImage.image.dataUrl, - }); + // Inline → upload to server, get bucket reference + if (isInlineSignatureImagePayload(signatureImage.image)) { + const result = await FormService.uploadSignatureImage({ + source: signatureImage.source, + dataUrl: signatureImage.image.dataUrl, + }); - if (!result.value) { - throw new Error("Signature image upload did not return a saved image."); + if (!result.value) { + throw new Error("Signature image upload did not return a saved image."); + } + + nextValues[field] = result.value; + continue; } - nextValues[field] = result.value; + // Bucket → resolve fresh signed URL + nextValues[field] = await resolveSignatureImageValue(value); } removeDuplicateSignatureImageKeys(nextValues); diff --git a/lib/signed-url.ts b/lib/signed-url.ts index 72ab0c33..cba1ba68 100644 --- a/lib/signed-url.ts +++ b/lib/signed-url.ts @@ -1,8 +1,14 @@ "use client"; +import { + isBucketSignatureImagePayload, + parseSignatureImageValue, + serializeSignatureImageValue, + type FormValues, +} from "@betterinternship/core/forms"; import { useEffect, useState } from "react"; -const BUCKET_PREFIX = +export const BUCKET_PREFIX = "https://storage.googleapis.com/better-internship-public-bucket/"; export const isBucketUrl = (url: string): boolean => @@ -30,11 +36,22 @@ const resolveFromServer = async ( }; export const resolveSignedUrl = (url: string): Promise => { - if (!isBucketUrl(url)) return Promise.resolve(url); + if (!isBucketUrl(url)) { + console.debug("[resolveSignedUrl] not a bucket URL, skip", { url }); + return Promise.resolve(url); + } const cached = cache.get(url); - if (cached && cached.expiresAt > Date.now()) + if (cached && cached.expiresAt > Date.now()) { + console.debug("[resolveSignedUrl] cache hit", { url, expiresAt: new Date(cached.expiresAt).toISOString() }); return Promise.resolve(cached.signedUrl); + } + + if (cached) { + console.debug("[resolveSignedUrl] cache expired", { url, expiredAt: new Date(cached.expiresAt).toISOString() }); + } else { + console.debug("[resolveSignedUrl] not in cache", { url }); + } const existing = inflight.get(url); if (existing) return existing; @@ -44,10 +61,12 @@ export const resolveSignedUrl = (url: string): Promise => { const signedUrl = result[url] ?? url; cache.set(url, { signedUrl, expiresAt: Date.now() + TTL_MS }); inflight.delete(url); + console.debug("[resolveSignedUrl] server resolved", { url, signedUrl }); return signedUrl; }) .catch(() => { inflight.delete(url); + console.debug("[resolveSignedUrl] server fetch failed, returning original", { url }); return url; }); inflight.set(url, promise); @@ -126,3 +145,35 @@ export const useSignedUrls = (urls: string[]) => { return { urls: resolved, loading }; }; + +export const resolveSignatureImageValue = async ( + value: string, +): Promise => { + const parsed = parseSignatureImageValue(value); + if (!parsed || !isBucketSignatureImagePayload(parsed.image)) { + console.debug("[resolveSignatureImageValue] not a bucket payload", { value, parsed }); + return value; + } + if (parsed.image.signedUrl) { + console.debug("[resolveSignatureImageValue] already has signedUrl, skip", { path: parsed.image.path, signedUrl: parsed.image.signedUrl }); + return value; + } + const bucketUrl = `${BUCKET_PREFIX}${parsed.image.path}`; + console.debug("[resolveSignatureImageValue] requesting signed URL", { bucketUrl }); + parsed.image.signedUrl = await resolveSignedUrl(bucketUrl); + console.debug("[resolveSignatureImageValue] resolved", { bucketUrl, signedUrl: parsed.image.signedUrl }); + return serializeSignatureImageValue(parsed); +}; + +export const resolveSignatureImageValues = async ( + values: FormValues, +): Promise => { + const next = { ...values }; + await Promise.all( + Object.entries(values).map(async ([key, value]) => { + if (!key.startsWith("__signatureImage:")) return; + next[key] = await resolveSignatureImageValue(value); + }), + ); + return next; +}; diff --git a/package.json b/package.json index d3707cbe..a6a2ef16 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@betterinternship/components": "1.5.28", - "@betterinternship/core": "^2.14.1", + "@betterinternship/core": "^2.16.0", "pdfjs-dist": "^4.4.168", "@betterinternship/schema": "^0.0.0", "@dnd-kit/core": "^6.3.1", From 531a4c7805ebd53f3b8dbda08207b16d66c0c991 Mon Sep 17 00:00:00 2001 From: anaj00 Date: Sun, 21 Jun 2026 00:51:56 +0800 Subject: [PATCH 07/10] chore: update @betterinternship/core dependency to version 2.16.6 + simplified previewer block filter --- .../forms/components/FormSigningLayout.tsx | 60 +++++-------------- package.json | 2 +- 2 files changed, 15 insertions(+), 47 deletions(-) diff --git a/app/student/forms/components/FormSigningLayout.tsx b/app/student/forms/components/FormSigningLayout.tsx index 6c76701d..4d49b5ae 100644 --- a/app/student/forms/components/FormSigningLayout.tsx +++ b/app/student/forms/components/FormSigningLayout.tsx @@ -184,17 +184,6 @@ export function FormSigningLayout({ window.removeEventListener("resize", updateCompactSigningLayout); }, []); - const fieldOwnerByName = useMemo(() => { - const ownerMap = new Map(); - const allBlocks = form.formMetadata.getBlocksForEditorService(); - allBlocks.forEach((block) => { - const fieldName = - block.field_schema?.field ?? block.phantom_field_schema?.field; - if (!fieldName || ownerMap.has(fieldName)) return; - ownerMap.set(fieldName, block.signing_party_id); - }); - return ownerMap; - }, [form.formMetadata, form.formName]); const formFilloutProcess = useFormFilloutProcessRunner(); const fromMe = useMemo( () => @@ -287,14 +276,6 @@ export function FormSigningLayout({ [], ); - const previewKeyedFields = useMemo( - () => - (form.keyedFields ?? []).map((field) => ({ - ...field, - signing_party_id: fieldOwnerByName.get(field.field), - })), - [form.keyedFields, fieldOwnerByName], - ); const requiredManualFieldGroups = useMemo(() => { const fields = noEsign ? form.formMetadata.getFieldsForClientService(undefined) @@ -346,25 +327,13 @@ export function FormSigningLayout({ } return resolved; }, [previewValuesWithDerived, refs]); - const previewValuesForViewer = useMemo(() => { - if (noEsign) return previewValuesResolved; - const filtered: Record = {}; - for (const key of Object.keys(previewValuesResolved)) { - const normalized = key.replace(/:default$/i, "").replace(/:auto$/i, ""); - const owner = - fieldOwnerByName.get(normalized) ?? fieldOwnerByName.get(key); - if (owner !== undefined && owner !== "initiator") continue; - filtered[key] = previewValuesResolved[key]; - } - return filtered; - }, [previewValuesResolved, fieldOwnerByName, noEsign]); useEffect(() => { - const sigEntries = Object.entries(previewValuesForViewer).filter(([k]) => + const sigEntries = Object.entries(previewValuesResolved).filter(([k]) => k.startsWith("__signatureImage"), ); if (sigEntries.length) console.debug("[FormSigningLayout] signature image values", sigEntries); - }, [previewValuesForViewer]); + }, [previewValuesResolved]); const wetSignatureHiddenFieldNames = useMemo( () => (noEsign ? getSignatureDerivedFieldNames(form.formMetadata) : []), [form.formMetadata, noEsign], @@ -373,21 +342,20 @@ export function FormSigningLayout({ const hiddenSet = new Set( wetSignatureHiddenFieldNames.map(normalizeFieldName), ); + const allBlocks = form.formMetadata.getBlocksForEditorService(); const raw = noEsign - ? previewKeyedFields.filter( - (field) => - field.type !== "signature" && - !hiddenSet.has(normalizeFieldName(field.field)), + ? allBlocks.filter( + (block) => + block.block_type === "form_field" && + block.field_schema?.type !== "signature" && + !hiddenSet.has(normalizeFieldName(block.field_schema?.field ?? "")), ) - : previewKeyedFields; - return raw.map((field) => ({ - ...field, - id: - field.id || - field._id || - `${field.field}:${field.page}:${field.x}:${field.y}`, + : allBlocks; + return raw.map((block) => ({ + ...block, + id: block._id, })); - }, [previewKeyedFields, noEsign, wetSignatureHiddenFieldNames]); + }, [form.formMetadata, noEsign, wetSignatureHiddenFieldNames]); const computeRequiredFieldsComplete = useCallback( (nextValues: FormValues) => @@ -902,7 +870,7 @@ export function FormSigningLayout({ key={isMobileLayout ? "mobile-preview" : "desktop-preview"} documentUrl={resolvedDocumentUrl} blocks={previewBlocksForViewer} - values={previewValuesForViewer} + values={previewValuesResolved} fieldErrors={formFiller.errors} selectionTick={selectionTick} autoScrollToSelectedField={ diff --git a/package.json b/package.json index a6a2ef16..3da73835 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@betterinternship/components": "1.5.28", - "@betterinternship/core": "^2.16.0", + "@betterinternship/core": "^2.16.6", "pdfjs-dist": "^4.4.168", "@betterinternship/schema": "^0.0.0", "@dnd-kit/core": "^6.3.1", From a733406d153aef7132a3e9b9fefb5822e48ab3c0 Mon Sep 17 00:00:00 2001 From: Jana Marie Bantolino Date: Mon, 22 Jun 2026 01:56:19 +0800 Subject: [PATCH 08/10] refactor: rm console debugs --- app/student/forms/components/FormSigningLayout.tsx | 8 +------- lib/signed-url.ts | 14 -------------- 2 files changed, 1 insertion(+), 21 deletions(-) diff --git a/app/student/forms/components/FormSigningLayout.tsx b/app/student/forms/components/FormSigningLayout.tsx index 4d49b5ae..0886efc0 100644 --- a/app/student/forms/components/FormSigningLayout.tsx +++ b/app/student/forms/components/FormSigningLayout.tsx @@ -327,13 +327,7 @@ export function FormSigningLayout({ } return resolved; }, [previewValuesWithDerived, refs]); - useEffect(() => { - const sigEntries = Object.entries(previewValuesResolved).filter(([k]) => - k.startsWith("__signatureImage"), - ); - if (sigEntries.length) - console.debug("[FormSigningLayout] signature image values", sigEntries); - }, [previewValuesResolved]); + const wetSignatureHiddenFieldNames = useMemo( () => (noEsign ? getSignatureDerivedFieldNames(form.formMetadata) : []), [form.formMetadata, noEsign], diff --git a/lib/signed-url.ts b/lib/signed-url.ts index cba1ba68..2c4743b8 100644 --- a/lib/signed-url.ts +++ b/lib/signed-url.ts @@ -37,22 +37,14 @@ const resolveFromServer = async ( export const resolveSignedUrl = (url: string): Promise => { if (!isBucketUrl(url)) { - console.debug("[resolveSignedUrl] not a bucket URL, skip", { url }); return Promise.resolve(url); } const cached = cache.get(url); if (cached && cached.expiresAt > Date.now()) { - console.debug("[resolveSignedUrl] cache hit", { url, expiresAt: new Date(cached.expiresAt).toISOString() }); return Promise.resolve(cached.signedUrl); } - if (cached) { - console.debug("[resolveSignedUrl] cache expired", { url, expiredAt: new Date(cached.expiresAt).toISOString() }); - } else { - console.debug("[resolveSignedUrl] not in cache", { url }); - } - const existing = inflight.get(url); if (existing) return existing; @@ -61,12 +53,10 @@ export const resolveSignedUrl = (url: string): Promise => { const signedUrl = result[url] ?? url; cache.set(url, { signedUrl, expiresAt: Date.now() + TTL_MS }); inflight.delete(url); - console.debug("[resolveSignedUrl] server resolved", { url, signedUrl }); return signedUrl; }) .catch(() => { inflight.delete(url); - console.debug("[resolveSignedUrl] server fetch failed, returning original", { url }); return url; }); inflight.set(url, promise); @@ -151,17 +141,13 @@ export const resolveSignatureImageValue = async ( ): Promise => { const parsed = parseSignatureImageValue(value); if (!parsed || !isBucketSignatureImagePayload(parsed.image)) { - console.debug("[resolveSignatureImageValue] not a bucket payload", { value, parsed }); return value; } if (parsed.image.signedUrl) { - console.debug("[resolveSignatureImageValue] already has signedUrl, skip", { path: parsed.image.path, signedUrl: parsed.image.signedUrl }); return value; } const bucketUrl = `${BUCKET_PREFIX}${parsed.image.path}`; - console.debug("[resolveSignatureImageValue] requesting signed URL", { bucketUrl }); parsed.image.signedUrl = await resolveSignedUrl(bucketUrl); - console.debug("[resolveSignatureImageValue] resolved", { bucketUrl, signedUrl: parsed.image.signedUrl }); return serializeSignatureImageValue(parsed); }; From 7058873d9b4175414425e9869f04d52914c2b02c Mon Sep 17 00:00:00 2001 From: Jana Marie Bantolino Date: Mon, 22 Jun 2026 02:03:36 +0800 Subject: [PATCH 09/10] chore: set max pool size to 1 for database connections in use-bi-moa-backend and use-refs-backend --- lib/db/use-bi-moa-backend.ts | 1 + lib/db/use-refs-backend.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/lib/db/use-bi-moa-backend.ts b/lib/db/use-bi-moa-backend.ts index 4be06043..b6fe0024 100644 --- a/lib/db/use-bi-moa-backend.ts +++ b/lib/db/use-bi-moa-backend.ts @@ -21,6 +21,7 @@ const db = new Kysely({ dialect: new PostgresDialect({ pool: new Pool({ connectionString: DATABASE_URL, + max: 1, }), }), }); diff --git a/lib/db/use-refs-backend.ts b/lib/db/use-refs-backend.ts index 61108e53..f5e9e88a 100644 --- a/lib/db/use-refs-backend.ts +++ b/lib/db/use-refs-backend.ts @@ -34,6 +34,7 @@ const db = new Kysely({ dialect: new PostgresDialect({ pool: new Pool({ connectionString: DATABASE_URL, + max: 1, }), }), }); From 35b5fede263d302c1232b1b42bd64eb42967c410 Mon Sep 17 00:00:00 2001 From: Jana Marie Bantolino Date: Mon, 22 Jun 2026 02:33:46 +0800 Subject: [PATCH 10/10] chore: lock js-yaml version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3da73835..25243658 100644 --- a/package.json +++ b/package.json @@ -139,7 +139,7 @@ "typescript-eslint": "^8.20.0" }, "overrides": { - "js-yaml": ">=4.1.2", + "js-yaml": "4.1.1", "nanoid": ">=5.0.9", "nodemailer": ">=9.0.0", "tar": ">=7.5.16"