Fix #5: createSSRequest fails fast when storeNumber is missing

- New SUBTYPES_REQUIRING_STORE_NUMBER set (seeded with every current
  subType, all of which mark Store Number required in JSM). Adding a
  future subType that does NOT require Store Number is a one-line omit.
- createSSRequest now trims storeNumber (rejects whitespace-only) and
  throws a 400 with a clear message ("storeNumber is required for
  subType ...") before making any Jira API call.
- Validation errors now carry err.status = 400 so future non-route
  callers can distinguish client errors from Jira failures.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
jmcqueen 2026-07-01 16:30:13 -04:00
parent c4a0a6934e
commit 312448f597

View file

@ -683,6 +683,12 @@ const REQUEST_TYPE_MAP = {
'Store Transportation Request': 493,
};
// SubTypes that require a storeNumber. Every currently-supported subType maps
// to a request type whose Store Number field is `required: true` in JSM (see
// ss-fields-*.json). Kept as an explicit set so a future subType that does NOT
// require Store Number can be added by simply omitting it from this set.
const SUBTYPES_REQUIRING_STORE_NUMBER = new Set(Object.keys(REQUEST_TYPE_MAP));
/**
* Create a Store Support ticket (JSM request) using the Service Desk API.
* @param {Object} params
@ -1350,12 +1356,29 @@ export async function createSSRequest(params = {}) {
} = params;
if (!subType || !summary) {
throw new Error('subType and summary are required');
const err = new Error('subType and summary are required');
err.status = 400;
throw err;
}
const requestTypeId = REQUEST_TYPE_MAP[subType];
if (!requestTypeId) {
throw new Error(`Unknown subType: "${subType}". Must be one of the supported values.`);
const err = new Error(`Unknown subType: "${subType}". Must be one of the supported values.`);
err.status = 400;
throw err;
}
// Fail-fast: every current subType requires Store Number. Catching this
// client-side gives a clean API error instead of forwarding to Jira and
// getting back an opaque "Please provide a value for required field
// 'Store Number'" that references Jira internals.
const normalizedStoreNumber = storeNumber != null && String(storeNumber).trim() !== ''
? String(storeNumber).trim()
: null;
if (SUBTYPES_REQUIRING_STORE_NUMBER.has(subType) && !normalizedStoreNumber) {
const err = new Error(`storeNumber is required for subType "${subType}"`);
err.status = 400;
throw err;
}
const serviceDeskId = config.jira.serviceDeskId || '170';
@ -1369,9 +1392,9 @@ export async function createSSRequest(params = {}) {
...additional
};
if (storeNumber) {
if (normalizedStoreNumber) {
// Resolve to proper Assets object reference: [ { "objectId": "82288" } ]
const storeRef = await resolveStoreAssetReference(storeNumber);
const storeRef = await resolveStoreAssetReference(normalizedStoreNumber);
if (storeRef) {
requestFieldValues[storeCustomField] = storeRef;
}