@ministryofjustice/hmpps-digital-prison-reporting-frontend 6.6.2 → 6.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -324,7 +324,7 @@ async function detectExpiredFinishedReports({ reports, services, token, }) {
324
324
  }
325
325
  // de‑duplicate tableIds for batch lookup
326
326
  const tableIds = [...new Set(finishedWithTables.map((r) => r.tableId))];
327
- const batches = chunkArray(tableIds, 50);
327
+ const batches = chunkArray(tableIds, 200);
328
328
  const expiryStates = await batches.reduce(async (accPromise, batch) => {
329
329
  const acc = await accPromise;
330
330
  const result = await services.reportingService.getTableExpiryState(token, batch);
@@ -1 +1 @@
1
- {"version":3,"file":"getReportStatus.js","sources":["../../../../../../../../../../src/dpr/utils/ReportStatus/getReportStatus.ts"],"sourcesContent":["import {\n RequestStatus,\n UpstreamSignal,\n StatusResolution,\n FailureInfo,\n EvaluateAndUpdateReportStatusOptions,\n GetReportStatusOptions,\n TERMINAL_STATUSES,\n FIFTEEN_MINUTES_MS,\n ExpireFinishedReportsOptions,\n} from './types'\nimport ErrorHandler, { DprErrorMessage } from '../ErrorHandler/ErrorHandler'\nimport { Services } from '../../types/Services'\nimport { StoredReportData, ReportType, RequestedReport } from '../../types/UserReports'\nimport { getValues } from '../localsHelper'\nimport { getAllMyReports } from '../reportStoreHelper'\nimport { components } from '../../types/api'\nimport logger from '../logger'\n\n/**\n * ------------------------------------------------------------\n * API\n * ------------------------------------------------------------\n */\n\n/**\n * Get the status by report type\n *\n * @param {GetReportStatusOptions} {\n * reportType,\n * services,\n * token,\n * reportId,\n * id,\n * executionId,\n * definitionsPath,\n * tableId,\n * }\n * @return {*} {Promise<UpstreamSignal>}\n */\nasync function getStatusByType({\n reportType,\n services,\n token,\n reportId,\n id,\n executionId,\n definitionsPath,\n tableId,\n}: GetReportStatusOptions): Promise<UpstreamSignal> {\n try {\n const response =\n reportType === ReportType.DASHBOARD\n ? await services.dashboardService.getAsyncStatus(token, reportId, id, executionId, tableId, definitionsPath)\n : await services.reportingService.getAsyncReportStatus(\n token,\n reportId,\n id,\n executionId,\n definitionsPath,\n tableId,\n )\n\n const data = response as {\n status?: string\n error: string\n errorCategory?: number\n stateChangeReason?: string\n }\n\n if (!data.status) {\n return { kind: 'EMPTY' }\n }\n\n if (data.status === RequestStatus.FAILED) {\n const formatted = failedPayloadToDprError(data)\n return {\n kind: 'ERROR',\n failure: toFailureInfo(formatted),\n }\n }\n\n return {\n kind: 'STATUS',\n status: data.status as RequestStatus,\n }\n } catch (error) {\n const formatted = new ErrorHandler(error).formatError()\n\n return {\n kind: 'ERROR',\n failure: toFailureInfo(formatted),\n }\n }\n}\n\n/**\n * ------------------------------------------------------------\n * ORCHESTRATION\n * ------------------------------------------------------------\n */\n\n/**\n * Gets the status for a reports and its child reports\n *\n * @param {{\n * stored: StoredReportData\n * services: Services\n * token: string\n * }} {\n * stored,\n * services,\n * token,\n * }\n * @return {*} {Promise<{\n * parentSignal: UpstreamSignal\n * childSignals: UpstreamSignal[]\n * }>}\n */\nasync function getStatus({\n stored,\n services,\n token,\n}: {\n stored: StoredReportData\n services: Services\n token: string\n}): Promise<{\n parentSignal: UpstreamSignal\n childSignals: UpstreamSignal[]\n}> {\n const { reportId, id, tableId, executionId, dataProductDefinitionsPath } = stored\n const definitionsPath = dataProductDefinitionsPath || ''\n\n if (!executionId || !tableId) {\n throw new Error('Stored report missing executionId or tableId')\n }\n\n const parentSignal = await getStatusByType({\n reportType: stored.type,\n services,\n token,\n reportId,\n id,\n executionId,\n definitionsPath,\n tableId,\n })\n\n const childSignals = stored.childExecutionData\n ? await Promise.all(\n stored.childExecutionData.map((child) => {\n const { tableId: childTableId, executionId: childExecutionId } = child\n\n if (!childExecutionId || !childTableId) {\n throw new Error('Stored child report missing executionId or tableId')\n }\n\n return getStatusByType({\n services,\n reportType: ReportType.REPORT,\n token,\n reportId,\n id,\n executionId: childExecutionId,\n definitionsPath,\n tableId: childTableId,\n })\n }),\n )\n : []\n\n return {\n parentSignal,\n childSignals,\n }\n}\n\n/**\n * Converts a normalized internal error (`DprErrorMessage`) into a `FailureInfo`\n * object that is safe and consistent to store and return to clients.\n *\n * @param {DprErrorMessage} error\n * @return {*} {FailureInfo}\n */\nfunction toFailureInfo(error: DprErrorMessage): FailureInfo {\n const normalize = (msg?: string | string[]): string =>\n Array.isArray(msg) ? msg.join('. ') : msg || 'An unexpected error occurred'\n\n return {\n userMessage: normalize(error.userMessage),\n ...(error.developerMessage && {\n developerMessage: normalize(error.developerMessage),\n }),\n ...(error.moreInfo && { moreInfo: error.moreInfo }),\n ...(typeof error.status === 'number' && {\n errorCode: error.status,\n }),\n }\n}\n\n/**\n * Adapts a successful (200 OK) response that represents a semantic\n * failure (`status: FAILED`) into the standard `DprErrorMessage` shape.\n *\n * @param {*} raw\n * @return {*} {DprErrorMessage}\n */\nfunction failedPayloadToDprError(raw: {\n status?: string\n error: string\n errorCategory?: number\n stateChangeReason?: string\n}): DprErrorMessage {\n const { error, stateChangeReason } = raw\n\n return {\n userMessage: 'An unexpected error occurred',\n developerMessage: error,\n ...(stateChangeReason && { moreInfo: stateChangeReason }),\n }\n}\n\n/**\n * ------------------------------------------------------------\n * RESOLVER\n * ------------------------------------------------------------\n */\n\nfunction isTerminal(status?: RequestStatus): boolean {\n return status ? TERMINAL_STATUSES.has(status) : false\n}\n\n/**\n * Decides the authoritative status of a report.\n *\n * @export\n * @param {{\n * stored: StoredReportData\n * parentSignal: UpstreamSignal\n * childSignals: UpstreamSignal[]\n * now: number\n * }} {\n * stored,\n * parentSignal,\n * childSignals,\n * now,\n * }\n * @return {*} {StatusResolution}\n */\nfunction resolveReportStatus({\n stored,\n parentSignal,\n childSignals,\n now,\n}: {\n stored: StoredReportData\n parentSignal: UpstreamSignal\n childSignals: UpstreamSignal[]\n now: number\n}): StatusResolution {\n const currentStatus = stored.status ?? RequestStatus.SUBMITTED\n\n /**\n * ------------------------------------------------------------\n * TERMINAL GUARD\n * ------------------------------------------------------------\n * Once a report is terminal, it never changes again.\n */\n if (isTerminal(currentStatus)) {\n return { type: 'NO_CHANGE' }\n }\n\n /**\n * ------------------------------------------------------------\n * TIMEOUT\n * ------------------------------------------------------------\n * If polling exceeds 15 minutes, we decide it has failed.\n */\n const requestedAt = stored.timestamp?.requested\n if (requestedAt) {\n const requestedTime = new Date(requestedAt).getTime()\n if (now - requestedTime >= FIFTEEN_MINUTES_MS) {\n return {\n type: 'UPDATE',\n newStatus: RequestStatus.FAILED,\n failureInfo: {\n userMessage: 'Report generation timed out',\n developerMessage: 'Polling exceeded 15 minutes',\n },\n }\n }\n }\n\n /**\n * ------------------------------------------------------------\n * API ERROR\n * ------------------------------------------------------------\n * The API failed.\n */\n if (parentSignal.kind === 'ERROR' || childSignals.some((signal) => signal.kind === 'ERROR')) {\n const failure =\n parentSignal.kind === 'ERROR' ? parentSignal.failure : childSignals.find((s) => s.kind === 'ERROR')!.failure\n\n return {\n type: 'UPDATE',\n newStatus: RequestStatus.FAILED,\n failureInfo: failure,\n }\n }\n\n /**\n * ------------------------------------------------------------\n * CHILD AGGREGATION\n * ------------------------------------------------------------\n * Execution identity comes from stored.childExecutionData,\n * execution truth comes from childSignals.\n */\n const childStatuses = childSignals.filter((s) => s.kind === 'STATUS').map((s) => s.status)\n\n if (childStatuses.some((status) => status === RequestStatus.FAILED)) {\n return {\n type: 'UPDATE',\n newStatus: RequestStatus.FAILED,\n }\n }\n\n if (childStatuses.length > 0 && childStatuses.every((status) => status === RequestStatus.FINISHED)) {\n return {\n type: 'UPDATE',\n newStatus: RequestStatus.FINISHED,\n }\n }\n\n /**\n * ------------------------------------------------------------\n * NORMAL STATUS TRANSITION\n * ------------------------------------------------------------\n * Parent progressed (SUBMITTED → STARTED → PICKED → FINISHED)\n */\n if (parentSignal.kind === 'STATUS' && parentSignal.status !== currentStatus) {\n return {\n type: 'UPDATE',\n newStatus: parentSignal.status,\n }\n }\n\n /**\n * ------------------------------------------------------------\n * NOTHING CHANGED\n * ------------------------------------------------------------\n */\n return { type: 'NO_CHANGE' }\n}\n\n/**\n * ------------------------------------------------------------\n * EVALUATE STATUS\n * ------------------------------------------------------------\n */\n\ntype EvaluateReportStatusOptions = {\n stored: StoredReportData\n services: Services\n token: string\n now?: number\n}\n\n/**\n * Evaluates the current authoritative report status.\n */\nasync function evaluateReportStatus({\n stored,\n services,\n token,\n now = Date.now(),\n}: EvaluateReportStatusOptions): Promise<StatusResolution> {\n // 1. Get the status data.\n const { parentSignal, childSignals } = await getStatus({\n stored,\n services,\n token,\n })\n\n // 2. Apply and resolve status rules.\n return resolveReportStatus({\n stored,\n parentSignal,\n childSignals,\n now,\n })\n}\n\n/**\n * Ensures the stored report status is correct.\n */\nexport async function evaluateAndUpdateReportStatus({\n stored,\n services,\n token,\n res,\n}: EvaluateAndUpdateReportStatusOptions): Promise<{\n resolution: StatusResolution\n updated?: RequestedReport\n}> {\n const { dprUser } = getValues(res)\n const { executionId } = stored\n\n if (!executionId) {\n throw new Error('Stored report missing executionId')\n }\n\n const resolution = await evaluateReportStatus({\n stored,\n services,\n token,\n })\n\n if (resolution.type === 'NO_CHANGE') {\n return { resolution }\n }\n\n // Set the error message if any to a string\n const errorMessage = resolution.failureInfo ? JSON.stringify(resolution.failureInfo) : undefined\n\n // Update the status\n await services.requestedReportService.updateStatus(executionId, dprUser.id, resolution.newStatus, errorMessage)\n\n // Get the updated stored state\n const updated = await services.requestedReportService.getReportByExecutionId(executionId, dprUser.id)\n if (!updated) {\n return { resolution }\n }\n\n return {\n resolution,\n updated,\n }\n}\n\n/**\n * ------------------------------------------------------------\n * PREFLIGHT / INITIALISATION\n * ------------------------------------------------------------\n */\n\nasync function detectExpiredFinishedReports({\n reports,\n services,\n token,\n}: {\n reports: StoredReportData[]\n services: Services\n token: string\n}): Promise<\n {\n executionId: string\n }[]\n> {\n const finishedWithTables = reports.filter(\n (r) =>\n (r.status === RequestStatus.FINISHED || r.status === RequestStatus.READY) &&\n Boolean(r.executionId) &&\n Boolean(r.tableId),\n )\n\n if (finishedWithTables.length === 0) {\n return []\n }\n\n // de‑duplicate tableIds for batch lookup\n const tableIds = [...new Set(finishedWithTables.map((r) => r.tableId!))]\n\n const batches = chunkArray(tableIds, 50)\n\n const expiryStates = await batches.reduce<Promise<components['schemas']['ResultTableExpiryState'][]>>(\n async (accPromise, batch) => {\n const acc = await accPromise\n const result = await services.reportingService.getTableExpiryState(token, batch)\n return [...acc, ...result]\n },\n Promise.resolve([]),\n )\n logger.info(`EXPIRED STATES: ${JSON.stringify(expiryStates)}`)\n\n const expiredTableIds = new Set(expiryStates.filter((s) => s.expired).map((s) => s.tableId))\n\n return finishedWithTables.filter((r) => expiredTableIds.has(r.tableId!)).map((r) => ({ executionId: r.executionId! }))\n}\n\nconst chunkArray = <T>(arr: T[], size: number): T[][] =>\n Array.from({ length: Math.ceil(arr.length / size) }, (_, i) => arr.slice(i * size, i * size + size))\n\n/**\n * Checks the expired status of reports and updates the state\n *\n * @export\n * @param {ExpireFinishedReportsOptions} {\n * reports,\n * services,\n * token,\n * res,\n * }\n * @return {*} {Promise<StoredReportData[]>}\n */\nexport async function expireFinishedReports({\n requestedReports,\n recentlyViewedReports,\n services,\n res,\n}: ExpireFinishedReportsOptions): Promise<{\n requestedReports: RequestedReport[]\n recentlyViewedReports: StoredReportData[]\n}> {\n const { dprUser, token } = getValues(res)\n\n const reports = [...requestedReports, ...recentlyViewedReports]\n\n const expired = await detectExpiredFinishedReports({\n reports,\n services,\n token,\n })\n\n if (expired.length === 0) {\n return {\n requestedReports,\n recentlyViewedReports,\n }\n }\n\n // de-duplicate executionIds\n const uniqueExpired = [...new Map(expired.map((e) => [e.executionId, e])).values()]\n logger.info(`EXPIRED STATES: ${JSON.stringify({ uniqueExpired })}`)\n\n // If any expired then update the state\n await uniqueExpired.reduce(async (prev, { executionId }) => {\n await prev\n await services.requestedReportService.setToExpired(executionId, dprUser.id)\n await services.recentlyViewedService.setToExpired(executionId, dprUser.id)\n }, Promise.resolve())\n\n // get a fresh version of all reports\n return getAllMyReports(res, services, dprUser.id)\n}\n\nconst EXPIRED_CHECK_INTERVAL_MS = 30 * 60 * 1000 // 30\n\n/**\n * Checks if the expiry check should run\n *\n * @export\n * @param {*} session\n * @return {*} {boolean}\n */\nexport function shouldRunExpiryCheck(session: { lastExpiredReportsCheckAt?: number }): boolean {\n const lastRun = session.lastExpiredReportsCheckAt\n if (!lastRun) return true\n return Date.now() - lastRun > EXPIRED_CHECK_INTERVAL_MS\n}\n\nexport function recordExpiryCheck(session: { lastExpiredReportsCheckAt?: number }) {\n // eslint-disable-next-line no-param-reassign\n session.lastExpiredReportsCheckAt = Date.now()\n}\n"],"names":["ReportType","RequestStatus","ErrorHandler","TERMINAL_STATUSES","FIFTEEN_MINUTES_MS","getValues","logger","getAllMyReports"],"mappings":"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"}
1
+ {"version":3,"file":"getReportStatus.js","sources":["../../../../../../../../../../src/dpr/utils/ReportStatus/getReportStatus.ts"],"sourcesContent":["import {\n RequestStatus,\n UpstreamSignal,\n StatusResolution,\n FailureInfo,\n EvaluateAndUpdateReportStatusOptions,\n GetReportStatusOptions,\n TERMINAL_STATUSES,\n FIFTEEN_MINUTES_MS,\n ExpireFinishedReportsOptions,\n} from './types'\nimport ErrorHandler, { DprErrorMessage } from '../ErrorHandler/ErrorHandler'\nimport { Services } from '../../types/Services'\nimport { StoredReportData, ReportType, RequestedReport } from '../../types/UserReports'\nimport { getValues } from '../localsHelper'\nimport { getAllMyReports } from '../reportStoreHelper'\nimport { components } from '../../types/api'\nimport logger from '../logger'\n\n/**\n * ------------------------------------------------------------\n * API\n * ------------------------------------------------------------\n */\n\n/**\n * Get the status by report type\n *\n * @param {GetReportStatusOptions} {\n * reportType,\n * services,\n * token,\n * reportId,\n * id,\n * executionId,\n * definitionsPath,\n * tableId,\n * }\n * @return {*} {Promise<UpstreamSignal>}\n */\nasync function getStatusByType({\n reportType,\n services,\n token,\n reportId,\n id,\n executionId,\n definitionsPath,\n tableId,\n}: GetReportStatusOptions): Promise<UpstreamSignal> {\n try {\n const response =\n reportType === ReportType.DASHBOARD\n ? await services.dashboardService.getAsyncStatus(token, reportId, id, executionId, tableId, definitionsPath)\n : await services.reportingService.getAsyncReportStatus(\n token,\n reportId,\n id,\n executionId,\n definitionsPath,\n tableId,\n )\n\n const data = response as {\n status?: string\n error: string\n errorCategory?: number\n stateChangeReason?: string\n }\n\n if (!data.status) {\n return { kind: 'EMPTY' }\n }\n\n if (data.status === RequestStatus.FAILED) {\n const formatted = failedPayloadToDprError(data)\n return {\n kind: 'ERROR',\n failure: toFailureInfo(formatted),\n }\n }\n\n return {\n kind: 'STATUS',\n status: data.status as RequestStatus,\n }\n } catch (error) {\n const formatted = new ErrorHandler(error).formatError()\n\n return {\n kind: 'ERROR',\n failure: toFailureInfo(formatted),\n }\n }\n}\n\n/**\n * ------------------------------------------------------------\n * ORCHESTRATION\n * ------------------------------------------------------------\n */\n\n/**\n * Gets the status for a reports and its child reports\n *\n * @param {{\n * stored: StoredReportData\n * services: Services\n * token: string\n * }} {\n * stored,\n * services,\n * token,\n * }\n * @return {*} {Promise<{\n * parentSignal: UpstreamSignal\n * childSignals: UpstreamSignal[]\n * }>}\n */\nasync function getStatus({\n stored,\n services,\n token,\n}: {\n stored: StoredReportData\n services: Services\n token: string\n}): Promise<{\n parentSignal: UpstreamSignal\n childSignals: UpstreamSignal[]\n}> {\n const { reportId, id, tableId, executionId, dataProductDefinitionsPath } = stored\n const definitionsPath = dataProductDefinitionsPath || ''\n\n if (!executionId || !tableId) {\n throw new Error('Stored report missing executionId or tableId')\n }\n\n const parentSignal = await getStatusByType({\n reportType: stored.type,\n services,\n token,\n reportId,\n id,\n executionId,\n definitionsPath,\n tableId,\n })\n\n const childSignals = stored.childExecutionData\n ? await Promise.all(\n stored.childExecutionData.map((child) => {\n const { tableId: childTableId, executionId: childExecutionId } = child\n\n if (!childExecutionId || !childTableId) {\n throw new Error('Stored child report missing executionId or tableId')\n }\n\n return getStatusByType({\n services,\n reportType: ReportType.REPORT,\n token,\n reportId,\n id,\n executionId: childExecutionId,\n definitionsPath,\n tableId: childTableId,\n })\n }),\n )\n : []\n\n return {\n parentSignal,\n childSignals,\n }\n}\n\n/**\n * Converts a normalized internal error (`DprErrorMessage`) into a `FailureInfo`\n * object that is safe and consistent to store and return to clients.\n *\n * @param {DprErrorMessage} error\n * @return {*} {FailureInfo}\n */\nfunction toFailureInfo(error: DprErrorMessage): FailureInfo {\n const normalize = (msg?: string | string[]): string =>\n Array.isArray(msg) ? msg.join('. ') : msg || 'An unexpected error occurred'\n\n return {\n userMessage: normalize(error.userMessage),\n ...(error.developerMessage && {\n developerMessage: normalize(error.developerMessage),\n }),\n ...(error.moreInfo && { moreInfo: error.moreInfo }),\n ...(typeof error.status === 'number' && {\n errorCode: error.status,\n }),\n }\n}\n\n/**\n * Adapts a successful (200 OK) response that represents a semantic\n * failure (`status: FAILED`) into the standard `DprErrorMessage` shape.\n *\n * @param {*} raw\n * @return {*} {DprErrorMessage}\n */\nfunction failedPayloadToDprError(raw: {\n status?: string\n error: string\n errorCategory?: number\n stateChangeReason?: string\n}): DprErrorMessage {\n const { error, stateChangeReason } = raw\n\n return {\n userMessage: 'An unexpected error occurred',\n developerMessage: error,\n ...(stateChangeReason && { moreInfo: stateChangeReason }),\n }\n}\n\n/**\n * ------------------------------------------------------------\n * RESOLVER\n * ------------------------------------------------------------\n */\n\nfunction isTerminal(status?: RequestStatus): boolean {\n return status ? TERMINAL_STATUSES.has(status) : false\n}\n\n/**\n * Decides the authoritative status of a report.\n *\n * @export\n * @param {{\n * stored: StoredReportData\n * parentSignal: UpstreamSignal\n * childSignals: UpstreamSignal[]\n * now: number\n * }} {\n * stored,\n * parentSignal,\n * childSignals,\n * now,\n * }\n * @return {*} {StatusResolution}\n */\nfunction resolveReportStatus({\n stored,\n parentSignal,\n childSignals,\n now,\n}: {\n stored: StoredReportData\n parentSignal: UpstreamSignal\n childSignals: UpstreamSignal[]\n now: number\n}): StatusResolution {\n const currentStatus = stored.status ?? RequestStatus.SUBMITTED\n\n /**\n * ------------------------------------------------------------\n * TERMINAL GUARD\n * ------------------------------------------------------------\n * Once a report is terminal, it never changes again.\n */\n if (isTerminal(currentStatus)) {\n return { type: 'NO_CHANGE' }\n }\n\n /**\n * ------------------------------------------------------------\n * TIMEOUT\n * ------------------------------------------------------------\n * If polling exceeds 15 minutes, we decide it has failed.\n */\n const requestedAt = stored.timestamp?.requested\n if (requestedAt) {\n const requestedTime = new Date(requestedAt).getTime()\n if (now - requestedTime >= FIFTEEN_MINUTES_MS) {\n return {\n type: 'UPDATE',\n newStatus: RequestStatus.FAILED,\n failureInfo: {\n userMessage: 'Report generation timed out',\n developerMessage: 'Polling exceeded 15 minutes',\n },\n }\n }\n }\n\n /**\n * ------------------------------------------------------------\n * API ERROR\n * ------------------------------------------------------------\n * The API failed.\n */\n if (parentSignal.kind === 'ERROR' || childSignals.some((signal) => signal.kind === 'ERROR')) {\n const failure =\n parentSignal.kind === 'ERROR' ? parentSignal.failure : childSignals.find((s) => s.kind === 'ERROR')!.failure\n\n return {\n type: 'UPDATE',\n newStatus: RequestStatus.FAILED,\n failureInfo: failure,\n }\n }\n\n /**\n * ------------------------------------------------------------\n * CHILD AGGREGATION\n * ------------------------------------------------------------\n * Execution identity comes from stored.childExecutionData,\n * execution truth comes from childSignals.\n */\n const childStatuses = childSignals.filter((s) => s.kind === 'STATUS').map((s) => s.status)\n\n if (childStatuses.some((status) => status === RequestStatus.FAILED)) {\n return {\n type: 'UPDATE',\n newStatus: RequestStatus.FAILED,\n }\n }\n\n if (childStatuses.length > 0 && childStatuses.every((status) => status === RequestStatus.FINISHED)) {\n return {\n type: 'UPDATE',\n newStatus: RequestStatus.FINISHED,\n }\n }\n\n /**\n * ------------------------------------------------------------\n * NORMAL STATUS TRANSITION\n * ------------------------------------------------------------\n * Parent progressed (SUBMITTED → STARTED → PICKED → FINISHED)\n */\n if (parentSignal.kind === 'STATUS' && parentSignal.status !== currentStatus) {\n return {\n type: 'UPDATE',\n newStatus: parentSignal.status,\n }\n }\n\n /**\n * ------------------------------------------------------------\n * NOTHING CHANGED\n * ------------------------------------------------------------\n */\n return { type: 'NO_CHANGE' }\n}\n\n/**\n * ------------------------------------------------------------\n * EVALUATE STATUS\n * ------------------------------------------------------------\n */\n\ntype EvaluateReportStatusOptions = {\n stored: StoredReportData\n services: Services\n token: string\n now?: number\n}\n\n/**\n * Evaluates the current authoritative report status.\n */\nasync function evaluateReportStatus({\n stored,\n services,\n token,\n now = Date.now(),\n}: EvaluateReportStatusOptions): Promise<StatusResolution> {\n // 1. Get the status data.\n const { parentSignal, childSignals } = await getStatus({\n stored,\n services,\n token,\n })\n\n // 2. Apply and resolve status rules.\n return resolveReportStatus({\n stored,\n parentSignal,\n childSignals,\n now,\n })\n}\n\n/**\n * Ensures the stored report status is correct.\n */\nexport async function evaluateAndUpdateReportStatus({\n stored,\n services,\n token,\n res,\n}: EvaluateAndUpdateReportStatusOptions): Promise<{\n resolution: StatusResolution\n updated?: RequestedReport\n}> {\n const { dprUser } = getValues(res)\n const { executionId } = stored\n\n if (!executionId) {\n throw new Error('Stored report missing executionId')\n }\n\n const resolution = await evaluateReportStatus({\n stored,\n services,\n token,\n })\n\n if (resolution.type === 'NO_CHANGE') {\n return { resolution }\n }\n\n // Set the error message if any to a string\n const errorMessage = resolution.failureInfo ? JSON.stringify(resolution.failureInfo) : undefined\n\n // Update the status\n await services.requestedReportService.updateStatus(executionId, dprUser.id, resolution.newStatus, errorMessage)\n\n // Get the updated stored state\n const updated = await services.requestedReportService.getReportByExecutionId(executionId, dprUser.id)\n if (!updated) {\n return { resolution }\n }\n\n return {\n resolution,\n updated,\n }\n}\n\n/**\n * ------------------------------------------------------------\n * PREFLIGHT / INITIALISATION\n * ------------------------------------------------------------\n */\n\nasync function detectExpiredFinishedReports({\n reports,\n services,\n token,\n}: {\n reports: StoredReportData[]\n services: Services\n token: string\n}): Promise<\n {\n executionId: string\n }[]\n> {\n const finishedWithTables = reports.filter(\n (r) =>\n (r.status === RequestStatus.FINISHED || r.status === RequestStatus.READY) &&\n Boolean(r.executionId) &&\n Boolean(r.tableId),\n )\n\n if (finishedWithTables.length === 0) {\n return []\n }\n\n // de‑duplicate tableIds for batch lookup\n const tableIds = [...new Set(finishedWithTables.map((r) => r.tableId!))]\n\n const batches = chunkArray(tableIds, 200)\n\n const expiryStates = await batches.reduce<Promise<components['schemas']['ResultTableExpiryState'][]>>(\n async (accPromise, batch) => {\n const acc = await accPromise\n const result = await services.reportingService.getTableExpiryState(token, batch)\n return [...acc, ...result]\n },\n Promise.resolve([]),\n )\n logger.info(`EXPIRED STATES: ${JSON.stringify(expiryStates)}`)\n\n const expiredTableIds = new Set(expiryStates.filter((s) => s.expired).map((s) => s.tableId))\n\n return finishedWithTables.filter((r) => expiredTableIds.has(r.tableId!)).map((r) => ({ executionId: r.executionId! }))\n}\n\nconst chunkArray = <T>(arr: T[], size: number): T[][] =>\n Array.from({ length: Math.ceil(arr.length / size) }, (_, i) => arr.slice(i * size, i * size + size))\n\n/**\n * Checks the expired status of reports and updates the state\n *\n * @export\n * @param {ExpireFinishedReportsOptions} {\n * reports,\n * services,\n * token,\n * res,\n * }\n * @return {*} {Promise<StoredReportData[]>}\n */\nexport async function expireFinishedReports({\n requestedReports,\n recentlyViewedReports,\n services,\n res,\n}: ExpireFinishedReportsOptions): Promise<{\n requestedReports: RequestedReport[]\n recentlyViewedReports: StoredReportData[]\n}> {\n const { dprUser, token } = getValues(res)\n\n const reports = [...requestedReports, ...recentlyViewedReports]\n\n const expired = await detectExpiredFinishedReports({\n reports,\n services,\n token,\n })\n\n if (expired.length === 0) {\n return {\n requestedReports,\n recentlyViewedReports,\n }\n }\n\n // de-duplicate executionIds\n const uniqueExpired = [...new Map(expired.map((e) => [e.executionId, e])).values()]\n logger.info(`EXPIRED STATES: ${JSON.stringify({ uniqueExpired })}`)\n\n // If any expired then update the state\n await uniqueExpired.reduce(async (prev, { executionId }) => {\n await prev\n await services.requestedReportService.setToExpired(executionId, dprUser.id)\n await services.recentlyViewedService.setToExpired(executionId, dprUser.id)\n }, Promise.resolve())\n\n // get a fresh version of all reports\n return getAllMyReports(res, services, dprUser.id)\n}\n\nconst EXPIRED_CHECK_INTERVAL_MS = 30 * 60 * 1000 // 30\n\n/**\n * Checks if the expiry check should run\n *\n * @export\n * @param {*} session\n * @return {*} {boolean}\n */\nexport function shouldRunExpiryCheck(session: { lastExpiredReportsCheckAt?: number }): boolean {\n const lastRun = session.lastExpiredReportsCheckAt\n if (!lastRun) return true\n return Date.now() - lastRun > EXPIRED_CHECK_INTERVAL_MS\n}\n\nexport function recordExpiryCheck(session: { lastExpiredReportsCheckAt?: number }) {\n // eslint-disable-next-line no-param-reassign\n session.lastExpiredReportsCheckAt = Date.now()\n}\n"],"names":["ReportType","RequestStatus","ErrorHandler","TERMINAL_STATUSES","FIFTEEN_MINUTES_MS","getValues","logger","getAllMyReports"],"mappings":"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"}
@@ -322,7 +322,7 @@ async function detectExpiredFinishedReports({ reports, services, token, }) {
322
322
  }
323
323
  // de‑duplicate tableIds for batch lookup
324
324
  const tableIds = [...new Set(finishedWithTables.map((r) => r.tableId))];
325
- const batches = chunkArray(tableIds, 50);
325
+ const batches = chunkArray(tableIds, 200);
326
326
  const expiryStates = await batches.reduce(async (accPromise, batch) => {
327
327
  const acc = await accPromise;
328
328
  const result = await services.reportingService.getTableExpiryState(token, batch);
@@ -1 +1 @@
1
- {"version":3,"file":"getReportStatus.js","sources":["../../../../../../../../../src/dpr/utils/ReportStatus/getReportStatus.ts"],"sourcesContent":["import {\n RequestStatus,\n UpstreamSignal,\n StatusResolution,\n FailureInfo,\n EvaluateAndUpdateReportStatusOptions,\n GetReportStatusOptions,\n TERMINAL_STATUSES,\n FIFTEEN_MINUTES_MS,\n ExpireFinishedReportsOptions,\n} from './types'\nimport ErrorHandler, { DprErrorMessage } from '../ErrorHandler/ErrorHandler'\nimport { Services } from '../../types/Services'\nimport { StoredReportData, ReportType, RequestedReport } from '../../types/UserReports'\nimport { getValues } from '../localsHelper'\nimport { getAllMyReports } from '../reportStoreHelper'\nimport { components } from '../../types/api'\nimport logger from '../logger'\n\n/**\n * ------------------------------------------------------------\n * API\n * ------------------------------------------------------------\n */\n\n/**\n * Get the status by report type\n *\n * @param {GetReportStatusOptions} {\n * reportType,\n * services,\n * token,\n * reportId,\n * id,\n * executionId,\n * definitionsPath,\n * tableId,\n * }\n * @return {*} {Promise<UpstreamSignal>}\n */\nasync function getStatusByType({\n reportType,\n services,\n token,\n reportId,\n id,\n executionId,\n definitionsPath,\n tableId,\n}: GetReportStatusOptions): Promise<UpstreamSignal> {\n try {\n const response =\n reportType === ReportType.DASHBOARD\n ? await services.dashboardService.getAsyncStatus(token, reportId, id, executionId, tableId, definitionsPath)\n : await services.reportingService.getAsyncReportStatus(\n token,\n reportId,\n id,\n executionId,\n definitionsPath,\n tableId,\n )\n\n const data = response as {\n status?: string\n error: string\n errorCategory?: number\n stateChangeReason?: string\n }\n\n if (!data.status) {\n return { kind: 'EMPTY' }\n }\n\n if (data.status === RequestStatus.FAILED) {\n const formatted = failedPayloadToDprError(data)\n return {\n kind: 'ERROR',\n failure: toFailureInfo(formatted),\n }\n }\n\n return {\n kind: 'STATUS',\n status: data.status as RequestStatus,\n }\n } catch (error) {\n const formatted = new ErrorHandler(error).formatError()\n\n return {\n kind: 'ERROR',\n failure: toFailureInfo(formatted),\n }\n }\n}\n\n/**\n * ------------------------------------------------------------\n * ORCHESTRATION\n * ------------------------------------------------------------\n */\n\n/**\n * Gets the status for a reports and its child reports\n *\n * @param {{\n * stored: StoredReportData\n * services: Services\n * token: string\n * }} {\n * stored,\n * services,\n * token,\n * }\n * @return {*} {Promise<{\n * parentSignal: UpstreamSignal\n * childSignals: UpstreamSignal[]\n * }>}\n */\nasync function getStatus({\n stored,\n services,\n token,\n}: {\n stored: StoredReportData\n services: Services\n token: string\n}): Promise<{\n parentSignal: UpstreamSignal\n childSignals: UpstreamSignal[]\n}> {\n const { reportId, id, tableId, executionId, dataProductDefinitionsPath } = stored\n const definitionsPath = dataProductDefinitionsPath || ''\n\n if (!executionId || !tableId) {\n throw new Error('Stored report missing executionId or tableId')\n }\n\n const parentSignal = await getStatusByType({\n reportType: stored.type,\n services,\n token,\n reportId,\n id,\n executionId,\n definitionsPath,\n tableId,\n })\n\n const childSignals = stored.childExecutionData\n ? await Promise.all(\n stored.childExecutionData.map((child) => {\n const { tableId: childTableId, executionId: childExecutionId } = child\n\n if (!childExecutionId || !childTableId) {\n throw new Error('Stored child report missing executionId or tableId')\n }\n\n return getStatusByType({\n services,\n reportType: ReportType.REPORT,\n token,\n reportId,\n id,\n executionId: childExecutionId,\n definitionsPath,\n tableId: childTableId,\n })\n }),\n )\n : []\n\n return {\n parentSignal,\n childSignals,\n }\n}\n\n/**\n * Converts a normalized internal error (`DprErrorMessage`) into a `FailureInfo`\n * object that is safe and consistent to store and return to clients.\n *\n * @param {DprErrorMessage} error\n * @return {*} {FailureInfo}\n */\nfunction toFailureInfo(error: DprErrorMessage): FailureInfo {\n const normalize = (msg?: string | string[]): string =>\n Array.isArray(msg) ? msg.join('. ') : msg || 'An unexpected error occurred'\n\n return {\n userMessage: normalize(error.userMessage),\n ...(error.developerMessage && {\n developerMessage: normalize(error.developerMessage),\n }),\n ...(error.moreInfo && { moreInfo: error.moreInfo }),\n ...(typeof error.status === 'number' && {\n errorCode: error.status,\n }),\n }\n}\n\n/**\n * Adapts a successful (200 OK) response that represents a semantic\n * failure (`status: FAILED`) into the standard `DprErrorMessage` shape.\n *\n * @param {*} raw\n * @return {*} {DprErrorMessage}\n */\nfunction failedPayloadToDprError(raw: {\n status?: string\n error: string\n errorCategory?: number\n stateChangeReason?: string\n}): DprErrorMessage {\n const { error, stateChangeReason } = raw\n\n return {\n userMessage: 'An unexpected error occurred',\n developerMessage: error,\n ...(stateChangeReason && { moreInfo: stateChangeReason }),\n }\n}\n\n/**\n * ------------------------------------------------------------\n * RESOLVER\n * ------------------------------------------------------------\n */\n\nfunction isTerminal(status?: RequestStatus): boolean {\n return status ? TERMINAL_STATUSES.has(status) : false\n}\n\n/**\n * Decides the authoritative status of a report.\n *\n * @export\n * @param {{\n * stored: StoredReportData\n * parentSignal: UpstreamSignal\n * childSignals: UpstreamSignal[]\n * now: number\n * }} {\n * stored,\n * parentSignal,\n * childSignals,\n * now,\n * }\n * @return {*} {StatusResolution}\n */\nfunction resolveReportStatus({\n stored,\n parentSignal,\n childSignals,\n now,\n}: {\n stored: StoredReportData\n parentSignal: UpstreamSignal\n childSignals: UpstreamSignal[]\n now: number\n}): StatusResolution {\n const currentStatus = stored.status ?? RequestStatus.SUBMITTED\n\n /**\n * ------------------------------------------------------------\n * TERMINAL GUARD\n * ------------------------------------------------------------\n * Once a report is terminal, it never changes again.\n */\n if (isTerminal(currentStatus)) {\n return { type: 'NO_CHANGE' }\n }\n\n /**\n * ------------------------------------------------------------\n * TIMEOUT\n * ------------------------------------------------------------\n * If polling exceeds 15 minutes, we decide it has failed.\n */\n const requestedAt = stored.timestamp?.requested\n if (requestedAt) {\n const requestedTime = new Date(requestedAt).getTime()\n if (now - requestedTime >= FIFTEEN_MINUTES_MS) {\n return {\n type: 'UPDATE',\n newStatus: RequestStatus.FAILED,\n failureInfo: {\n userMessage: 'Report generation timed out',\n developerMessage: 'Polling exceeded 15 minutes',\n },\n }\n }\n }\n\n /**\n * ------------------------------------------------------------\n * API ERROR\n * ------------------------------------------------------------\n * The API failed.\n */\n if (parentSignal.kind === 'ERROR' || childSignals.some((signal) => signal.kind === 'ERROR')) {\n const failure =\n parentSignal.kind === 'ERROR' ? parentSignal.failure : childSignals.find((s) => s.kind === 'ERROR')!.failure\n\n return {\n type: 'UPDATE',\n newStatus: RequestStatus.FAILED,\n failureInfo: failure,\n }\n }\n\n /**\n * ------------------------------------------------------------\n * CHILD AGGREGATION\n * ------------------------------------------------------------\n * Execution identity comes from stored.childExecutionData,\n * execution truth comes from childSignals.\n */\n const childStatuses = childSignals.filter((s) => s.kind === 'STATUS').map((s) => s.status)\n\n if (childStatuses.some((status) => status === RequestStatus.FAILED)) {\n return {\n type: 'UPDATE',\n newStatus: RequestStatus.FAILED,\n }\n }\n\n if (childStatuses.length > 0 && childStatuses.every((status) => status === RequestStatus.FINISHED)) {\n return {\n type: 'UPDATE',\n newStatus: RequestStatus.FINISHED,\n }\n }\n\n /**\n * ------------------------------------------------------------\n * NORMAL STATUS TRANSITION\n * ------------------------------------------------------------\n * Parent progressed (SUBMITTED → STARTED → PICKED → FINISHED)\n */\n if (parentSignal.kind === 'STATUS' && parentSignal.status !== currentStatus) {\n return {\n type: 'UPDATE',\n newStatus: parentSignal.status,\n }\n }\n\n /**\n * ------------------------------------------------------------\n * NOTHING CHANGED\n * ------------------------------------------------------------\n */\n return { type: 'NO_CHANGE' }\n}\n\n/**\n * ------------------------------------------------------------\n * EVALUATE STATUS\n * ------------------------------------------------------------\n */\n\ntype EvaluateReportStatusOptions = {\n stored: StoredReportData\n services: Services\n token: string\n now?: number\n}\n\n/**\n * Evaluates the current authoritative report status.\n */\nasync function evaluateReportStatus({\n stored,\n services,\n token,\n now = Date.now(),\n}: EvaluateReportStatusOptions): Promise<StatusResolution> {\n // 1. Get the status data.\n const { parentSignal, childSignals } = await getStatus({\n stored,\n services,\n token,\n })\n\n // 2. Apply and resolve status rules.\n return resolveReportStatus({\n stored,\n parentSignal,\n childSignals,\n now,\n })\n}\n\n/**\n * Ensures the stored report status is correct.\n */\nexport async function evaluateAndUpdateReportStatus({\n stored,\n services,\n token,\n res,\n}: EvaluateAndUpdateReportStatusOptions): Promise<{\n resolution: StatusResolution\n updated?: RequestedReport\n}> {\n const { dprUser } = getValues(res)\n const { executionId } = stored\n\n if (!executionId) {\n throw new Error('Stored report missing executionId')\n }\n\n const resolution = await evaluateReportStatus({\n stored,\n services,\n token,\n })\n\n if (resolution.type === 'NO_CHANGE') {\n return { resolution }\n }\n\n // Set the error message if any to a string\n const errorMessage = resolution.failureInfo ? JSON.stringify(resolution.failureInfo) : undefined\n\n // Update the status\n await services.requestedReportService.updateStatus(executionId, dprUser.id, resolution.newStatus, errorMessage)\n\n // Get the updated stored state\n const updated = await services.requestedReportService.getReportByExecutionId(executionId, dprUser.id)\n if (!updated) {\n return { resolution }\n }\n\n return {\n resolution,\n updated,\n }\n}\n\n/**\n * ------------------------------------------------------------\n * PREFLIGHT / INITIALISATION\n * ------------------------------------------------------------\n */\n\nasync function detectExpiredFinishedReports({\n reports,\n services,\n token,\n}: {\n reports: StoredReportData[]\n services: Services\n token: string\n}): Promise<\n {\n executionId: string\n }[]\n> {\n const finishedWithTables = reports.filter(\n (r) =>\n (r.status === RequestStatus.FINISHED || r.status === RequestStatus.READY) &&\n Boolean(r.executionId) &&\n Boolean(r.tableId),\n )\n\n if (finishedWithTables.length === 0) {\n return []\n }\n\n // de‑duplicate tableIds for batch lookup\n const tableIds = [...new Set(finishedWithTables.map((r) => r.tableId!))]\n\n const batches = chunkArray(tableIds, 50)\n\n const expiryStates = await batches.reduce<Promise<components['schemas']['ResultTableExpiryState'][]>>(\n async (accPromise, batch) => {\n const acc = await accPromise\n const result = await services.reportingService.getTableExpiryState(token, batch)\n return [...acc, ...result]\n },\n Promise.resolve([]),\n )\n logger.info(`EXPIRED STATES: ${JSON.stringify(expiryStates)}`)\n\n const expiredTableIds = new Set(expiryStates.filter((s) => s.expired).map((s) => s.tableId))\n\n return finishedWithTables.filter((r) => expiredTableIds.has(r.tableId!)).map((r) => ({ executionId: r.executionId! }))\n}\n\nconst chunkArray = <T>(arr: T[], size: number): T[][] =>\n Array.from({ length: Math.ceil(arr.length / size) }, (_, i) => arr.slice(i * size, i * size + size))\n\n/**\n * Checks the expired status of reports and updates the state\n *\n * @export\n * @param {ExpireFinishedReportsOptions} {\n * reports,\n * services,\n * token,\n * res,\n * }\n * @return {*} {Promise<StoredReportData[]>}\n */\nexport async function expireFinishedReports({\n requestedReports,\n recentlyViewedReports,\n services,\n res,\n}: ExpireFinishedReportsOptions): Promise<{\n requestedReports: RequestedReport[]\n recentlyViewedReports: StoredReportData[]\n}> {\n const { dprUser, token } = getValues(res)\n\n const reports = [...requestedReports, ...recentlyViewedReports]\n\n const expired = await detectExpiredFinishedReports({\n reports,\n services,\n token,\n })\n\n if (expired.length === 0) {\n return {\n requestedReports,\n recentlyViewedReports,\n }\n }\n\n // de-duplicate executionIds\n const uniqueExpired = [...new Map(expired.map((e) => [e.executionId, e])).values()]\n logger.info(`EXPIRED STATES: ${JSON.stringify({ uniqueExpired })}`)\n\n // If any expired then update the state\n await uniqueExpired.reduce(async (prev, { executionId }) => {\n await prev\n await services.requestedReportService.setToExpired(executionId, dprUser.id)\n await services.recentlyViewedService.setToExpired(executionId, dprUser.id)\n }, Promise.resolve())\n\n // get a fresh version of all reports\n return getAllMyReports(res, services, dprUser.id)\n}\n\nconst EXPIRED_CHECK_INTERVAL_MS = 30 * 60 * 1000 // 30\n\n/**\n * Checks if the expiry check should run\n *\n * @export\n * @param {*} session\n * @return {*} {boolean}\n */\nexport function shouldRunExpiryCheck(session: { lastExpiredReportsCheckAt?: number }): boolean {\n const lastRun = session.lastExpiredReportsCheckAt\n if (!lastRun) return true\n return Date.now() - lastRun > EXPIRED_CHECK_INTERVAL_MS\n}\n\nexport function recordExpiryCheck(session: { lastExpiredReportsCheckAt?: number }) {\n // eslint-disable-next-line no-param-reassign\n session.lastExpiredReportsCheckAt = Date.now()\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"getReportStatus.js","sources":["../../../../../../../../../src/dpr/utils/ReportStatus/getReportStatus.ts"],"sourcesContent":["import {\n RequestStatus,\n UpstreamSignal,\n StatusResolution,\n FailureInfo,\n EvaluateAndUpdateReportStatusOptions,\n GetReportStatusOptions,\n TERMINAL_STATUSES,\n FIFTEEN_MINUTES_MS,\n ExpireFinishedReportsOptions,\n} from './types'\nimport ErrorHandler, { DprErrorMessage } from '../ErrorHandler/ErrorHandler'\nimport { Services } from '../../types/Services'\nimport { StoredReportData, ReportType, RequestedReport } from '../../types/UserReports'\nimport { getValues } from '../localsHelper'\nimport { getAllMyReports } from '../reportStoreHelper'\nimport { components } from '../../types/api'\nimport logger from '../logger'\n\n/**\n * ------------------------------------------------------------\n * API\n * ------------------------------------------------------------\n */\n\n/**\n * Get the status by report type\n *\n * @param {GetReportStatusOptions} {\n * reportType,\n * services,\n * token,\n * reportId,\n * id,\n * executionId,\n * definitionsPath,\n * tableId,\n * }\n * @return {*} {Promise<UpstreamSignal>}\n */\nasync function getStatusByType({\n reportType,\n services,\n token,\n reportId,\n id,\n executionId,\n definitionsPath,\n tableId,\n}: GetReportStatusOptions): Promise<UpstreamSignal> {\n try {\n const response =\n reportType === ReportType.DASHBOARD\n ? await services.dashboardService.getAsyncStatus(token, reportId, id, executionId, tableId, definitionsPath)\n : await services.reportingService.getAsyncReportStatus(\n token,\n reportId,\n id,\n executionId,\n definitionsPath,\n tableId,\n )\n\n const data = response as {\n status?: string\n error: string\n errorCategory?: number\n stateChangeReason?: string\n }\n\n if (!data.status) {\n return { kind: 'EMPTY' }\n }\n\n if (data.status === RequestStatus.FAILED) {\n const formatted = failedPayloadToDprError(data)\n return {\n kind: 'ERROR',\n failure: toFailureInfo(formatted),\n }\n }\n\n return {\n kind: 'STATUS',\n status: data.status as RequestStatus,\n }\n } catch (error) {\n const formatted = new ErrorHandler(error).formatError()\n\n return {\n kind: 'ERROR',\n failure: toFailureInfo(formatted),\n }\n }\n}\n\n/**\n * ------------------------------------------------------------\n * ORCHESTRATION\n * ------------------------------------------------------------\n */\n\n/**\n * Gets the status for a reports and its child reports\n *\n * @param {{\n * stored: StoredReportData\n * services: Services\n * token: string\n * }} {\n * stored,\n * services,\n * token,\n * }\n * @return {*} {Promise<{\n * parentSignal: UpstreamSignal\n * childSignals: UpstreamSignal[]\n * }>}\n */\nasync function getStatus({\n stored,\n services,\n token,\n}: {\n stored: StoredReportData\n services: Services\n token: string\n}): Promise<{\n parentSignal: UpstreamSignal\n childSignals: UpstreamSignal[]\n}> {\n const { reportId, id, tableId, executionId, dataProductDefinitionsPath } = stored\n const definitionsPath = dataProductDefinitionsPath || ''\n\n if (!executionId || !tableId) {\n throw new Error('Stored report missing executionId or tableId')\n }\n\n const parentSignal = await getStatusByType({\n reportType: stored.type,\n services,\n token,\n reportId,\n id,\n executionId,\n definitionsPath,\n tableId,\n })\n\n const childSignals = stored.childExecutionData\n ? await Promise.all(\n stored.childExecutionData.map((child) => {\n const { tableId: childTableId, executionId: childExecutionId } = child\n\n if (!childExecutionId || !childTableId) {\n throw new Error('Stored child report missing executionId or tableId')\n }\n\n return getStatusByType({\n services,\n reportType: ReportType.REPORT,\n token,\n reportId,\n id,\n executionId: childExecutionId,\n definitionsPath,\n tableId: childTableId,\n })\n }),\n )\n : []\n\n return {\n parentSignal,\n childSignals,\n }\n}\n\n/**\n * Converts a normalized internal error (`DprErrorMessage`) into a `FailureInfo`\n * object that is safe and consistent to store and return to clients.\n *\n * @param {DprErrorMessage} error\n * @return {*} {FailureInfo}\n */\nfunction toFailureInfo(error: DprErrorMessage): FailureInfo {\n const normalize = (msg?: string | string[]): string =>\n Array.isArray(msg) ? msg.join('. ') : msg || 'An unexpected error occurred'\n\n return {\n userMessage: normalize(error.userMessage),\n ...(error.developerMessage && {\n developerMessage: normalize(error.developerMessage),\n }),\n ...(error.moreInfo && { moreInfo: error.moreInfo }),\n ...(typeof error.status === 'number' && {\n errorCode: error.status,\n }),\n }\n}\n\n/**\n * Adapts a successful (200 OK) response that represents a semantic\n * failure (`status: FAILED`) into the standard `DprErrorMessage` shape.\n *\n * @param {*} raw\n * @return {*} {DprErrorMessage}\n */\nfunction failedPayloadToDprError(raw: {\n status?: string\n error: string\n errorCategory?: number\n stateChangeReason?: string\n}): DprErrorMessage {\n const { error, stateChangeReason } = raw\n\n return {\n userMessage: 'An unexpected error occurred',\n developerMessage: error,\n ...(stateChangeReason && { moreInfo: stateChangeReason }),\n }\n}\n\n/**\n * ------------------------------------------------------------\n * RESOLVER\n * ------------------------------------------------------------\n */\n\nfunction isTerminal(status?: RequestStatus): boolean {\n return status ? TERMINAL_STATUSES.has(status) : false\n}\n\n/**\n * Decides the authoritative status of a report.\n *\n * @export\n * @param {{\n * stored: StoredReportData\n * parentSignal: UpstreamSignal\n * childSignals: UpstreamSignal[]\n * now: number\n * }} {\n * stored,\n * parentSignal,\n * childSignals,\n * now,\n * }\n * @return {*} {StatusResolution}\n */\nfunction resolveReportStatus({\n stored,\n parentSignal,\n childSignals,\n now,\n}: {\n stored: StoredReportData\n parentSignal: UpstreamSignal\n childSignals: UpstreamSignal[]\n now: number\n}): StatusResolution {\n const currentStatus = stored.status ?? RequestStatus.SUBMITTED\n\n /**\n * ------------------------------------------------------------\n * TERMINAL GUARD\n * ------------------------------------------------------------\n * Once a report is terminal, it never changes again.\n */\n if (isTerminal(currentStatus)) {\n return { type: 'NO_CHANGE' }\n }\n\n /**\n * ------------------------------------------------------------\n * TIMEOUT\n * ------------------------------------------------------------\n * If polling exceeds 15 minutes, we decide it has failed.\n */\n const requestedAt = stored.timestamp?.requested\n if (requestedAt) {\n const requestedTime = new Date(requestedAt).getTime()\n if (now - requestedTime >= FIFTEEN_MINUTES_MS) {\n return {\n type: 'UPDATE',\n newStatus: RequestStatus.FAILED,\n failureInfo: {\n userMessage: 'Report generation timed out',\n developerMessage: 'Polling exceeded 15 minutes',\n },\n }\n }\n }\n\n /**\n * ------------------------------------------------------------\n * API ERROR\n * ------------------------------------------------------------\n * The API failed.\n */\n if (parentSignal.kind === 'ERROR' || childSignals.some((signal) => signal.kind === 'ERROR')) {\n const failure =\n parentSignal.kind === 'ERROR' ? parentSignal.failure : childSignals.find((s) => s.kind === 'ERROR')!.failure\n\n return {\n type: 'UPDATE',\n newStatus: RequestStatus.FAILED,\n failureInfo: failure,\n }\n }\n\n /**\n * ------------------------------------------------------------\n * CHILD AGGREGATION\n * ------------------------------------------------------------\n * Execution identity comes from stored.childExecutionData,\n * execution truth comes from childSignals.\n */\n const childStatuses = childSignals.filter((s) => s.kind === 'STATUS').map((s) => s.status)\n\n if (childStatuses.some((status) => status === RequestStatus.FAILED)) {\n return {\n type: 'UPDATE',\n newStatus: RequestStatus.FAILED,\n }\n }\n\n if (childStatuses.length > 0 && childStatuses.every((status) => status === RequestStatus.FINISHED)) {\n return {\n type: 'UPDATE',\n newStatus: RequestStatus.FINISHED,\n }\n }\n\n /**\n * ------------------------------------------------------------\n * NORMAL STATUS TRANSITION\n * ------------------------------------------------------------\n * Parent progressed (SUBMITTED → STARTED → PICKED → FINISHED)\n */\n if (parentSignal.kind === 'STATUS' && parentSignal.status !== currentStatus) {\n return {\n type: 'UPDATE',\n newStatus: parentSignal.status,\n }\n }\n\n /**\n * ------------------------------------------------------------\n * NOTHING CHANGED\n * ------------------------------------------------------------\n */\n return { type: 'NO_CHANGE' }\n}\n\n/**\n * ------------------------------------------------------------\n * EVALUATE STATUS\n * ------------------------------------------------------------\n */\n\ntype EvaluateReportStatusOptions = {\n stored: StoredReportData\n services: Services\n token: string\n now?: number\n}\n\n/**\n * Evaluates the current authoritative report status.\n */\nasync function evaluateReportStatus({\n stored,\n services,\n token,\n now = Date.now(),\n}: EvaluateReportStatusOptions): Promise<StatusResolution> {\n // 1. Get the status data.\n const { parentSignal, childSignals } = await getStatus({\n stored,\n services,\n token,\n })\n\n // 2. Apply and resolve status rules.\n return resolveReportStatus({\n stored,\n parentSignal,\n childSignals,\n now,\n })\n}\n\n/**\n * Ensures the stored report status is correct.\n */\nexport async function evaluateAndUpdateReportStatus({\n stored,\n services,\n token,\n res,\n}: EvaluateAndUpdateReportStatusOptions): Promise<{\n resolution: StatusResolution\n updated?: RequestedReport\n}> {\n const { dprUser } = getValues(res)\n const { executionId } = stored\n\n if (!executionId) {\n throw new Error('Stored report missing executionId')\n }\n\n const resolution = await evaluateReportStatus({\n stored,\n services,\n token,\n })\n\n if (resolution.type === 'NO_CHANGE') {\n return { resolution }\n }\n\n // Set the error message if any to a string\n const errorMessage = resolution.failureInfo ? JSON.stringify(resolution.failureInfo) : undefined\n\n // Update the status\n await services.requestedReportService.updateStatus(executionId, dprUser.id, resolution.newStatus, errorMessage)\n\n // Get the updated stored state\n const updated = await services.requestedReportService.getReportByExecutionId(executionId, dprUser.id)\n if (!updated) {\n return { resolution }\n }\n\n return {\n resolution,\n updated,\n }\n}\n\n/**\n * ------------------------------------------------------------\n * PREFLIGHT / INITIALISATION\n * ------------------------------------------------------------\n */\n\nasync function detectExpiredFinishedReports({\n reports,\n services,\n token,\n}: {\n reports: StoredReportData[]\n services: Services\n token: string\n}): Promise<\n {\n executionId: string\n }[]\n> {\n const finishedWithTables = reports.filter(\n (r) =>\n (r.status === RequestStatus.FINISHED || r.status === RequestStatus.READY) &&\n Boolean(r.executionId) &&\n Boolean(r.tableId),\n )\n\n if (finishedWithTables.length === 0) {\n return []\n }\n\n // de‑duplicate tableIds for batch lookup\n const tableIds = [...new Set(finishedWithTables.map((r) => r.tableId!))]\n\n const batches = chunkArray(tableIds, 200)\n\n const expiryStates = await batches.reduce<Promise<components['schemas']['ResultTableExpiryState'][]>>(\n async (accPromise, batch) => {\n const acc = await accPromise\n const result = await services.reportingService.getTableExpiryState(token, batch)\n return [...acc, ...result]\n },\n Promise.resolve([]),\n )\n logger.info(`EXPIRED STATES: ${JSON.stringify(expiryStates)}`)\n\n const expiredTableIds = new Set(expiryStates.filter((s) => s.expired).map((s) => s.tableId))\n\n return finishedWithTables.filter((r) => expiredTableIds.has(r.tableId!)).map((r) => ({ executionId: r.executionId! }))\n}\n\nconst chunkArray = <T>(arr: T[], size: number): T[][] =>\n Array.from({ length: Math.ceil(arr.length / size) }, (_, i) => arr.slice(i * size, i * size + size))\n\n/**\n * Checks the expired status of reports and updates the state\n *\n * @export\n * @param {ExpireFinishedReportsOptions} {\n * reports,\n * services,\n * token,\n * res,\n * }\n * @return {*} {Promise<StoredReportData[]>}\n */\nexport async function expireFinishedReports({\n requestedReports,\n recentlyViewedReports,\n services,\n res,\n}: ExpireFinishedReportsOptions): Promise<{\n requestedReports: RequestedReport[]\n recentlyViewedReports: StoredReportData[]\n}> {\n const { dprUser, token } = getValues(res)\n\n const reports = [...requestedReports, ...recentlyViewedReports]\n\n const expired = await detectExpiredFinishedReports({\n reports,\n services,\n token,\n })\n\n if (expired.length === 0) {\n return {\n requestedReports,\n recentlyViewedReports,\n }\n }\n\n // de-duplicate executionIds\n const uniqueExpired = [...new Map(expired.map((e) => [e.executionId, e])).values()]\n logger.info(`EXPIRED STATES: ${JSON.stringify({ uniqueExpired })}`)\n\n // If any expired then update the state\n await uniqueExpired.reduce(async (prev, { executionId }) => {\n await prev\n await services.requestedReportService.setToExpired(executionId, dprUser.id)\n await services.recentlyViewedService.setToExpired(executionId, dprUser.id)\n }, Promise.resolve())\n\n // get a fresh version of all reports\n return getAllMyReports(res, services, dprUser.id)\n}\n\nconst EXPIRED_CHECK_INTERVAL_MS = 30 * 60 * 1000 // 30\n\n/**\n * Checks if the expiry check should run\n *\n * @export\n * @param {*} session\n * @return {*} {boolean}\n */\nexport function shouldRunExpiryCheck(session: { lastExpiredReportsCheckAt?: number }): boolean {\n const lastRun = session.lastExpiredReportsCheckAt\n if (!lastRun) return true\n return Date.now() - lastRun > EXPIRED_CHECK_INTERVAL_MS\n}\n\nexport function recordExpiryCheck(session: { lastExpiredReportsCheckAt?: number }) {\n // eslint-disable-next-line no-param-reassign\n session.lastExpiredReportsCheckAt = Date.now()\n}\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ministryofjustice/hmpps-digital-prison-reporting-frontend",
3
- "version": "6.6.2",
3
+ "version": "6.6.3",
4
4
  "description": "The Digital Prison Reporting Frontend contains templates and code to help display data effectively in UI applications.",
5
5
  "main": "./cjs/index.js",
6
6
  "module": "./index.js",