generated from ministryofjustice/hmpps-template-typescript
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* Refactor NOMIS config download routes into a self-contained nested router * Add utility function to convert objects with nested Dates into strings * Allow downloading NOMIS report configuration in source JSON format * Add methods to retrieve incident reporting constants from API * Allow downloading incident reporting api constants as source JSON * Add script to import DPS constants/enumerations into typescript types * Add script to list all report configuration URLs in an environment and document import steps ```mermaid flowchart TD Download[Download DPS config JSON via UI app] --> Import[Import files using CLI from UI app locally] Import --> Git[Check updated enumerations and constants into git] Git --> End([ ]) ``` Steps to get latest incident reporting API constants imported: - download DPS constants/enumerations - run script to import them into generated typescript files - check into git - latest types from incident reporting api are now baked into this repo Steps to get latest NOMIS configuration imported: - download NOMIS JSON files - [NOT IMPLEMENTED] run script to import them into generated typescript files - [NOT IMPLEMENTED] check into git - [NOT IMPLEMENTED] latest configuration from NOMIS are now baked into this repo As noted in the README, download links are listed using `./scripts/listDownloadLinks.ts prod` command.
- Loading branch information
Showing
29 changed files
with
1,352 additions
and
560 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
#!/usr/bin/env npx tsx | ||
import { spawnSync } from 'node:child_process' | ||
import fs from 'node:fs' | ||
import path from 'node:path' | ||
|
||
import type { IncidentReportingApi, Constant, TypeConstant } from '../server/data/incidentReportingApi' | ||
|
||
type ConstantsMethod = keyof IncidentReportingApi['constants'] | ||
interface Template { | ||
method: ConstantsMethod | ||
enumName: string | ||
documentation: string | ||
} | ||
const templates: Template[] = [ | ||
{ method: 'types', enumName: 'Type', documentation: 'Types of reportable incidents' }, | ||
{ method: 'statuses', enumName: 'Status', documentation: 'Report statuses' }, | ||
{ | ||
method: 'informationSources', | ||
enumName: 'InformationSource', | ||
documentation: 'Whether the report was first created in DPS or NOMIS', | ||
}, | ||
{ | ||
method: 'staffInvolvementRoles', | ||
enumName: 'StaffInvolvementRole', | ||
documentation: 'Roles of staff involvement in an incident', | ||
}, | ||
{ | ||
method: 'prisonerInvolvementRoles', | ||
enumName: 'PrisonerInvolvementRole', | ||
documentation: 'Roles of a prisoner’s involvement in an incident', | ||
}, | ||
{ | ||
method: 'prisonerInvolvementOutcomes', | ||
enumName: 'PrisonerInvolvementOutcome', | ||
documentation: 'Outcomes from a prisoner’s involvement in an incident', | ||
}, | ||
{ | ||
method: 'correctionRequestReasons', | ||
enumName: 'CorrectionRequestReason', | ||
documentation: 'Reasons for correction requests made about a report', | ||
}, | ||
{ | ||
method: 'errorCodes', | ||
enumName: 'ErrorCode', | ||
documentation: 'Unique codes to discriminate errors returned from the incident reporting api', | ||
}, | ||
] | ||
|
||
const scriptName = path.basename(process.argv[1]) | ||
|
||
function printHelp(): never { | ||
const help = ` | ||
Imports constants from incident reporting api downloaded as JSON files. | ||
Usage: | ||
./scripts/${scriptName} <type> <file path> | ||
Where <type> is one of ${templates.map(template => template.method).join(', ')} | ||
`.trim() | ||
process.stderr.write(`${help}\n`) | ||
process.exit(1) | ||
} | ||
|
||
const [, , type, filePath] = process.argv | ||
if (!type || !filePath) { | ||
printHelp() | ||
} | ||
const template = templates.find(t => t.method === type) | ||
if (!template) { | ||
printHelp() | ||
} | ||
const { method, enumName, documentation } = template | ||
|
||
const constants: (Constant | TypeConstant)[] = JSON.parse(fs.readFileSync(filePath, { encoding: 'utf8' })) | ||
|
||
const outputPath = path.resolve(__dirname, `../server/reportConfiguration/constants/${method}.ts`) | ||
const outputFile = fs.openSync(outputPath, 'w') | ||
|
||
fs.writeSync(outputFile, `// Generated with ./scripts/${scriptName} at ${new Date().toISOString()}\n\n`) | ||
if (method === 'errorCodes') { | ||
// error codes are numbers so need special treatment | ||
|
||
fs.writeSync(outputFile, `/** ${documentation} */\n`) | ||
fs.writeSync(outputFile, '// eslint-disable-next-line import/prefer-default-export\n') | ||
fs.writeSync(outputFile, `export enum ${enumName} {\n`) | ||
constants.forEach(constant => { | ||
fs.writeSync(outputFile, `${constant.description} = ${constant.code},\n`) | ||
}) | ||
fs.writeSync(outputFile, '}\n') | ||
} else { | ||
// other constants are strings with extra info | ||
|
||
fs.writeSync(outputFile, `/** ${documentation} */\n`) | ||
fs.writeSync(outputFile, `export const ${method} = [\n`) | ||
constants.forEach(constant => { | ||
fs.writeSync( | ||
outputFile, | ||
`{ code: ${JSON.stringify(constant.code)}, description: ${JSON.stringify(constant.description)},\n`, | ||
) | ||
if ('active' in constant) { | ||
fs.writeSync(outputFile, `active: ${constant.active}, nomisCode: ${JSON.stringify(constant.nomisCode)} },\n`) | ||
} else { | ||
fs.writeSync(outputFile, '},\n') | ||
} | ||
}) | ||
fs.writeSync(outputFile, '] as const\n\n') | ||
fs.writeSync(outputFile, `/** ${documentation} */\n`) | ||
fs.writeSync(outputFile, `export type ${enumName} = (typeof ${method})[number]['code']\n`) | ||
if (method === 'types') { | ||
fs.writeSync(outputFile, `\n/** ${documentation}\n * @deprecated\n */\n`) | ||
fs.writeSync(outputFile, `export type Nomis${enumName} = (typeof ${method})[number]['nomisCode']\n`) | ||
} | ||
} | ||
fs.closeSync(outputFile) | ||
|
||
spawnSync('npx', ['prettier', '--write', outputPath], { encoding: 'utf8' }) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
#!/usr/bin/env npx tsx | ||
import fs from 'node:fs' | ||
import path from 'node:path' | ||
|
||
import { parse as parseYaml } from 'yaml' | ||
|
||
const scriptName = path.basename(process.argv[1]) | ||
|
||
const helmRootPath = path.resolve(__dirname, '../helm_deploy') | ||
const environments = fs | ||
.readdirSync(helmRootPath, { encoding: 'utf8' }) | ||
.filter(p => p.startsWith('values-') && p.endsWith('.yaml')) | ||
.map(p => { | ||
const { environment } = /^values-(?<environment>.*?).yaml$/.exec(p).groups | ||
const helmValuesPath = path.join(helmRootPath, p) | ||
const helmValues: { 'generic-service': { ingress: { host: string } } } = parseYaml( | ||
fs.readFileSync(helmValuesPath, { encoding: 'utf8' }), | ||
) | ||
const baseUrl = `https://${helmValues['generic-service'].ingress.host}` | ||
return { environment, baseUrl } | ||
}) | ||
|
||
function printHelp(): never { | ||
const help = ` | ||
Prints download links for DPS and NOMIS configuration: | ||
Usage: | ||
./scripts/${scriptName} <env> | ||
Where <env> is one of ${environments.map(e => e.environment).join(', ')} | ||
`.trim() | ||
process.stderr.write(`${help}\n`) | ||
process.exit(1) | ||
} | ||
|
||
const [, , env] = process.argv | ||
if (!env) { | ||
printHelp() | ||
} | ||
const environment = environments.find(e => e.environment === env) | ||
if (!environment) { | ||
printHelp() | ||
} | ||
const { baseUrl } = environment | ||
|
||
process.stderr.write('DPS configuration JSON downloads:\n') | ||
;[ | ||
'types', | ||
'statuses', | ||
'informationSources', | ||
'staffInvolvementRoles', | ||
'prisonerInvolvementRoles', | ||
'prisonerInvolvementOutcomes', | ||
'correctionRequestReasons', | ||
'errorCodes', | ||
].forEach(type => { | ||
process.stderr.write(` - ${baseUrl}/download-report-config/dps/${type}.json\n`) | ||
}) | ||
|
||
process.stderr.write('\nNOMIS configuration JSON downloads:\n') | ||
;[ | ||
'incident-types', | ||
'incident-type/<type>/questions', | ||
'incident-type/<type>/prisoner-roles', | ||
'staff-involvement-roles', | ||
'prisoner-involvement-roles', | ||
'prisoner-involvement-outcome', | ||
].forEach(urlSlug => { | ||
process.stderr.write(` - ${baseUrl}/download-report-config/nomis/${urlSlug}.json\n`) | ||
}) | ||
process.stderr.write('Where <type> is the NOMIS incident report type code.\n') | ||
|
||
process.stderr.write('\nNOMIS configuration CSV downloads:\n') | ||
;[ | ||
'incident-types', | ||
'incident-type/<type>/questions', | ||
'incident-type/<type>/prisoner-roles', | ||
'staff-involvement-roles', | ||
'prisoner-involvement-roles', | ||
'prisoner-involvement-outcome', | ||
].forEach(urlSlug => { | ||
process.stderr.write(` - ${baseUrl}/download-report-config/nomis/${urlSlug}.csv\n`) | ||
}) | ||
process.stderr.write('Where <type> is the NOMIS incident report type code.\n') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.