Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bugfix/DEVSU-2131-fix-rapid-report-filter #277

Merged
merged 11 commits into from
Nov 16, 2023
3 changes: 2 additions & 1 deletion .github/workflows/npm-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node: [14, 16, 18, 20]
node: [18, 20]
# TODO: readd node versions: node: [14, 16, 18, 20]
name: node-${{ matrix.node }}
services:
postgres:
Expand Down
51 changes: 15 additions & 36 deletions app/middleware/report.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
const HTTP_STATUS = require('http-status-codes');
const db = require('../models');
const logger = require('../log');
const cache = require('../cache');
const aclMiddleware = require('./acl');
const {hasAccessToNonProdReports} = require('../libs/helperFunctions');

Expand Down Expand Up @@ -29,48 +28,28 @@ module.exports = async (req, res, next, ident) => {
},
];

// Check cache for report
const key = `/reports/${ident}`;
let result;

try {
result = await cache.get(key);
} catch (error) {
logger.error(`Error during report cache get ${error}`);
}

if (result) {
// Build Sequelize model from cached string without calling db
result = db.models.report.build(JSON.parse(result), {
raw: true,
isNewRecord: false,
result = await db.models.report.findOne({
where: {ident},
attributes: {exclude: ['config']},
include,
});
} else {
try {
result = await db.models.report.findOne({
where: {ident},
attributes: {exclude: ['config']},
include,
});
} catch (error) {
logger.error(`Error while trying to get report: ${ident} ${error}`);
return res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({error: {message: 'Error while trying to get report'}});
}

// Nothing found?
if (!result) {
logger.error(`Unable to find the requested report ${ident}`);
return res.status(HTTP_STATUS.NOT_FOUND).json({error: {message: 'Unable to find the requested report'}});
}
} catch (error) {
logger.error(`Error while trying to get report: ${ident} ${error}`);
return res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({error: {message: 'Error while trying to get report'}});
}

if (!hasAccessToNonProdReports(req.user) && result.state === 'nonproduction') {
logger.error(`User does not have non-production access to ${ident}`);
return res.status(HTTP_STATUS.FORBIDDEN).json({error: {message: 'User does not have access to Non-Production reports'}});
}
// Nothing found?
if (!result) {
logger.error(`Unable to find the requested report ${ident}`);
return res.status(HTTP_STATUS.NOT_FOUND).json({error: {message: 'Unable to find the requested report'}});
}

// Add result to cache
cache.set(key, JSON.stringify(result), 'EX', 14400);
if (!hasAccessToNonProdReports(req.user) && result.state === 'nonproduction') {
logger.error(`User does not have non-production access to ${ident}`);
return res.status(HTTP_STATUS.FORBIDDEN).json({error: {message: 'User does not have access to Non-Production reports'}});
}

// Add report to request
Expand Down
30 changes: 11 additions & 19 deletions app/routes/report/variants.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,18 @@ const therapeuticAssociationFilter = {
matchedCancer: true,
variantType: {[Op.and]: [
{[Op.is]: literal('distinct from \'exp\'')},
{[Op.is]: literal('distinct from \'msi\'')},
{[Op.is]: literal('distinct from \'tmb\'')},
]},
[Op.or]: [
{
relevance: 'resistance',
iprEvidenceLevel: 'IPR-A',
},
{
relevance: 'sensitivity',
},
],
[Op.and]: {
[Op.or]: [
{
relevance: 'resistance',
iprEvidenceLevel: 'IPR-A',
},
{
relevance: 'sensitivity',
},
],
},
// Regex filter for finding columns with 2 or more spaces that end with
// mutation or mutations
[Op.not]: {kbVariant: {[Op.regexp]: MUTATION_REGEX}},
Expand All @@ -58,14 +58,6 @@ const therapeuticAssociationFilter = {
// Literal is used in order to accomodate NULL rows.
const cancerRelevanceFilter = {
id: {[Op.ne]: null},
[Op.not]: {
[Op.or]: [
{iprEvidenceLevel: {[Op.is]: literal('not distinct from \'IPR-A\'')}},
{iprEvidenceLevel: {[Op.is]: literal('not distinct from \'IPR-B\'')}},
],
category: 'therapeutic',
matchedCancer: true,
},
variantType: {[Op.and]: [
{[Op.is]: literal('distinct from \'exp\'')},
]},
Expand Down
5 changes: 3 additions & 2 deletions test/routes/report/report.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ describe('/reports/{REPORTID}', () => {
let totalReports;
let reportDualProj;

beforeEach(async () => {
beforeAll(async () => {
// Get genomic template
const template = await db.models.template.findOne({where: {name: 'genomic'}});
// Create Report and associate projects
Expand Down Expand Up @@ -549,12 +549,13 @@ describe('/reports/{REPORTID}', () => {
});

// delete report
afterEach(async () => {
afterAll(async () => {
await db.models.report.destroy({where: {id: report.id}, force: true});
await db.models.report.destroy({where: {id: reportReady.id}, force: true});
await db.models.report.destroy({where: {id: reportReviewed.id}, force: true});
await db.models.report.destroy({where: {id: reportArchived.id}, force: true});
await db.models.report.destroy({where: {id: reportNonProduction.id}, force: true});
await db.models.report.destroy({where: {id: reportNonProduction.id}, force: true});
}, LONGER_TIMEOUT);
});

Expand Down
2 changes: 1 addition & 1 deletion test/routes/report/variants.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ describe('/reports/{REPORTID}/kb-matches', () => {

// delete report
afterAll(async () => {
// await db.models.report.destroy({where: {ident: rapidReportIdent}, force: true});
await db.models.report.destroy({where: {ident: rapidReportIdent}, force: true});
}, LONGER_TIMEOUT);
});

Expand Down
30 changes: 22 additions & 8 deletions test/testData/mockRapidReportData.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"category": "therapeutic",
"variantType": "cnv",
"variant": "TA",
"iprEvidenceLevel": "IPR-B",
"iprEvidenceLevel": "IPR-A",
"kbVariant": "this should be in table 1",
"matchedCancer": true,
"relevance": "resistance",
Expand All @@ -43,6 +43,16 @@
"relevance": "resistance",
"evidenceLevel": "table 2"
},
{
"category": "therapeutic",
"variantType": "cnv",
"variant": "CR",
"iprEvidenceLevel": "IPR-D",
"kbVariant": "geneX specific mutation 7",
"matchedCancer": true,
"relevance": "sensitivity",
"evidenceLevel": "table 2"
},
{
"category": "therapeutic",
"variantType": "cnv",
Expand Down Expand Up @@ -71,20 +81,24 @@
"evidenceLevel": "table 2"
},
{
"category": "unknown",
"category": "therapeutic",
"variantType": "msi",
"variant": "msi",
"iprEvidenceLevel": "IPR-A",
"kbVariant": "also should be table 2",
"evidenceLevel": "table 2"
"matchedCancer": true,
"relevance": "sensitivity",
"kbVariant": "also should be table 1",
"evidenceLevel": "table 1"
},
{
"category": "unknown",
"category": "therapeutic",
"variantType": "tmb",
"variant": "tmb",
"iprEvidenceLevel": "IPR-A",
"matchedCancer": true,
"relevance": "sensitivity",
"kbVariant": "geneX specific mutation 2",
"evidenceLevel": "table 2"
"evidenceLevel": "table 1"
},
{
"category": "therapeutic",
Expand Down Expand Up @@ -243,13 +257,13 @@
],
"tmburMutationBurden": {
"key": "tmb",
"displayName": "table 2"
"displayName": "table 1"
},
"msi": [
{
"score": 100,
"key": "msi",
"displayName": "table 2"
"displayName": "table 1"
},
{
"score": 15,
Expand Down