diff --git a/apps/backoffice/src/app/features/license-review/components/DecisionConfirmModal.tsx b/apps/backoffice/src/app/features/license-review/components/DecisionConfirmModal.tsx
index 3dbbe232a..d9df085d5 100644
--- a/apps/backoffice/src/app/features/license-review/components/DecisionConfirmModal.tsx
+++ b/apps/backoffice/src/app/features/license-review/components/DecisionConfirmModal.tsx
@@ -57,8 +57,14 @@ interface DecisionConfirmModalProps {
action: ResolvedAction | null;
applicantName: string;
applicationNumber: string;
- /** Document keys the officer flagged, for the deficiency checklist. */
- flaggedDocuments?: string[];
+ /**
+ * What the officer flagged, for the deficiency checklist.
+ *
+ * Carries a label as well as the key because the key is only human-readable
+ * for documents: a form section is camelCase and a flagged staff member is a
+ * uuid, which is not something to put in front of an officer.
+ */
+ flaggedItems?: Array<{ key: string; label: string }>;
/** Populated for Assign and Escalate, which must name a person. */
officers?: Array<{ id: string; name: string | null }>;
submitting?: boolean;
@@ -81,7 +87,7 @@ export function DecisionConfirmModal({
action,
applicantName,
applicationNumber,
- flaggedDocuments = [],
+ flaggedItems = [],
officers = [],
submitting,
onClose,
@@ -97,9 +103,9 @@ export function DecisionConfirmModal({
const [confirmText, setConfirmText] = useState('');
const codes = action ? (REASON_CODES[action.id] ?? []) : [];
- // `flaggedDocuments` is a fresh array on every parent render, so keying the
+ // `flaggedItems` is a fresh array on every parent render, so keying the
// reset effect on its identity would wipe the officer's edits continuously.
- const flaggedKey = flaggedDocuments.join('|');
+ const flaggedKey = flaggedItems.map((item) => item.key).join('|');
// Reset per opening, and seed the message the applicant will receive so the
// officer edits real copy rather than composing from nothing.
@@ -107,7 +113,7 @@ export function DecisionConfirmModal({
if (!action) return;
setReasonCode(null);
setReason('');
- setDeficiencies(flaggedDocuments);
+ setDeficiencies(flaggedItems.map((item) => item.key));
setAcknowledged(false);
setOfficerId(null);
setConfirmText('');
@@ -216,7 +222,7 @@ export function DecisionConfirmModal({
)}
{/* 3. Deficiency checklist — the applicant sees exactly this list. */}
- {action.id === 'request-adjustment' && flaggedDocuments.length > 0 && (
+ {action.id === 'request-adjustment' && flaggedItems.length > 0 && (
- {flaggedDocuments.map((key) => (
-
+ {flaggedItems.map((item) => (
+
))}
diff --git a/apps/backoffice/src/app/features/license-review/components/DocumentsTab.tsx b/apps/backoffice/src/app/features/license-review/components/DocumentsTab.tsx
index 839125fe1..3de93748c 100644
--- a/apps/backoffice/src/app/features/license-review/components/DocumentsTab.tsx
+++ b/apps/backoffice/src/app/features/license-review/components/DocumentsTab.tsx
@@ -336,12 +336,16 @@ export function DocumentsTab({
'Why must this document be corrected?',
)}
value={rejecting[attachment.documentKey]}
- onChange={(e) =>
+ onChange={(e) => {
+ // Read before the updater: React nulls `currentTarget`
+ // once the handler returns, and the updater runs later,
+ // during the re-render.
+ const reason = e.currentTarget.value;
setRejecting((prev) => ({
...prev,
- [attachment.documentKey]: e.currentTarget.value,
- }))
- }
+ [attachment.documentKey]: reason,
+ }));
+ }}
/>