@ministryofjustice/hmpps-digital-prison-reporting-frontend
Version:
The Digital Prison Reporting Frontend contains templates and code to help display data effectively in UI applications.
185 lines (182 loc) • 6.55 kB
JavaScript
import { captureDprError, LoggerErrorType } from '../../../utils/captureError.js';
import { RequestedReportSchema } from './requested-reports/validation.js';
import { ViewedReportSchema } from './recently-viewed/validation.js';
/**
* Get a single report from My reports
* - validates the report and removes if invalid
*
* @param {GetRemoveMyReportData} reportData
* @param {('requested' | 'viewed')} type
* @param {Services} services
* @param {string} userId
* @return {*} {(Promise<RequestedReport | RecentlyViewedReport | undefined>)}
*/
const getMyReport = async (reportData, type, services, userId) => {
const rawReport = await fetchReport(type, reportData, services, userId);
if (!rawReport) {
return undefined;
}
const schema = getSchema(type);
const result = schema.safeParse(rawReport);
if (!result.success) {
captureDprError(result.error, 'Invalid Redis payload');
try {
await removeMyReport(type, reportData, services, userId);
}
catch (cleanupError) {
const meta = rawReport
? {
id: rawReport.id ?? 'unknown',
reportId: rawReport.reportId ?? 'unknown',
tableId: rawReport.tableId ?? 'unknown',
executionId: rawReport.executionId ?? 'unknown',
loadType: rawReport.loadType,
}
: {};
captureDprError(cleanupError, 'Failed to remove invalid report', meta);
}
return undefined;
}
return result.data;
};
/**
* Gets all My Reports for a particular type
* - validats the list and removes invalid ones
*
* @param {('requested' | 'viewed')} type
* @param {Services} services
* @param {string} userId
* @return {*} {(Promise<(RequestedReport | RecentlyViewedReport)[]>)}
*/
const getAllMyReports = async (type, services, userId) => {
const service = getService(type, services);
const schema = getSchema(type);
const reports = await service.getAllReports(userId);
const results = await Promise.all(reports.map(async (rawReport) => {
const result = schema.safeParse(rawReport);
if (result.success) {
return result.data;
}
const { id, reportName, reportId, loadType } = rawReport;
const errorMeta = {
id,
type,
reportName,
reportId,
loadType: loadType,
};
captureDprError(result.error, 'Invalid Redis payload', errorMeta, LoggerErrorType.WARN);
try {
const report = rawReport;
await removeMyReport(type, {
reportId: report.reportId,
id: report.id,
executionId: report.executionId,
tableId: report.tableId,
}, services, userId);
}
catch (cleanupError) {
const meta = rawReport
? {
id: rawReport.id ?? 'unknown',
reportId: rawReport.reportId ?? 'unknown',
tableId: rawReport.tableId ?? 'unknown',
executionId: rawReport.executionId ?? 'unknown',
loadType: rawReport.loadType,
}
: {};
captureDprError(cleanupError, 'Failed to remove invalid report (list)', meta);
}
return null;
}));
const res = results.filter(Boolean);
return res;
};
/**
* Add a report to my report
* - validates the incoming report data before addition
*
* @param {('requested' | 'viewed')} type
* @param {(RequestedReport | RecentlyViewedReport)} reportData
* @param {Services} services
* @param {string} userId
*/
const addMyReport = async (type, reportData, services, userId) => {
const schema = getSchema(type);
const result = schema.safeParse(reportData);
if (!result.success) {
captureDprError(result.error, 'Unable to add report - Invalid report data');
return;
}
switch (type) {
case 'requestedReports':
await services.requestedReportService.addReport(userId, result.data);
break;
case 'recentlyViewedReports':
await services.recentlyViewedService.setRecentlyViewed(result.data, userId);
break;
case 'subscriptions':
await services.subscriptionStoreService.addReport(userId, result.data);
break;
}
};
/**
* Removes a report from My Reports
*
* @param {('requested' | 'viewed')} type
* @param {GetRemoveMyReportData} reportData
* @param {Services} services
* @param {string} userId
* @return {*} {Promise<void>}
*/
const removeMyReport = async (type, reportData, services, userId) => {
const { executionId, tableId, reportId, id } = reportData;
if (executionId && type === 'requestedReports') {
return services.requestedReportService.removeReport(executionId, userId);
}
if (type === 'recentlyViewedReports') {
return services.recentlyViewedService.removeReport(userId, reportId, id, tableId);
}
if (type === 'subscriptions' && reportId && id) {
return services.subscriptionStoreService.removeReport(userId, reportId, id);
}
return undefined;
};
/**
* Fetches the reports from My reports
*
* @param {('requested' | 'viewed')} type
* @param {GetRemoveMyReportData} reportData
* @param {Services} services
* @param {string} userId
* @return {*} {Promise<RequestedReport | RecentlyViewedReport | undefined>}
*/
const fetchReport = async (type, reportData, services, userId) => {
const { executionId, tableId } = reportData;
const service = getService(type, services);
if (executionId) {
return service.getReportByExecutionId(executionId, userId);
}
if (tableId) {
return service.getReportByTableId(tableId, userId);
}
return undefined;
};
const getSchema = (type) => {
const schemaMap = {
requestedReports: RequestedReportSchema,
recentlyViewedReports: ViewedReportSchema,
subscriptions: ViewedReportSchema,
};
return schemaMap[type];
};
const getService = (type, services) => {
const serviceMap = {
requestedReports: services.requestedReportService,
recentlyViewedReports: services.recentlyViewedService,
subscriptions: services.subscriptionStoreService,
};
return serviceMap[type];
};
export { addMyReport, getAllMyReports, getMyReport, removeMyReport };
//# sourceMappingURL=utils.js.map