Skip to content

Commit

Permalink
fix: ACMG criteria can not be saved to the server (#379) (#386)
Browse files Browse the repository at this point in the history
  • Loading branch information
gromdimon authored Jan 19, 2024
1 parent 0fefba5 commit 8359dff
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 41 deletions.
4 changes: 3 additions & 1 deletion backend/app/api/internal/endpoints/remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,9 @@ async def acmg(request: Request):
try:
backend_json = backend_resp.json()
except json.JSONDecodeError:
return Response(status_code=500, content="Invalid response from InterVar backend")
return Response(
status_code=500, content=json.dumps({"error": "Invalid response from Intervar"})
)

acmg_rating = default_acmg_rating()
for key, value in backend_json.items():
Expand Down
10 changes: 5 additions & 5 deletions frontend/src/api/__tests__/acmgSeqvar.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ describe.concurrent('AcmgSeqVar Client', () => {
it('fails to list ACMG ratings', async () => {
// arrange:
fetchMocker.mockResponse((req) => {
if (req.url.includes('acmgSeqvar/list')) {
if (req.url.includes('acmgseqvar/list')) {
return Promise.resolve(JSON.stringify({ status: 500 }))
}
return Promise.resolve(JSON.stringify({ status: 400 }))
Expand Down Expand Up @@ -72,7 +72,7 @@ describe.concurrent('AcmgSeqVar Client', () => {
it('fails to fetch ACMG rating', async () => {
// arrange:
fetchMocker.mockResponse((req) => {
if (req.url.includes('acmgSeqvar/get')) {
if (req.url.includes('acmgseqvar/get')) {
return Promise.resolve(JSON.stringify({ status: 500 }))
}
return Promise.resolve(JSON.stringify({ status: 400 }))
Expand Down Expand Up @@ -101,7 +101,7 @@ describe.concurrent('AcmgSeqVar Client', () => {
it('fails to save ACMG rating', async () => {
// arrange:
fetchMocker.mockResponse((req) => {
if (req.url.includes('acmgSeqvar/create')) {
if (req.url.includes('acmgseqvar/create')) {
return Promise.resolve(JSON.stringify({ status: 500 }))
}
return Promise.resolve(JSON.stringify({ status: 400 }))
Expand Down Expand Up @@ -130,7 +130,7 @@ describe.concurrent('AcmgSeqVar Client', () => {
it('fails to update ACMG rating', async () => {
// arrange:
fetchMocker.mockResponse((req) => {
if (req.url.includes('acmgSeqvar/update')) {
if (req.url.includes('acmgseqvar/update')) {
return Promise.resolve(JSON.stringify({ status: 500 }))
}
return Promise.resolve(JSON.stringify({ status: 400 }))
Expand Down Expand Up @@ -159,7 +159,7 @@ describe.concurrent('AcmgSeqVar Client', () => {
it('fails to delete ACMG rating', async () => {
// arrange:
fetchMocker.mockResponse((req) => {
if (req.url.includes('acmgSeqvar/delete')) {
if (req.url.includes('acmgseqvar/delete')) {
return Promise.resolve(JSON.stringify({ status: 500 }))
}
return Promise.resolve(JSON.stringify({ status: 400 }))
Expand Down
10 changes: 5 additions & 5 deletions frontend/src/api/acmgSeqvar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export class AcmgSeqVarClient {
* @returns The list of ACMG ratings for the user.
*/
async listAcmgRatings(): Promise<any> {
const url = `${this.apiBaseUrl}acmgSeqvar/list`
const url = `${this.apiBaseUrl}acmgseqvar/list`
const response = await fetch(url, {
method: 'GET',
mode: 'cors',
Expand All @@ -38,7 +38,7 @@ export class AcmgSeqVarClient {
* @returns The ACMG rating for the variant.
*/
async fetchAcmgRating(seqvar: SeqvarImpl): Promise<any> {
const url = `${this.apiBaseUrl}acmgSeqvar/get?seqvar=${seqvar.toName()}`
const url = `${this.apiBaseUrl}acmgseqvar/get?seqvar=${seqvar.toName()}`
const response = await fetch(url, {
method: 'GET',
mode: 'cors',
Expand All @@ -58,7 +58,7 @@ export class AcmgSeqVarClient {
"seqvar_name": "${seqVar.toName()}",
"acmg_rank": ${JSON.stringify(acmgRating)}
}`
const response = await fetch(`${this.apiBaseUrl}acmgSeqvar/create`, {
const response = await fetch(`${this.apiBaseUrl}acmgseqvar/create`, {
method: 'POST',
mode: 'cors',
credentials: 'include',
Expand All @@ -82,7 +82,7 @@ export class AcmgSeqVarClient {
"seqvar_name": "${seqVar.toName()}",
"acmg_rank": ${JSON.stringify(acmgRating)}
}`
const response = await fetch(`${this.apiBaseUrl}acmgSeqvar/update`, {
const response = await fetch(`${this.apiBaseUrl}acmgseqvar/update`, {
method: 'PUT',
mode: 'cors',
credentials: 'include',
Expand All @@ -99,7 +99,7 @@ export class AcmgSeqVarClient {
* Delete the ACMG rating for a variant.
*/
async deleteAcmgRating(seqVar: SeqvarImpl): Promise<AcmgRatingBackend> {
const response = await fetch(`${this.apiBaseUrl}acmgSeqvar/delete?seqvar=${seqVar.toName()}`, {
const response = await fetch(`${this.apiBaseUrl}acmgseqvar/delete?seqvar=${seqVar.toName()}`, {
method: 'DELETE',
mode: 'cors',
credentials: 'include'
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/components/SeqvarDetails/ClinsigCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ const refetchAcmgRatingInterVar = () => {
/** Whether to re-fetch ACMG rating saved on server earlier. */
const refetchAcmgRatingServer = () => {
tryCatchEmitErrorDisplay(async () => {
if (props.seqvar) {
await acmgRatingStore.refetchAcmgRating(props.seqvar)
}
})
tryCatchEmitErrorDisplay(async () => acmgRatingStore.acmgRating.setUserPresenceServer())
}
Expand Down
58 changes: 29 additions & 29 deletions frontend/src/stores/__tests__/seqvarAcmgRating.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,21 +113,21 @@ describe.concurrent('geneInfo Store', () => {
value ? Presence.Present : Presence.Absent
)
// Set Absent for all criteria for Server source
expectedAcmgRating.setPresence(
StateSource.Server,
AcmgCriteria[acmgCriteriaKey],
Presence.Absent
)
// expectedAcmgRating.setPresence(
// StateSource.Server,
// AcmgCriteria[acmgCriteriaKey],
// Presence.Absent
// )
// Set evidence level to the Default for all criteria for Server source
const defaultEvidenceLevel = expectedAcmgRating.getCriteriaStateFromSource(
acmgCriteriaKey,
StateSource.Default
).evidenceLevel
expectedAcmgRating.setEvidenceLevel(
StateSource.Server,
AcmgCriteria[acmgCriteriaKey],
defaultEvidenceLevel
)
// const defaultEvidenceLevel = expectedAcmgRating.getCriteriaStateFromSource(
// acmgCriteriaKey,
// StateSource.Default
// ).evidenceLevel
// expectedAcmgRating.setEvidenceLevel(
// StateSource.Server,
// AcmgCriteria[acmgCriteriaKey],
// defaultEvidenceLevel
// )
}
expect(store.acmgRating).toStrictEqual(expectedAcmgRating)
expect(store.seqvar).toStrictEqual(structuredClone(seqvarInfo))
Expand Down Expand Up @@ -177,21 +177,21 @@ describe.concurrent('geneInfo Store', () => {
value ? Presence.Present : Presence.Absent
)
// Set Absent for all criteria for Server source
expectedAcmgRating.setPresence(
StateSource.Server,
AcmgCriteria[acmgCriteriaKey],
Presence.Absent
)
// Set evidence level to the Default for all criteria for Server source
const defaultEvidenceLevel = expectedAcmgRating.getCriteriaStateFromSource(
acmgCriteriaKey,
StateSource.Default
).evidenceLevel
expectedAcmgRating.setEvidenceLevel(
StateSource.Server,
AcmgCriteria[acmgCriteriaKey],
defaultEvidenceLevel
)
// expectedAcmgRating.setPresence(
// StateSource.Server,
// AcmgCriteria[acmgCriteriaKey],
// Presence.Absent
// )
// // Set evidence level to the Default for all criteria for Server source
// const defaultEvidenceLevel = expectedAcmgRating.getCriteriaStateFromSource(
// acmgCriteriaKey,
// StateSource.Default
// ).evidenceLevel
// expectedAcmgRating.setEvidenceLevel(
// StateSource.Server,
// AcmgCriteria[acmgCriteriaKey],
// defaultEvidenceLevel
// )
}
expect(store.acmgRating).toStrictEqual(expectedAcmgRating)
expect(store.seqvar).toStrictEqual(seqvarInfo)
Expand Down
45 changes: 44 additions & 1 deletion frontend/src/stores/seqvarAcmgRating.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,44 @@ export const useSeqvarAcmgRatingStore = defineStore('seqvarAcmgRating', () => {
}
}

/**
* Refetch the server data.
*
* @param seqvar$ The sequence variant to retrieve the ACMG rating for.
*/
const refetchAcmgRating = async (seqvar$: Seqvar) => {
// Fetch the ACMG rating from the server
try {
const acmgSeqvarClient = new AcmgSeqVarClient()
if (!seqvar$) {
throw new Error('There was an error loading the ACMG data from the server.')
}
const seqvarImpl = seqvarImplFromSeqvar(seqvar$)
const acmgRatingBackend = await acmgSeqvarClient.fetchAcmgRating(seqvarImpl)
if (acmgRatingBackend.acmg_rank?.criterias) {
acmgRatingStatus.value = true
// Go through the data and setPresense for each criteria
for (const criteria of acmgRatingBackend.acmg_rank.criterias) {
const criteriaKey = criteria.criteria as keyof typeof AcmgCriteria
acmgRating.value.setPresence(
StateSource.Server,
AcmgCriteria[criteriaKey],
criteria.presence
)
acmgRating.value.setEvidenceLevel(
StateSource.Server,
AcmgCriteria[criteriaKey],
criteria.evidence
)
}
}
} catch (e) {
clearData()
storeState.value = StoreState.Error
throw new Error(`There was an error loading the ACMG data from the server: ${e}`)
}
}

/**
* List all ACMG ratings for a user.
*
Expand Down Expand Up @@ -199,7 +237,11 @@ export const useSeqvarAcmgRatingStore = defineStore('seqvarAcmgRating', () => {
try {
const acmgSeqvarClient = new AcmgSeqVarClient()
const acmgSeqvar = await acmgSeqvarClient.fetchAcmgRating(seqvarImpl)
if (acmgSeqvar && acmgSeqvar.detail !== 'ACMG Sequence Variant not found') {
if (
acmgSeqvar &&
acmgSeqvar.detail !== 'ACMG Sequence Variant not found' &&
acmgSeqvar.detail !== 'Not Found'
) {
await acmgSeqvarClient.updateAcmgRating(seqvarImpl, acmgRating)
} else {
await acmgSeqvarClient.saveAcmgRating(seqvarImpl, acmgRating)
Expand Down Expand Up @@ -241,6 +283,7 @@ export const useSeqvarAcmgRatingStore = defineStore('seqvarAcmgRating', () => {
deleteAcmgRating,
clearData,
fetchAcmgRating,
refetchAcmgRating,
listAcmgRatings
}
})

0 comments on commit 8359dff

Please sign in to comment.