From 1cc8bd5a4cfde3fbe37e4740c76efa36c57aa62d Mon Sep 17 00:00:00 2001 From: Jordan Ramos Date: Wed, 3 Jun 2026 13:33:24 -0600 Subject: [PATCH] Improve CARD decline error diagnostics and prevent accidental modal dismiss - Log the full owner response in audit when update_token is missing so we can see what CARD actually returned - Improve error message to suggest the asset may have already been actioned - Remove backdrop-click-to-close on TemplateFormModal to prevent accidental data loss while filling in template content --- backend/routes/cardApi.js | 4 ++-- frontend/src/components/TemplateFormModal.js | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/backend/routes/cardApi.js b/backend/routes/cardApi.js index f377b9f..c8d6afa 100644 --- a/backend/routes/cardApi.js +++ b/backend/routes/cardApi.js @@ -363,8 +363,8 @@ function createCardApiRouter() { const updateToken = ownerData.owner && ownerData.owner.update_token; if (!updateToken) { - const errMsg = 'update_token not found in owner record.'; - logAudit({ userId: req.user.id, username: req.user.username, action: 'card_action_failed', entityType: 'ivanti_todo_queue', entityId: String(queueItemId), details: { actionType: 'decline', assetId, error: errMsg, cardStatus: null }, ipAddress: req.ip }); + const errMsg = 'update_token not found in owner record. The asset may have already been actioned or the owner record is in an unexpected state.'; + logAudit({ userId: req.user.id, username: req.user.username, action: 'card_action_failed', entityType: 'ivanti_todo_queue', entityId: String(queueItemId), details: { actionType: 'decline', assetId, error: errMsg, cardStatus: null, ownerResponse: ownerData }, ipAddress: req.ip }); return res.status(502).json({ error: 'CARD API request failed.', details: errMsg }); } diff --git a/frontend/src/components/TemplateFormModal.js b/frontend/src/components/TemplateFormModal.js index db321b8..fefc18c 100644 --- a/frontend/src/components/TemplateFormModal.js +++ b/frontend/src/components/TemplateFormModal.js @@ -8,7 +8,7 @@ import React, { useState, useEffect, useRef } from 'react'; import { X, Save, AlertCircle, Loader } from 'lucide-react'; -const API_BASE = process.env.REACT_APP_API_BASE || 'http://localhost:3001/api'; +const API_BASE = process.env.REACT_APP_API_BASE || 'http://localhost:3001/api'; // ⚠️ CONVENTION: Prefer relative API paths (e.g. '/api') over absolute URL fallback // --------------------------------------------------------------------------- // Section definitions — ordered as static first, then semi-static @@ -386,7 +386,6 @@ export default function TemplateFormModal({ mode = 'create', template = null, on aria-modal="true" aria-labelledby="template-form-modal-title" style={STYLES.backdrop} - onClick={(e) => { if (e.target === e.currentTarget) onClose?.(); }} >
{/* Header */}