diff --git a/app/libs/createReport.js b/app/libs/createReport.js index 4f38d0123..9682089e1 100644 --- a/app/libs/createReport.js +++ b/app/libs/createReport.js @@ -76,12 +76,14 @@ const createReportKbMatchSection = async (reportId, modelName, sectionContent, o variantType: record.variantType, variantId: record.variantId, kbVariant: record.kbVariant, + kbVariantId: record.kbVariantId, }; const statementCopy = {...record}; delete statementCopy.variantType; delete statementCopy.variantId; delete statementCopy.kbVariant; + delete statementCopy.kbVariantId; statementData = [{...statementCopy}]; } diff --git a/app/libs/getUser.js b/app/libs/getUser.js index 347eeee25..f01d37031 100644 --- a/app/libs/getUser.js +++ b/app/libs/getUser.js @@ -76,7 +76,7 @@ const getUser = async (req, res) => { } // Check for IPR access if (!decoded.realm_access.roles.includes(nconf.get('keycloak:role'))) { - return res.status(HTTP_STATUS.FORBIDDEN).json({message: 'IPR Access Error'}); + return res.status(HTTP_STATUS.FORBIDDEN).json({message: 'IPR Access Error: Keycloak role missing'}); } const username = decoded.preferred_username; const expiry = decoded.exp; diff --git a/app/models/reports/kbMatchJoin.js b/app/models/reports/kbMatchJoin.js index ce2e7daf4..1195cf30f 100644 --- a/app/models/reports/kbMatchJoin.js +++ b/app/models/reports/kbMatchJoin.js @@ -38,6 +38,16 @@ module.exports = (sequelize, Sq) => { }, }, }, + indexes: [ + { + name: 'idx_kb_match_id_join', + fields: ['kb_match_id'], + }, + { + name: 'idx_kb_matched_statement_id_join', + fields: ['kb_matched_statement_id'], + }, + ], }, ); }; diff --git a/app/models/reports/mutationBurden.js b/app/models/reports/mutationBurden.js index fc8134107..0a75b94c4 100644 --- a/app/models/reports/mutationBurden.js +++ b/app/models/reports/mutationBurden.js @@ -116,7 +116,7 @@ module.exports = (sequelize, Sq) => { name: 'svBurdenHidden', field: 'sv_burden_hidden', type: Sq.BOOLEAN, - defaultValue: false, + defaultValue: true, allowNull: false, jsonSchema: { description: 'SV Burden Hidden', diff --git a/app/models/reports/report.js b/app/models/reports/report.js index 08102a5df..59aced16f 100644 --- a/app/models/reports/report.js +++ b/app/models/reports/report.js @@ -26,6 +26,11 @@ module.exports = (sequelize, Sq) => { field: 'hrdetect_score', type: Sq.FLOAT, }, + intersectTmbScore: { + name: 'intersectTmbScore', + field: 'intersect_tmb_score', + type: Sq.FLOAT, + }, alternateIdentifier: { name: 'alternateIdentifier', field: 'alternate_identifier', diff --git a/app/routes/variantText/variantText.js b/app/routes/variantText/variantText.js index 9c53a5c78..e8b3466bd 100644 --- a/app/routes/variantText/variantText.js +++ b/app/routes/variantText/variantText.js @@ -203,6 +203,10 @@ router.route('/') delete req.body.project; delete req.body.template; + if (typeof req.body.cancerType === 'string') { + req.body.cancerType = [req.body.cancerType]; + } + await validateAgainstSchema(createSchema, req.body); } catch (error) { const message = `Error while validating variant text create request ${error}`; diff --git a/app/schemas/report/reportUpload/kbMatches.js b/app/schemas/report/reportUpload/kbMatches.js index fd8e13706..2294f99d0 100644 --- a/app/schemas/report/reportUpload/kbMatches.js +++ b/app/schemas/report/reportUpload/kbMatches.js @@ -13,6 +13,7 @@ module.exports = (isJsonSchema) => { type: 'array', description: 'kbMatched statement object', }, category: {type: 'string', description: 'legacy kbMatch loading'}, + approvedTherapy: {type: 'boolean', description: 'legacy kbMatch loading'}, disease: {type: 'string', description: 'legacy kbMatch loading'}, relevance: {type: 'string', description: 'legacy kbMatch loading'}, context: {type: 'string', description: 'legacy kbMatch loading'}, diff --git a/migrations/20241106215517-DEVSU-2462-new-report-field.js b/migrations/20241106215517-DEVSU-2462-new-report-field.js new file mode 100644 index 000000000..8d2238efa --- /dev/null +++ b/migrations/20241106215517-DEVSU-2462-new-report-field.js @@ -0,0 +1,20 @@ +const TABLE = 'reports'; + +module.exports = { + async up(queryInterface, Sq) { + return queryInterface.sequelize.transaction(async (transaction) => { + await queryInterface.addColumn( + TABLE, + 'intersect_tmb_score', + { + type: Sq.FLOAT, + }, + {transaction}, + ); + }); + }, + + async down() { + throw new Error('Not Implemented!'); + }, +}; diff --git a/migrations/20241107001943-DEVSU-2473-default-hidesvburden-true.js b/migrations/20241107001943-DEVSU-2473-default-hidesvburden-true.js new file mode 100644 index 000000000..7f5e186c7 --- /dev/null +++ b/migrations/20241107001943-DEVSU-2473-default-hidesvburden-true.js @@ -0,0 +1,22 @@ +const TABLE = 'reports_mutation_burden'; + +module.exports = { + async up(queryInterface, Sq) { + return queryInterface.sequelize.transaction(async (transaction) => { + await queryInterface.changeColumn( + TABLE, + 'sv_burden_hidden', + { + type: Sq.BOOLEAN, + defaultValue: true, + allowNull: false, + }, + {transaction}, + ); + }); + }, + + async down() { + throw new Error('Not Implemented!'); + }, +}; diff --git a/migrations/20241112210700-DEVSU-2457-fix-id-sequence.js b/migrations/20241112210700-DEVSU-2457-fix-id-sequence.js new file mode 100644 index 000000000..03548f9e7 --- /dev/null +++ b/migrations/20241112210700-DEVSU-2457-fix-id-sequence.js @@ -0,0 +1,10 @@ +module.exports = { + up: async (queryInterface) => { + // eslint-disable-next-line max-len + queryInterface.sequelize.query('SELECT setval(\'reports_kb_matches_id_seq\', (SELECT MAX(id) FROM reports_kb_matches) + 1);'); + }, + + down: async () => { + throw new Error('Not Implemented!'); + }, +}; diff --git a/migrations/20241112211455-DEVSU-2483-add-kb-match-index.js b/migrations/20241112211455-DEVSU-2483-add-kb-match-index.js new file mode 100644 index 000000000..20ac2e91c --- /dev/null +++ b/migrations/20241112211455-DEVSU-2483-add-kb-match-index.js @@ -0,0 +1,14 @@ +module.exports = { + up: async (queryInterface) => { + await queryInterface.addIndex('reports_kb_match_join', ['kb_match_id'], { + name: 'idx_kb_match_id_join', + }); + await queryInterface.addIndex('reports_kb_match_join', ['kb_matched_statement_id'], { + name: 'idx_kb_matched_statement_id_join', + }); + }, + + down: async () => { + throw new Error('Not Implemented!'); + }, +}; diff --git a/test/routes/report/report.test.js b/test/routes/report/report.test.js index 078bc480d..e7bd0233a 100644 --- a/test/routes/report/report.test.js +++ b/test/routes/report/report.test.js @@ -29,6 +29,7 @@ const checkReport = (report) => { 'biopsyDate', 'biopsyName', 'presentationDate', 'kbDiseaseMatch', 'kbUrl', 'pediatricIds', 'captiv8Score', 'appendix', 'hrdetectScore', 'legacyReportFilepath', 'legacyPresentationFilepath', 'signatures', + 'intersectTmbScore', ].forEach((element) => { expect(report).toHaveProperty(element); }); diff --git a/test/routes/report/reportAsync.test.js b/test/routes/report/reportAsync.test.js index 14cf4617f..5f1d4cecc 100644 --- a/test/routes/report/reportAsync.test.js +++ b/test/routes/report/reportAsync.test.js @@ -27,6 +27,7 @@ const checkReport = (report) => { 'state', 'expression_matrix', 'alternateIdentifier', 'ageOfConsent', 'biopsyDate', 'biopsyName', 'presentationDate', 'kbDiseaseMatch', 'kbUrl', 'pediatricIds', 'captiv8Score', 'hrdetectScore', 'appendix', + 'intersectTmbScore', ].forEach((element) => { expect(report).toHaveProperty(element); }); diff --git a/test/routes/report/signatureVariants.test.js b/test/routes/report/signatureVariants.test.js index f4eaa06ac..f7a254065 100644 --- a/test/routes/report/signatureVariants.test.js +++ b/test/routes/report/signatureVariants.test.js @@ -124,7 +124,7 @@ describe('/reports/{REPORTID}/sigv', () => { }); afterEach(async () => { - await db.models.signatureVariants.destroy({where: {ident: sigvUpdate.ident}, force: true}); + await db.models.signatureVariants.destroy({where: {ident: sigvUpdate.ident}}); }); test('/{sigv} - 200 Success', async () => { @@ -169,7 +169,7 @@ describe('/reports/{REPORTID}/sigv', () => { }); afterEach(async () => { - await db.models.signatureVariants.destroy({where: {ident: sigvDelete.ident}, force: true}); + await db.models.signatureVariants.destroy({where: {ident: sigvDelete.ident}}); }); test('/{sigv} - 204 No content', async () => { @@ -201,7 +201,7 @@ describe('/reports/{REPORTID}/sigv', () => { afterAll(async () => { // delete newly created report and all of it's components // indirectly by hard deleting newly created patient - report.destroy({force: true}); + report.destroy(); }); }); diff --git a/test/testData/mockReportData.json b/test/testData/mockReportData.json index aefdc28e6..04144bbbf 100644 --- a/test/testData/mockReportData.json +++ b/test/testData/mockReportData.json @@ -2,6 +2,7 @@ "template": "genomic", "captiv8Score": 20, "hrdetectScore": 10.5, + "intersectTmbScore": 9.75, "appendix": "this is an example of an appendix", "sampleInfo": [ { @@ -255,6 +256,7 @@ "variantType": "exp", "variant": "hash12345678", "kbVariant": "protein increased expression", + "kbVariantId": "123321", "category": "cancer predisposition", "disease": "colorectal cancer", "relevance": "unfavourable", @@ -268,7 +270,8 @@ "kbStatementId": "prognostic_unfavourable_lower overall survival_(ELV-PROT_ZNF703_increased expression,True,ns)_colorectal cancer_reported_pubmed_25017610", "externalSource": "CIViC", "externalStatementId": "1234", - "reviewStatus": "pending" + "reviewStatus": "pending", + "approvedTherapy": true }, { "variantType": "msi",