Skip to content

Commit

Permalink
Use reviewed content only (oncokb#430)
Browse files Browse the repository at this point in the history
* Use reviewed content only

* Ignore if in review added state

* Save Genes now checks if added

* Delete parent node if added field is true

* Fixed build

* don't save undefined

* Addressed PR comments

* Addressed PR comments
  • Loading branch information
jfkonecn committed Sep 20, 2024
1 parent bf385ad commit ff7b93b
Show file tree
Hide file tree
Showing 10 changed files with 763 additions and 369 deletions.
2 changes: 2 additions & 0 deletions src/main/webapp/app/service/firebase/firebase-gene-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -600,9 +600,11 @@ export class FirebaseGeneService {
let count = 0;
for (const [hugoSymbol, gene] of Object.entries(geneLookup)) {
count++;
// eslint-disable-next-line no-console
console.log(`${count} - Saving ${hugoSymbol}...`);
const nullableVus: Record<string, Vus> | null = vusLookup[hugoSymbol];
await this.saveGeneWithData(isGermlineProp, hugoSymbol, drugLookup, gene, nullableVus);
// eslint-disable-next-line no-console
console.log('\tDone Saving.');
}
};
Expand Down
4 changes: 2 additions & 2 deletions src/main/webapp/app/shared/api/manual/drive-annotation-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ export const DriveAnnotationAxiosParamCreator = function (configuration?: Config
for (const [key, value] of Object.entries(driveAnnotation)) {
if (typeof value === 'boolean') {
bodyFormData.append(key, `${value}`);
} else {
bodyFormData.append(key, value ?? '');
} else if (value !== undefined) {
bodyFormData.append(key, value);
}
}
localVarRequestOptions.data = bodyFormData;
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,42 +1,42 @@
import _ from 'lodash';
import { Drug, Gene, Mutation, Review, Treatment, Tumor, Vus, DrugCollection } from '../../model/firebase/firebase.model';
import { useLastReviewedOnly } from '../core-submission-shared/core-submission-utils';

export function getGeneData(geneData: Gene, onlyReviewedContent: boolean, drugList: DrugCollection): true | Gene {
const gene = _.cloneDeep(geneData);
processData(gene, ['summary', 'background'], onlyReviewedContent);
processData(gene.type, ['tsg', 'ocg'], onlyReviewedContent);
export function getGeneData(geneData: Gene, drugList: DrugCollection): Gene | undefined {
const gene = useLastReviewedOnly(geneData);
if (gene === undefined) {
return undefined;
}
processData(gene, ['summary', 'background']);
processData(gene.type, ['tsg', 'ocg']);
const tempMutations: Mutation[] = [];
for (const mutation of gene.mutations ?? []) {
const tempTumors: Tumor[] = [];
if (shouldExclude(onlyReviewedContent, mutation.name_review)) {
if (shouldExclude(mutation.name_review)) {
tempMutations.push(mutation);
continue;
}
processData(mutation, ['name'], onlyReviewedContent);
processData(mutation.mutation_effect, ['oncogenic', 'effect', 'description'], onlyReviewedContent);
processData(mutation, ['name']);
processData(mutation.mutation_effect, ['oncogenic', 'effect', 'description']);
for (const tumor of mutation.tumors ?? []) {
if (shouldExclude(onlyReviewedContent, tumor.cancerTypes_review)) {
if (shouldExclude(tumor.cancerTypes_review)) {
tempTumors.push(tumor);
continue;
}
// process tumor cancerTypes
processData(tumor, ['summary', 'diagnosticSummary', 'prognosticSummary'], onlyReviewedContent);
processData(tumor.diagnostic, ['level', 'description', 'excludedRCTs'], onlyReviewedContent);
processData(tumor.prognostic, ['level', 'description', 'excludedRCTs'], onlyReviewedContent);
processData(tumor, ['summary', 'diagnosticSummary', 'prognosticSummary']);
processData(tumor.diagnostic, ['level', 'description', 'excludedRCTs']);
processData(tumor.prognostic, ['level', 'description', 'excludedRCTs']);
for (const ti of tumor.TIs) {
type TempTreatment = Omit<Treatment, 'name'> & { name: ReturnType<typeof drugUuidToDrug> | string };
const tempTreatments: TempTreatment[] = [];
for (const treatment of ti.treatments ?? []) {
if (shouldExclude(onlyReviewedContent, treatment.name_review)) {
if (shouldExclude(treatment.name_review)) {
tempTreatments.push(treatment);
return true;
return undefined;
}
(treatment as TempTreatment).name = drugUuidToDrug(treatment.name, drugList);
processData(
treatment,
['level', 'propagation', 'propagationLiquid', 'indication', 'description', 'fdaLevel'],
onlyReviewedContent,
);
processData(treatment, ['level', 'propagation', 'propagationLiquid', 'indication', 'description', 'fdaLevel']);
}
for (const item of tempTreatments) {
const index = ti.treatments.indexOf(item as Treatment);
Expand All @@ -62,20 +62,18 @@ export function getGeneData(geneData: Gene, onlyReviewedContent: boolean, drugLi
return gene;
}

function processData<T, K extends keyof T & string>(data: T | undefined, keys: K[], onlyReviewedContent: boolean) {
function processData<T, K extends keyof T & string>(data: T | undefined, keys: K[]) {
if (data !== undefined) {
for (const key of keys) {
delete data?.[key + '_comments'];
const reviewKey = key + '_review';
const maybeReview = data?.[reviewKey];
if (
data !== null &&
onlyReviewedContent &&
typeof maybeReview === 'object' &&
maybeReview !== null &&
'lastReviewed' in maybeReview
) {
data[key] = maybeReview.lastReviewed;
const maybeReview: Review | null | undefined = data?.[reviewKey];
if (data !== null && typeof maybeReview === 'object' && maybeReview !== null) {
if (maybeReview.added) {
delete data[key];
} else if ('lastReviewed' in maybeReview) {
data[key] = maybeReview.lastReviewed as (T & object)[K];
}
}
}
}
Expand All @@ -91,12 +89,13 @@ export function getVUSData(vus: Vus[]) {
return vusDataArray;
}

function shouldExclude(onlyReviewedContent: boolean, reviewObj: Review | undefined) {
return (
reviewObj &&
((onlyReviewedContent && reviewObj.added === true && reviewObj.promotedToMutation === true && reviewObj.initialUpdate === true) ||
(!onlyReviewedContent && reviewObj.removed === true))
);
function shouldExclude(reviewObj: Review | undefined) {
/* initialUpdate is true when it is the first time updating excludedRCTs field.
* Normally for string fields, we set lastReviewed: "" to empty string.
* The "lastReviewed" for excludedRCTs is empty array, which cannot be stored
* into firebase, so we created this initialUpdate field to denote that.
* */
return reviewObj && (reviewObj.added === true || reviewObj.promotedToMutation === true || reviewObj.initialUpdate === true);
}

function drugUuidToDrug(key: string | undefined, drugList: DrugCollection): Drug[][] | Record<string, unknown> {
Expand Down Expand Up @@ -138,10 +137,13 @@ export function getDriveAnnotations(
{ gene, vus, releaseGene }: { gene: Gene | undefined; vus: Vus[] | undefined; releaseGene: boolean },
): DriveAnnotation {
const params: DriveAnnotation = { gene: undefined, vus: undefined, releaseGene: false };
if (gene) {
params.gene = JSON.stringify(getGeneData(gene, true, drugList));
if (gene !== undefined) {
const geneData = getGeneData(gene, drugList);
if (geneData !== undefined) {
params.gene = JSON.stringify(geneData);
}
}
if (vus) {
if (vus !== undefined) {
params.vus = JSON.stringify(getVUSData(vus));
}
if (releaseGene) {
Expand Down
Loading

0 comments on commit ff7b93b

Please sign in to comment.