From 82cda52c6f4d38d026174257bd33f08f9578be3e Mon Sep 17 00:00:00 2001 From: James Scherer Date: Fri, 9 Feb 2024 11:38:41 -0600 Subject: [PATCH] [Feature Branch] Analysis Discussion Section - Phase 1 (#161) * [Frontend] Create a new discussion component to be displayed in an Analysis view (#139) * Updating the paper to include the country for each affiliation which is required for publication. * Updated the system tests workflow to use electron (#140) * Added a DiscussionsSection.vue in AnalysisView components, updated the analysis model to return an injected discussion object, and updating the styling of the buttons to match figma more closely * The discussion collapse works * Looks ready for a pull request * Tests should be working now * Left out the node test * Updating CSS in a few places * Updating the DiscussionSection values --------- Co-authored-by: Angelina Uno-Antonison * Created a discussions property in each of the analyses with several posts within them. Removed the temp fixture used in the frontend (#141) * Fixed frontend unit test with AnalysisView * fixed line too long * Missed the updated json * Changed formatting on the /etc/fixtures/analyses.json * removed the etc/.certificate files * Displaying discussion posts (#150) * New Discussions post button, text field, and save/publish buttons * Creating temporary discussion API mock api endpoints to test integrating them into the frontend * Displaying posts from an analysis * Hooked up the discussion post to the backend and return a mock discussions post. Added styling to the discussion posts * Updated CSS to alternate discussion post colors * Added more unit test coverage on the frontend and linted * Added system tests and data-test attributes to go along with it --------- Co-authored-by: Angelina Uno-Antonison * [Frontend] Clicking the "New Discussion" button opens a field below the header line divider to enter an opinion (#151) * New Discussions post button, text field, and save/publish buttons * Displaying posts from an analysis * Added more unit test coverage on the frontend and linted * Toggles New Discussion Field * added system and unit tests for the discussion section * forgot to add the system test * Minor CSS fixes * [Backend] Add a new route and repository to handle an incoming post and save it in Mongo (#153) * Added a new collection to update a new post along with a test and linting * Fixing python unit test * Integration test and linting * Updated the analysis_collection add_discussion_post function to use pymongo find_one_and_update function to simplify how posts are added to discussions in analyses * linting * New migration script to ensure both supporting_evidence_files and discussions keys are added to each analysis object in the analyses collection (#154) * Updated phenotips importer to include supporting_evidence_files and discussions field. Updated the analyses fixture to include these fields as well (#155) * Adding context menu to discussion posts (#156) * added actions to the discussion post context menus * Changed the backend user object to send back the clientId in the basic user object, this is used to check if the user made a post and present a context menu * new ContextMenu.vue duplicates the DropDownMenu.vue functionality and turns it from hover to click. This is not quite right * lots of changes: swapped dropdown and contextmenu icons, contextmenu will now open on click and close when unfocused or an action is taken on the menu. ContextMenu styling changes * Fixed frontend test * Lots of fixes, trying to figure out how to test this * Frontend linting * Removed a .only in front end test * [Backend] Remove and edit post route and methods to update and delete a post from the discussion section (#157) * Added a delete route and delete post analysis collection function * Added a new route for editing a post and matching collection function, also added error checking for different situations in modifying discussion posts in an analysis * Change responsibilities of routes and put helper function to find discussion post in analysis model * proper error handling for discussion posts in progress * Removed the discussion fixtures and properly gets the discussion posts from the analysis * Finished integration and unit tests for updating and deleting a discussion post * Formatting/linting * Fixed integration test * Added unit and integration tests for analysis model and routers * Update backend/src/routers/analysis_discussion_router.py Co-authored-by: Angelina Uno-Antonison Signed-off-by: James Scherer * Update backend/tests/integration/test_analysis_routers.py Co-authored-by: Angelina Uno-Antonison Signed-off-by: James Scherer * linting --------- Signed-off-by: James Scherer Co-authored-by: Angelina Uno-Antonison * [Frontend] The vertical '...' context menu functions to delete posts (#158) * Frontend discussion post deletion working, complete with notification dialog * Adding a system test for successfully deleting a new discussion post * fixing frontend unit tests and adding an extra system test * Linting * Changed the delete action in the context menu to have an emit key and chain the emits down the section to be called in the view to delete a post * Linting and changing var names * Lots of frontend unit tests, but not yet finished * Added more tests and linting * Fixed issue with contextId being renamed * Removed console log * [Frontend] The vertical '...' context menu functions to edit posts (#160) * Frontend discussion post deletion working, complete with notification dialog * Adding a system test for successfully deleting a new discussion post * fixing frontend unit tests and adding an extra system test * Linting * Changed the delete action in the context menu to have an emit key and chain the emits down the section to be called in the view to delete a post * Linting and changing var names * Lots of frontend unit tests, but not yet finished * Added more tests and linting * Fixed issue with contextId being renamed * Removed console log * Edit post emit chain working and backend is saving properly, it's just the discussion content is the same as what's posted * Now editing a post works, it edits the post in place * More styling for the post editing * Frontend linting * Frontend tests and linting * Added system tests for post editing * Update .github/workflows/system-tests.yml Co-authored-by: Angelina Uno-Antonison Signed-off-by: James Scherer * Update backend/src/routers/analysis_router.py Co-authored-by: Angelina Uno-Antonison Signed-off-by: James Scherer * skipping the a test in rosalution_analysis to match main, will come back later --------- Signed-off-by: James Scherer Co-authored-by: Angelina Uno-Antonison --- backend/src/core/phenotips_importer.py | 2 + backend/src/models/analysis.py | 27 + backend/src/models/user.py | 2 +- backend/src/repository/analysis_collection.py | 36 + .../src/routers/analysis_discussion_router.py | 139 + backend/src/routers/analysis_router.py | 2 + backend/tests/fixtures/analysis-CPAM0002.json | 1 + backend/tests/fixtures/empty-pedigree.json | 1 + backend/tests/integration/conftest.py | 2 +- .../integration/test_analysis_routers.py | 170 +- backend/tests/unit/models/test_analysis.py | 48 + .../repository/test_analysis_collection.py | 61 + etc/fixtures/initial-seed/analyses.json | 3679 +++++++++-------- ...e-insert-discussion-and-supporting-keys.js | 66 + .../AnalysisView/DiscussionPost.vue | 202 + .../AnalysisView/DiscussionSection.vue | 179 + frontend/src/components/ContextMenu.vue | 85 + frontend/src/components/RosalutionHeader.vue | 2 +- frontend/src/main.js | 4 +- frontend/src/models/analyses.js | 25 + frontend/src/requests.js | 6 +- frontend/src/stores/authStore.js | 5 +- frontend/src/styles/main.css | 3 +- frontend/src/styles/rosalution.css | 34 +- frontend/src/views/AnalysisView.vue | 66 +- .../AnalysisView/DiscussionPost.spec.js | 125 + .../AnalysisView/DiscussionSection.spec.js | 141 + frontend/test/models/analyses.spec.js | 22 + frontend/test/stores/authStore.spec.js | 3 +- frontend/test/views/AnalysisView.spec.js | 127 +- system-tests/e2e/discussions_analysis.cy.js | 145 + system-tests/e2e/rosalution_analysis.cy.js | 4 +- 32 files changed, 3569 insertions(+), 1845 deletions(-) create mode 100644 backend/src/routers/analysis_discussion_router.py create mode 100644 etc/fixtures/migrations/migrate-insert-discussion-and-supporting-keys.js create mode 100644 frontend/src/components/AnalysisView/DiscussionPost.vue create mode 100644 frontend/src/components/AnalysisView/DiscussionSection.vue create mode 100644 frontend/src/components/ContextMenu.vue create mode 100644 frontend/test/components/AnalysisView/DiscussionPost.spec.js create mode 100644 frontend/test/components/AnalysisView/DiscussionSection.spec.js create mode 100644 system-tests/e2e/discussions_analysis.cy.js diff --git a/backend/src/core/phenotips_importer.py b/backend/src/core/phenotips_importer.py index fb51f8cf..fe0d764f 100644 --- a/backend/src/core/phenotips_importer.py +++ b/backend/src/core/phenotips_importer.py @@ -42,6 +42,8 @@ def import_phenotips_json(self, phenotips_json_data): analysis_data = self.import_analysis_data(phenotips_json_data, phenotips_variants, phenotips_json_data["genes"]) + analysis_data['discussions'] = [] + analysis_data['supporting_evidence_files'] = [] analysis_data['timeline'] = [] return analysis_data diff --git a/backend/src/models/analysis.py b/backend/src/models/analysis.py index afb38f8e..26092271 100644 --- a/backend/src/models/analysis.py +++ b/backend/src/models/analysis.py @@ -80,6 +80,7 @@ class Analysis(BaseAnalysis): genomic_units: List[GenomicUnit] = [] sections: List[Section] = [] + discussions: List = [] supporting_evidence_files: List = [] def units_to_annotate(self): @@ -105,3 +106,29 @@ def units_to_annotate(self): }) return units + + def find_discussion_post(self, discussion_post_id): + """ + Finds a specific discussion post in an analysis by the discussion post id otherwise returns none + if no discussion with that post id in the analysis. + """ + for discussion in self.discussions: + if discussion['post_id'] == discussion_post_id: + return discussion + + return None + + def find_authored_discussion_post(self, discussion_post_id, client_id): + """ + Finds a discussion post from a user that authored the post in an analysis otherwise returns none if the post + was found, but the user did not author the post + """ + discussion_post = self.find_discussion_post(discussion_post_id) + + if discussion_post is None: + raise ValueError(f"Post '{discussion_post_id}' does not exist.") + + if discussion_post['author_id'] == client_id: + return discussion_post + + return None diff --git a/backend/src/models/user.py b/backend/src/models/user.py index bf50717f..9307c0ca 100644 --- a/backend/src/models/user.py +++ b/backend/src/models/user.py @@ -14,11 +14,11 @@ class User(BaseModel): full_name: Optional[str] = None disabled: Optional[bool] = None scope: Optional[str] = None + client_id: str class AccessUserAPI(User): """ This extends the user class to include the user's credentials for API access """ - client_id: str client_secret: Optional[str] = None diff --git a/backend/src/repository/analysis_collection.py b/backend/src/repository/analysis_collection.py index 1e015141..9a2c53d0 100644 --- a/backend/src/repository/analysis_collection.py +++ b/backend/src/repository/analysis_collection.py @@ -486,3 +486,39 @@ def remove_section_supporting_evidence(self, analysis_name: str, section_name: s return_field = {"header": section_name, "field": field_name} return return_field + + def add_discussion_post(self, analysis_name: str, discussion_post: object): + """ Appends a new discussion post to an analysis """ + + updated_document = self.collection.find_one_and_update({"name": analysis_name}, + {"$push": {"discussions": discussion_post}}, + return_document=ReturnDocument.AFTER) + + updated_document.pop("_id", None) + + return updated_document['discussions'] + + def updated_discussion_post(self, discussion_post_id: str, discussion_content: str, analysis_name: str): + """ Edits a discussion post from an analysis to update the discussion post's content """ + + updated_document = self.collection.find_one_and_update({"name": analysis_name}, { + "$set": {"discussions.$[item].content": discussion_content} + }, + array_filters=[{"item.post_id": discussion_post_id}], + return_document=ReturnDocument.AFTER) + + updated_document.pop("_id", None) + + return updated_document['discussions'] + + def delete_discussion_post(self, discussion_post_id: str, analysis_name: str): + """ Removes a discussion post from an analysis """ + + updated_document = self.collection.find_one_and_update({"name": analysis_name}, { + "$pull": {"discussions": {"post_id": discussion_post_id}} + }, + return_document=ReturnDocument.AFTER) + + updated_document.pop("_id", None) + + return updated_document['discussions'] diff --git a/backend/src/routers/analysis_discussion_router.py b/backend/src/routers/analysis_discussion_router.py new file mode 100644 index 00000000..ec0cda66 --- /dev/null +++ b/backend/src/routers/analysis_discussion_router.py @@ -0,0 +1,139 @@ +# pylint: disable=too-many-arguments +# Due to adding scope checks, it's adding too many arguments (7/6) to functions, so diabling this for now. +# Need to refactor later. +""" Analysis endpoint routes that provide an interface to interact with an Analysis' discussions """ +from datetime import datetime, timezone +import logging +from uuid import uuid4 + +from fastapi import (APIRouter, Depends, Form, Security, HTTPException, status) + +from ..dependencies import database +from ..models.user import VerifyUser +from ..models.analysis import Analysis +from ..security.security import get_current_user + +logger = logging.getLogger(__name__) + +router = APIRouter(tags=["analysis"], dependencies=[Depends(database)]) + + +@router.get("/{analysis_name}/discussions") +def get_analysis_discussions(analysis_name: str, repositories=Depends(database)): + """ Returns a list of discussion posts for a given analysis """ + logger.info("Retrieving the analysis '%s' discussions ", analysis_name) + + found_analysis = repositories['analysis'].find_by_name(analysis_name) + + if not found_analysis: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail=f"Analysis '{analysis_name}' does not exist.'" + ) + + analysis = Analysis(**found_analysis) + + return analysis.discussions + + +@router.post("/{analysis_name}/discussions") +def add_analysis_discussion( + analysis_name: str, + discussion_content: str = Form(...), + repositories=Depends(database), + client_id: VerifyUser = Security(get_current_user) +): + """ Adds a new analysis topic """ + logger.info("Adding the analysis '%s' from user '%s'", analysis_name, client_id) + logger.info("The message: %s", discussion_content) + + found_analysis = repositories['analysis'].find_by_name(analysis_name) + + if not found_analysis: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, detail=f"Analysis '{analysis_name}' does not exist.'" + ) + + analysis = Analysis(**found_analysis) + current_user = repositories["user"].find_by_client_id(client_id) + + new_discussion_post = { + "post_id": str(uuid4()), + "author_id": client_id, + "author_fullname": current_user["full_name"], + "publish_timestamp": datetime.now(timezone.utc), + "content": discussion_content, + "attachments": [], + "thread": [], + } + + return repositories['analysis'].add_discussion_post(analysis.name, new_discussion_post) + + +@router.put("/{analysis_name}/discussions/{discussion_post_id}") +def update_analysis_discussion_post( + analysis_name: str, + discussion_post_id: str, + discussion_content: str = Form(...), + repositories=Depends(database), + client_id: VerifyUser = Security(get_current_user) +): + """ Updates a discussion post's content in an analysis by the discussion post id """ + logger.info( + "Editing post '%s' by user '%s' from the analysis '%s' with new content: '%s'", discussion_post_id, client_id, + analysis_name, discussion_content + ) + + found_analysis = repositories['analysis'].find_by_name(analysis_name) + + if not found_analysis: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=f"Analysis '{analysis_name}' does not exist. Unable to update discussion post.'" + ) + + analysis = Analysis(**found_analysis) + + try: + valid_post = analysis.find_authored_discussion_post(discussion_post_id, client_id) + except ValueError as e: + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e)) from e + + if not valid_post: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, detail="User cannot update post they did not author." + ) + + return repositories['analysis'].updated_discussion_post(valid_post['post_id'], discussion_content, analysis.name) + + +@router.delete("/{analysis_name}/discussions/{discussion_post_id}") +def delete_analysis_discussion( + analysis_name: str, + discussion_post_id: str, + repositories=Depends(database), + client_id: VerifyUser = Security(get_current_user) +): + """ Deletes a discussion post in an analysis by the discussion post id """ + logger.info("Deleting post %s by user '%s' from the analysis '%s'", discussion_post_id, client_id, analysis_name) + + found_analysis = repositories['analysis'].find_by_name(analysis_name) + + if not found_analysis: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=f"Analysis '{analysis_name}' does not exist. Unable to delete discussion post.'" + ) + + analysis = Analysis(**found_analysis) + + try: + valid_post = analysis.find_authored_discussion_post(discussion_post_id, client_id) + except ValueError as e: + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e)) from e + + if not valid_post: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, detail="User cannot delete post they did not author." + ) + + return repositories['analysis'].delete_discussion_post(valid_post['post_id'], analysis.name) diff --git a/backend/src/routers/analysis_router.py b/backend/src/routers/analysis_router.py index 93b15536..85726cbf 100644 --- a/backend/src/routers/analysis_router.py +++ b/backend/src/routers/analysis_router.py @@ -21,10 +21,12 @@ from ..models.phenotips_json import BasePhenotips from ..models.user import VerifyUser from ..security.security import get_authorization, get_current_user +from . import analysis_discussion_router logger = logging.getLogger(__name__) router = APIRouter(prefix="/analysis", tags=["analysis"], dependencies=[Depends(database)]) +router.include_router(analysis_discussion_router.router) @router.get("/", response_model=List[Analysis]) diff --git a/backend/tests/fixtures/analysis-CPAM0002.json b/backend/tests/fixtures/analysis-CPAM0002.json index ceac7f75..f38613bd 100644 --- a/backend/tests/fixtures/analysis-CPAM0002.json +++ b/backend/tests/fixtures/analysis-CPAM0002.json @@ -222,6 +222,7 @@ ] } ], + "discussions":[], "supporting_evidence_files": [ { "name": "test.txt", diff --git a/backend/tests/fixtures/empty-pedigree.json b/backend/tests/fixtures/empty-pedigree.json index fdc4f552..98d7fd93 100644 --- a/backend/tests/fixtures/empty-pedigree.json +++ b/backend/tests/fixtures/empty-pedigree.json @@ -216,6 +216,7 @@ ] } ], + "discussions":[], "supporting_evidence_files": [ { "name": "test.txt", diff --git a/backend/tests/integration/conftest.py b/backend/tests/integration/conftest.py index 832277d1..456560a3 100644 --- a/backend/tests/integration/conftest.py +++ b/backend/tests/integration/conftest.py @@ -74,7 +74,7 @@ def mock_current_user(): @pytest.fixture(name="mock_user") def test_auth_user(): """A mocked user that can be used to generate an OAuth2 access token""" - return {"sub": "johndoe", "scopes": ["read", "write"]} + return {"sub": "johndoe-client-id", "scopes": ["read", "write"]} @pytest.fixture(name="mock_access_token") diff --git a/backend/tests/integration/test_analysis_routers.py b/backend/tests/integration/test_analysis_routers.py index e9ca9af3..87c72028 100644 --- a/backend/tests/integration/test_analysis_routers.py +++ b/backend/tests/integration/test_analysis_routers.py @@ -80,7 +80,7 @@ def test_import_analysis_with_phenotips_json( assert response.status_code == 200 response_data = json.loads(response.text) assert response_data['latest_status'] == "Preparation" - assert response_data['timeline'][0]['username'] == 'johndoe' + assert response_data['timeline'][0]['username'] == 'johndoe-client-id' def test_update_analysis_section(client, mock_access_token, mock_repositories, update_analysis_section_response_json): @@ -366,6 +366,174 @@ def test_mark_ready_analysis_does_not_exist(client, mock_access_token, mock_repo assert response.json() == {'detail': 'Analysis with name CPAM2222 does not exist.'} +def test_add_new_discussion_to_analysis(client, mock_access_token, mock_repositories, cpam0002_analysis_json): + """ Testing that a discussion was added and returned properly """ + cpam_analysis = "CPAM0002" + new_post_user = "John Doe" + new_post_content = "Integration Test Text" + + def valid_query_side_effect(*args, **kwargs): # pylint: disable=unused-argument + find, query = args # pylint: disable=unused-variable + analysis = cpam0002_analysis_json + analysis['discussions'].append(query['$push']['discussions']) + analysis['_id'] = 'fake-mongo-object-id' + return analysis + + mock_repositories["user"].collection.find_one.return_value = {"full_name": new_post_user} + mock_repositories['analysis'].collection.find_one.return_value = cpam0002_analysis_json + mock_repositories["analysis"].collection.find_one_and_update.side_effect = valid_query_side_effect + + response = client.post( + "/analysis/" + cpam_analysis + "/discussions", + headers={"Authorization": "Bearer " + mock_access_token}, + data={"discussion_content": new_post_content} + ) + + assert response.status_code == 200 + + assert len(response.json()) == 4 + + actual_most_recent_post = response.json().pop() + + assert actual_most_recent_post['author_fullname'] == new_post_user + assert actual_most_recent_post['content'] == new_post_content + + +def test_update_discussion_post_in_analysis(client, mock_access_token, mock_repositories, cpam0002_analysis_json): + """ Tests successfully updating an existing post in the discussions with the user being the author """ + cpam_analysis = "CPAM0002" + discussion_post_id = "fake-post-id" + discussion_content = "I am an integration test post. Look at me!" + + # Inject a new discussion post by John Doe + def valid_query_side_effect_one(*args, **kwargs): # pylint: disable=unused-argument + analysis = cpam0002_analysis_json + + new_discussion_post = { + "post_id": "fake-post-id", "author_id": "johndoe-client-id", "author_fullname": 'johndoe', + "content": "Hello, I am a discussion post." + } + + analysis['discussions'].append(new_discussion_post) + analysis['_id'] = 'fake-mongo-object-id' + return analysis + + def valid_query_side_effect_two(*args, **kwargs): # pylint: disable=unused-argument + find, query = args # pylint: disable=unused-variable + query_filter = kwargs + + analysis = cpam0002_analysis_json + fake_post_content = query['$set']['discussions.$[item].content'] + fake_post_id = query_filter['array_filters'][0]['item.post_id'] + + for d in analysis['discussions']: + if d['post_id'] == fake_post_id: + d['content'] = fake_post_content + + analysis['_id'] = 'fake-mongo-object-id' + + return analysis + + mock_repositories['analysis'].collection.find_one.side_effect = valid_query_side_effect_one + mock_repositories["analysis"].collection.find_one_and_update.side_effect = valid_query_side_effect_two + + response = client.put( + "/analysis/" + cpam_analysis + "/discussions/" + discussion_post_id, + headers={"Authorization": "Bearer " + mock_access_token}, + data={"discussion_content": discussion_content} + ) + + actual_post = None + + for d in response.json(): + if d['post_id'] == discussion_post_id: + actual_post = d + + assert len(response.json()) == 4 + assert actual_post['content'] == discussion_content + + +def test_update_post_in_analysis_author_mismatch(client, mock_access_token, mock_repositories, cpam0002_analysis_json): + """ Tests updating a post that the author did not post and results in an unauthorized failure """ + cpam_analysis = "CPAM0002" + discussion_post_id = "9027ec8d-6298-4afb-add5-6ef710eb5e98" + discussion_content = "I am an integration test post. Look at me!" + + mock_repositories['analysis'].collection.find_one.return_value = cpam0002_analysis_json + + response = client.put( + "/analysis/" + cpam_analysis + "/discussions/" + discussion_post_id, + headers={"Authorization": "Bearer " + mock_access_token}, + data={"discussion_content": discussion_content} + ) + + expected_failure_detail = {'detail': 'User cannot update post they did not author.'} + + assert response.status_code == 401 + assert response.json() == expected_failure_detail + + +def test_delete_discussion_post_in_analysis(client, mock_access_token, mock_repositories, cpam0002_analysis_json): + """ Tests successfully deleting an existing post in the discussions with the user being the author """ + cpam_analysis = "CPAM0002" + discussion_post_id = "fake-post-id" + + # Inject a new discussion post by John Doe + def valid_query_side_effect_one(*args, **kwargs): # pylint: disable=unused-argument + analysis = cpam0002_analysis_json + + new_discussion_post = { + "post_id": "fake-post-id", + "author_id": "johndoe-client-id", + "author_fullname": 'johndoe', + } + + analysis['discussions'].append(new_discussion_post) + analysis['_id'] = 'fake-mongo-object-id' + return analysis + + def valid_query_side_effect_two(*args, **kwargs): # pylint: disable=unused-argument + find, query = args # pylint: disable=unused-variable + + analysis = cpam0002_analysis_json + fake_post_id = query['$pull']['discussions']['post_id'] + + analysis['discussions'] = [x for x in analysis['discussions'] if fake_post_id not in x['post_id']] + analysis['_id'] = 'fake-mongo-object-id' + + return analysis + + mock_repositories['analysis'].collection.find_one.side_effect = valid_query_side_effect_one + mock_repositories["analysis"].collection.find_one_and_update.side_effect = valid_query_side_effect_two + + response = client.delete( + "/analysis/" + cpam_analysis + "/discussions/" + discussion_post_id, + headers={"Authorization": "Bearer " + mock_access_token} + ) + + assert len(response.json()) == 3 + + +def test_handle_delete_post_not_existing_in_analysis( + client, mock_access_token, mock_repositories, cpam0002_analysis_json +): + """ Tests failure of deleting a discussion post but does not exist in the analysis """ + cpam_analysis = "CPAM0002" + discussion_post_id = "fake-post-id" + + mock_repositories['analysis'].collection.find_one.return_value = cpam0002_analysis_json + + response = client.delete( + "/analysis/" + cpam_analysis + "/discussions/" + discussion_post_id, + headers={"Authorization": "Bearer " + mock_access_token} + ) + + expected_failure_detail = {'detail': f"Post '{discussion_post_id}' does not exist."} + + assert response.status_code == 404 + assert response.json() == expected_failure_detail + + @pytest.fixture(name="analysis_updates_json") def fixture_analysis_updates_json(): """The JSON that is being sent from a client to the endpoint with updates in it""" diff --git a/backend/tests/unit/models/test_analysis.py b/backend/tests/unit/models/test_analysis.py index acd166b4..e7874fad 100644 --- a/backend/tests/unit/models/test_analysis.py +++ b/backend/tests/unit/models/test_analysis.py @@ -33,6 +33,54 @@ def test_get_transcripts_in_units_to_annotate(units_to_annotate): assert "NM_001017980.3" in transcript_names +def test_find_dicussion_post(cpam0002_analysis): + """ Finds a discussion post matching the post_id """ + found_post = cpam0002_analysis.find_discussion_post("9027ec8d-6298-4afb-add5-6ef710eb5e98") + + assert found_post['author_id'] == '3bghhsmnyqi6uxovazy07ryn9q1tqbnt' + assert found_post['author_fullname'] == 'Developer Person' + + +def test_find_dicussion_post_not_found(cpam0002_analysis): + """ Finds a discussion post matching the post_id """ + found_post = cpam0002_analysis.find_discussion_post("fake-post-id-failure") + + assert found_post is None + + +def test_find_authored_discussion_post(cpam0002_analysis): + """ Tests that a discussion post is returned matching a post id and client id """ + discussion_post_id = "e6023fa7-b598-416a-9f42-862c826255ef" + client_id = 'exqkhvidr7uh2ndslsdymbzfbmqjlunk' + + found_post = cpam0002_analysis.find_authored_discussion_post(discussion_post_id, client_id) + + assert found_post['author_id'] == client_id + assert found_post['author_fullname'] == 'Variant Review Report Preparer Person' + + +def test_find_authored_discussion_post_failure_missing_post(cpam0002_analysis): + """ Tests that a ValueError is thrown if no discussion post is found matching the post_id """ + discussion_post_id = "fake-post-id-failure" + client_id = 'exqkhvidr7uh2ndslsdymbzfbmqjlunk' + + try: + cpam0002_analysis.find_authored_discussion_post(discussion_post_id, client_id) + except ValueError as error: + assert isinstance(error, ValueError) + assert str(error) == f"Post '{discussion_post_id}' does not exist." + + +def test_find_authored_discussion_post_author_mismatch(cpam0002_analysis): + """ Test that no post is returned if a post is found, but the author's client id does not match """ + discussion_post_id = "e6023fa7-b598-416a-9f42-862c826255ef" + client_id = 'fake-client-id-failure' + + found_post = cpam0002_analysis.find_authored_discussion_post(discussion_post_id, client_id) + + assert found_post is None + + @pytest.fixture(name="units_to_annotate") def fixture_units_to_annotate(cpam0002_analysis): """Fixture for the units to annotate for the CPAM0002 Analysis""" diff --git a/backend/tests/unit/repository/test_analysis_collection.py b/backend/tests/unit/repository/test_analysis_collection.py index 64cf57ac..465a3c44 100644 --- a/backend/tests/unit/repository/test_analysis_collection.py +++ b/backend/tests/unit/repository/test_analysis_collection.py @@ -380,6 +380,67 @@ def test_remove_section_supporting_evidence(analysis_collection): assert expected == actual +def test_add_discussion_post_to_analysis(analysis_collection, cpam0002_analysis_json): + """ Tests adding a user's discussion post to an analysis """ + + def valid_query_side_effect(*args, **kwargs): # pylint: disable=unused-argument + find, query = args # pylint: disable=unused-variable + updated_analysis = cpam0002_analysis_json + updated_analysis['discussions'].append(query['$push']['discussions']) + updated_analysis['_id'] = 'fake-mongo-object-id' + return updated_analysis + + analysis_collection.collection.find_one_and_update.side_effect = valid_query_side_effect + + new_post = { + "post_id": "a677bb36-acf8-4ff9-a406-b113a7952f7e", "author_id": "kw0g790fdx715xsr1ead2jk0pqubtlyz", + "author_fullname": "Researcher Person", "publish_timestamp": "2023-10-10T21:13:22.687000", + "content": "Mauris at mauris eu neque varius suscipit.", "attachments": [], "thread": [] + } + + actual = analysis_collection.add_discussion_post("CPAM0002", new_post) + + assert len(actual) == 4 + + actual_most_recent_post = actual.pop() + + assert actual_most_recent_post == new_post + + +def test_update_discussion_post_in_analysis(analysis_collection): + """ Tests updating the content of a user's post from an analysis by the post id""" + analysis_collection.collection.find_one_and_update.return_value = {"discussions": []} + + discussion_post_id = "9027ec8d-6298-4afb-add5-6ef710eb5e98" + discussion_content = "This is new content." + analysis_name = "CPAM0002" + + expected_find = {"name": analysis_name} + expected_update = {"$set": {"discussions.$[item].content": discussion_content}} + expected_filter = [{"item.post_id": discussion_post_id}] + + analysis_collection.updated_discussion_post(discussion_post_id, discussion_content, analysis_name) + analysis_collection.collection.find_one_and_update.assert_called_once_with( + expected_find, expected_update, array_filters=expected_filter, return_document=True + ) + + +def test_delete_discussion_post_in_analysis(analysis_collection): + """ Tests deleting a user's discussion post from an analysis by the post id """ + analysis_collection.collection.find_one_and_update.return_value = {"discussions": []} + + discussion_post_id = "9027ec8d-6298-4afb-add5-6ef710eb5e98" + analysis_name = "CPAM0002" + + expected_find = {"name": analysis_name} + expected_update = {"$pull": {"discussions": {"post_id": discussion_post_id}}} + + analysis_collection.delete_discussion_post(discussion_post_id, analysis_name) + analysis_collection.collection.find_one_and_update.assert_called_with( + expected_find, expected_update, return_document=True + ) + + @pytest.fixture(name="analysis_with_no_p_dot") def fixture_analysis_with_no_p_dot(): """Returns an analysis with no p. in the genomic unit""" diff --git a/etc/fixtures/initial-seed/analyses.json b/etc/fixtures/initial-seed/analyses.json index b4adc2d3..ffa4c6be 100644 --- a/etc/fixtures/initial-seed/analyses.json +++ b/etc/fixtures/initial-seed/analyses.json @@ -1,1815 +1,1868 @@ [ - { - "name":"CPAM0002", - "description":"Vacuolar myopathy with autophagy, X-linked vacuolar myopathy with autophagy", - "nominated_by":"Dr. Person One", - "genomic_units":[ - { - "gene":"VMA21", - "transcripts":[ - { - "transcript":"NM_001017980.3" - } - ], - "variants":[ - { - "hgvs_variant":"NM_001017980.3:c.164G>T", - "c_dot":"c.164G>T", - "p_dot":"p.Gly55Val", - "build":"hg19", - "case":[ - { - "field":"Evidence", - "value":[ - "Array" - ] - }, - { - "field":"Other Datasource", - "value":[ - "Array" - ] - }, - { - "field":"Interpretation", - "value":[ - "Array" - ] - } - ] - } - ] - } - ], - "sections":[ - { - "header":"Brief", - "content":[ - { - "type":"section-text", - "field":"Nominator", - "value":[ - "Dr. Person One" - ] - }, - { - "type":"section-text", - "field":"Participant", - "value":[ - "1 patient, carrier mother" - ] - }, - { - "type":"section-text", - "field":"Phenotype", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"ACMG Classification", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"ACMG Classification Criteria", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"ACMG Criteria To Add", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Decision", - "value":[ - - ] - } - ] - }, - { - "header":"Clinical History", - "content":[ - { - "type":"section-text", - "field":"Clinical Diagnosis", - "value":[ - "Vacuolor myopathy with autophagy, X-linked vacuolor myopathy with autophagy" - ] - }, - { - "type":"section-text", - "field":"Affected Individuals Identified", - "value":[ - "1 patient, carrier mother", - "Maternal grandfather with myopathy.", - "Mother has muscle signal changes on MRI", - "Thus presumed to be an X-linked myopathy" - ] - }, - { - "type":"section-text", - "field":"Sequencing", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Testing", - "value":[ - "- DMD, LAMP2, myofibrillar myopathy panel performed testing for BAG3, crystalline B, desmin, DNAJB6, FLH1, LDB3, and myotilin. Non diagnostic.", - "- DMD testing revealed a hemizygous variant of unknown significance in the DMD gene.", - "- Fulgent Diagnostics identified a hemizygous VUS in the VMA21(XMEA); c.164G>T (p.Gly55Val). His mother also carried this variant." - ] - }, - { - "type":"section-text", - "field":"Systems", - "value":[ - "Musculoskeletal and orthopedics" - ] - }, - { - "type":"section-text", - "field":"Additional Details", - "value":[ - "8 yo male at time of testing. Ambulatory. Myopathy starting from 2 years of age with falls, elevated CK, and myopathic muscle biopsy. Clinical course is slowly progressive.", - "Exam showed proximal limb girdle pattern of weakness. Proximal upper and lower extremity weakness. Myopathy Congenital myopathy. Diminished muscle bulk / eps. scapular, Lordotic gait.", - "Muscle biopsy (2014) showed fiber size variability with prominent perimysial fibrous tissue; scattered myofibers with vacuoles staining dark blue with trichome and positive PAS staining; normal enzyme activity for phosphorylase, myoadenylase and phosphofructokinase.", - "Electron microscopy (2014) showed membrane bound vacuoles which contain glycogen and degenerated mitochondria; some of these vacuoles contain secondary lysosomes.", - "CK level 1121U/L.", - "Mode of Inheritance", - "X linked" - ] - } - ] - }, - { - "header":"Mus musculus (Mouse) Model System", - "content":[ - { - "type":"section-text", - "field":"Mutation", - "value":[ - "NF1 c.2970-2972del (p.Met992del)" - ] - }, - { - "type":"section-text", - "field":"Pathogenicity Test", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Design", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Founder Screening/Expansion", - "value":[ - "Mice during embryogenesis P1 and E16.5 animals exhibit a double-outlet right ventricle VSD. The surviving mice with this genotype are suspected to not have the VSD. " - ] - }, - { - "type":"section-text", - "field":"Screening", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"History", - "value":[ - "Animals were submitted for a full pathology screen of the heart and other tissues as a part of CPAM workup to confirm this phenotype and develop a more thorough characterization of this mutation. Submitted 3 homozygous males 4-6 months old and a littermate control for necropsy and histopathology." - ] - }, - { - "type":"section-text", - "field":"Diagnoses", - "value":[ - "Lungs, pyogranulomatous bronchopneumonia, chronic, multifocal, moderate to marked (suggestive of an aspiration pneumonia) Ear canal, suppurative otitis media, chronic, bilateral, severe" - ] - }, - { - "type":"section-text", - "field":"Remarks", - "value":[ - "Findings in mutant mice are consistent in all 3 animals examined. Dilation of proximal esophagus was noted in 2/3 animals examined with minimal evidence of inflammation. Overall the etiology is unclear, but I suspect the cause of aspiration pneumonia was a result of dysphagia (Oropharyngeal dysphagia), possibly involving innervation and normal function of the esophagus.", - "NF1 patients do exhibit dysphagia and alterations in vocal quality, however, these changes are secondary to neurofibromas involving the innervation at these sites (esophagus and layrnx). There was no evidence of peripheral neurofibromas were noted in innervation to the esophagus or other organs or spinal plexiform ganglia or within the central nervous system.", - "Additional characterization of the cause of aspiration pneumonia is recommended, specifically functional assessment of swallowing to determine if dysphagia is present.", - "The etiology of bilateral middle ear infections seen in 2/3 animals with NF1 mutation, is uncertain." - ] - }, - { - "type":"section-supporting-evidence", - "field":"Veterinary Histology Report", - "value":[] - }, - { - "type":"section-supporting-evidence", - "field":"Veterinary Pathology Imaging", - "value":[] - } - ] - }, - { - "header":"Pedigree", - "attachment_field":"Pedigree", - "content":[ - { - "type":"images-dataset", - "field":"Pedigree", - "value":[ - - ] - } - ] - }, - { - "header":"VMA21 Gene To Phenotype", - "attachment_field":"VMA21 Gene To Phenotype", - "content":[ - { - "type":"images-dataset", - "field":"VMA21 Gene To Phenotype", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"HPO Terms", - "value":[ - "HP:0003198; HP:0003797; HP:0003325; HP:0008997; HP:0008994; HP:0001288; HP:0009060; HP:0004303; HP:0012103; HP:0003736" - ] - } - ] - }, - { - "header":"VMA21 Molecular Mechanism", - "content":[ - { - "type":"section-text", - "field":"Function Overview", - "value":[ - - ] - } - ] - }, - { - "header":"VMA21 Function", - "attachment_field":"VMA21 Function", - "content":[ - { - "type":"images-dataset", - "field":"VMA21 Function", - "value":[ - - ] - } - ] - }, - { - "header":"Model Goals", - "content":[ - { - "type":"section-text", - "field":"Model of Interest", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Goals", - "value":[ - "Review of ACMG classification", - "Functional impact study (in silico/animal/cell modeling)", - "Therapeutic predictions (in silico predictions)" - ] - }, - { - "type":"section-text", - "field":"Proposed Model/Project", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Existing Collaborations", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Existing Funding", - "value":[ - - ] - } - ] - } - ], - "supporting_evidence_files":[ - - ], - "timeline":[ - { - "event":"create", - "timestamp":"2022-10-09T21:13:22.687000", - "username":"vrr-prep" - }, - { - "event":"ready", - "timestamp":"2022-10-09T21:14:22.687000", - "username":"vrr-prep" - }, - { - "event":"opened", - "timestamp":"2022-10-09T21:15:22.687000", - "username":"vrr-prep" - }, - { - "event":"approve", - "timestamp":"2022-10-09T21:16:22.687000", - "username":"vrr-prep" - } - ] - }, - { - "name":"CPAM0046", - "description":": LMNA-related congenital muscular dystropy", - "nominated_by":"Dr. Person Two", - "genomic_units":[ - { - "gene":"LMNA", - "transcripts":[ - { - "transcript":"NM_170707.3" - } - ], - "variants":[ - { - "hgvs_variant":"NM_170707.3:c.745C>T", - "c_dot":"c.745C>T", - "p_dot":"p.R249W", - "build":"hg19", - "case":[ - { - "field":"Evidence", - "value":[ - "PS2", - "PS3", - "PM2", - "PP3", - "PP5" - ] - }, - { - "field":"Interpretation", - "value":[ - "Pathogenic" - ] - }, - { - "field":"Inheritance", - "value":[ - "De Novo" - ] - } - ] - } - ] - } - ], - "sections":[ - { - "header":"Brief", - "content":[ - { - "type":"section-text", - "field":"Nominator", - "value":[ - "Dr. Person Two (Local) - working with Dr. Person Three in Person Four Lab" - ] - }, - { - "type":"section-text", - "field":"Participant", - "value":[ - "Male, YOB: 2019" - ] - }, - { - "type":"section-text", - "field":"Phenotype", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"ACMG Classification", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"ACMG Classification Criteria", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"ACMG Criteria To Add", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Decision", - "value":[ - - ] - } - ] - }, - { - "header":"Clinical History", - "content":[ - { - "type":"section-text", - "field":"Clinical Diagnosis", - "value":[ - "LMNA-related congenital muscular dystropy" - ] - }, - { - "type":"section-text", - "field":"Affected Individuals Identified", - "value":[ - "Male, YOB: 2019" - ] - }, - { - "type":"section-text", - "field":"Sequencing", - "value":[ - "WES" - ] - }, - { - "type":"section-text", - "field":"Testing", - "value":[ - "WES - February 2020;" - ] - }, - { - "type":"section-text", - "field":"Systems", - "value":[ - "Growth Parameters; Craniofacial; Musculoskeletal; Gastrointestinal; Behavior, Cognition and Development; Neurological" - ] - }, - { - "type":"section-text", - "field":"Additional Details", - "value":[ - "Review of VUSes (Why not considered)", - "NEB (NM_001164508.1) | c.7385C>G (p.A2462G) (Pat.) and c.16625A>G (p.H5542R) (Mat.).", - " - Associated with Nemaline myopathy 2, autosomal recessive", - " - Both variants are still classified as VUS (last evaluated Feb 2020)", - " - 195 out of 203 (96.1%) non-VUS missense variants in gene NEB are benign", - " ", - "LYZL6 (NM_020426.2) | c.228G>C (p.Q76H) (Mat./Pat.)", - " - Lysozyme Like 6.", - " - No currently known disease associations.", - " ", - "NOL6 (NM_022917.4) | c.518G>A (p.R173Q) (Pat.) and c.91G>A (p.G31R) (Mat.).", - " - Nucleolar protein 6.", - " - No currently known disease associations" - ] - } - ] - }, - { - "header":"Pedigree", - "attachment_field":"Pedigree", - "content":[ - { - "type":"images-dataset", - "field":"Pedigree", - "value":[ - - ] - } - ] - }, - { - "header":"LMNA Gene To Phenotype", - "attachment_field":"LMNA Gene To Phenotype", - "content":[ - { - "type":"images-dataset", - "field":"LMNA Gene To Phenotype", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"HPO Terms", - "value":[ - "HP:0001508:Failure to thrive; HP:0001357:Plagiocephaly; HP:0000473:Torticollis; HP:0003560:Muscular dystrophy; HP:0003701:Proximal muscle weakness; HP:0009062:Infantile axial hypotonia; HP:0012389:Appendicular hypotonia; HP: 0003236:Elevated serum creatine kinase; HP:0002020:Gastroesophageal reflux; HP:0011471:Gastrostomy tube feeding in infancy; HP:0011968:Feeding difficulties; HP:0001263:Global developmental delay; HP:0001265:Hyproflexia; HP:0032988:Persistent head lag; HP:0000960:Sacral dimple;" - ] - } - ] - }, - { - "header":"LMNA Molecular Mechanism", - "content":[ - { - "type":"section-text", - "field":"Function Overview", - "value":[ - - ] - } - ] - }, - { - "header":"LMNA Function", - "attachment_field":"LMNA Function", - "content":[ - { - "type":"images-dataset", - "field":"LMNA Function", - "value":[ - - ] - } - ] - }, - { - "header":"Model Goals", - "content":[ - { - "type":"section-text", - "field":"Model of Interest", - "value":[ - "Zebrafish" - ] - }, - { - "type":"section-text", - "field":"Goals", - "value":[ - "Functional impact confirmation (animal/cell modeling)", - "Therapeutic predictions (in-silico predictions)", - "Downstream applications (sharing model to conduct larger drug screens)" - ] - }, - { - "type":"section-text", - "field":"Proposed Model/Project", - "value":[ - "Contribute a dominant negative patient-variant model to the existing zebrafish model (LOF; in-progress)", - "Will be used in NBL 240: a research-based undergraduate course at UAB" - ] - }, - { - "type":"section-text", - "field":"Existing Collaborations", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Existing Funding", - "value":[ - - ] - } - ] - } - ], - "timeline":[ - { - "event":"create", - "timestamp":"2022-10-09T21:13:22.687000", - "username":"vrr-prep" - }, - { - "event":"ready", - "timestamp":"2022-10-09T21:14:22.687000", - "username":"vrr-prep" - }, - { - "event":"opened", - "timestamp":"2022-10-09T21:15:22.687000", - "username":"vrr-prep" - }, - { - "event":"approve", - "timestamp":"2022-10-09T21:16:22.687000", - "username":"vrr-prep" - } - ] - }, - { - "name":"CPAM0047", - "description":"Congenital variant of Rett syndrome", - "genomic_units":[ - { - "gene":"SBF1", - "transcripts":[ - { - "transcript":"NM_002972.2" - } - ], - "variants":[ - { - "hgvs_variant":"NM_002972.2:c.3493_3494dupTA", - "c_dot":"c.3493_3494dupTA", - "p_dot":"Pro1166ThrfsX5", - "build":"hg19", - "case":[ - - ] - }, - { - "hgvs_variant":"NM_002972.2:c.5474_5475delTG", - "c_dot":"c.5474_5475delTG", - "p_dot":"Val1825GlyfsX27", - "build":"hg19", - "case":[ - - ] - } - ] - } - ], - "nominated_by":"CMT4B3 Foundation", - "sections":[ - { - "header":"Brief", - "content":[ - { - "type":"section-text", - "field":"Nominator", - "value":[ - "CMT4B3 Foundation" - ] - }, - { - "type":"section-text", - "field":"Participant", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Phenotype", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"ACMG Classification", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"ACMG Classification Criteria", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"ACMG Criteria To Add", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Decision", - "value":[ - - ] - } - ] - }, - { - "header":"Clinical History", - "content":[ - { - "type":"section-text", - "field":"Clinical Diagnosis", - "value":[ - "Mild Zellweger Spectrum Disorder (a Peroxisome Biogenesis Disorder)", - "Current clinical manifestation is cerebellar ataxia that has impeded gross motor development." - ] - }, - { - "type":"section-text", - "field":"Affected Individuals Identified", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Sequencing", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Testing", - "value":[ - " - Invitae Boosted Exome in 2019" - ] - }, - { - "type":"section-text", - "field":"Systems", - "value":[ - "Craniofacial, Eye Defects, Cutaneous, Musculoskeletal, Behavior, Cognition and Development, Neurological" - ] - }, - { - "type":"section-text", - "field":"Additional Details", - "value":[ - "Symptoms: postural instability, delayed gross motor development, generalized hypotonia, generalized hypotonia due to defect at the neuromuscular junction, motor delay, abnormality of the dentate nucleus, abnormality of the periventricular white matter, poor motor coordination, and congenital nystagmus " - ] - } - ] - }, - { - "header":"Pedigree", - "attachment_field":"Pedigree", - "content":[ - { - "type":"images-dataset", - "field":"Pedigree", - "value":[ - - ] - } - ] - }, - { - "header":"SBF1 Gene To Phenotype", - "attachment_field":"SBF1 Gene To Phenotype", - "content":[ - { - "type":"images-dataset", - "field":"SBF1 Gene To Phenotype", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"HPO Terms", - "value":[ - - ] - } - ] - }, - { - "header":"SBF1 Molecular Mechanism", - "content":[ - { - "type":"section-text", - "field":"Function Overview", - "value":[ - - ] - } - ] - }, - { - "header":"SBF1 Function", - "attachment_field":"SBF1 Function", - "content":[ - { - "type":"images-dataset", - "field":"SBF1 Function", - "value":[ - - ] - } - ] - }, - { - "header":"Model Goals", - "content":[ - { - "type":"section-text", - "field":"Model of Interest", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Goals", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Proposed Model/Project", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Existing Collaborations", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Existing Funding", - "value":[ - - ] - } - ] - } - ], - "timeline":[ - { - "event":"create", - "timestamp":"2022-10-09T21:13:22.687000", - "username":"vrr-prep" - }, - { - "event":"ready", - "timestamp":"2022-10-09T21:14:22.687000", - "username":"vrr-prep" - }, - { - "event":"opened", - "timestamp":"2022-10-09T21:15:22.687000", - "username":"vrr-prep" - }, - { - "event":"decline", - "timestamp":"2022-10-09T21:16:22.687000", - "username":"vrr-prep" - } - ] - }, - { - "name":"CPAM0053", - "description":"Mild Zellweger Spectrum Disorder, a Peroxisome Biogenesis Disorder", - "nominated_by":"Precision Medicine Institute", - "genomic_units":[ - { - "gene":"PEX10", - "transcripts":[ - { - "transcript":"NM_153818.2" - } - ], - "variants":[ - { - "hgvs_variant":"NM_153818.2:c.28dup", - "c_dot":"c.28dup", - "p_dot":"p.Glu10fs", - "build":"hg19", - "case":[ - { - "field":"Evidence", - "value":[ - "PVS1", - "PM2", - "PP5" - ] - }, - { - "field":"Interpretation", - "value":[ - "Pathogenic" - ] - }, - { - "field":"Zygosity", - "value":[ - "Compound Hetrozygous" - ] - }, - { - "field":"Inheritance", - "value":[ - "Autosomal Recesive" - ] - } - ] - }, - { - "hgvs_variant":"NM_153818.2:c.928C>G", - "c_dot":"c.928G>G", - "p_dot":"p.His310Asp", - "build":"hg19", - "case":[ - { - "field":"Evidence", - "value":[ - "PM2", - "PM5", - "PP3" - ] - }, - { - "field":"Interpretation", - "value":[ - "Variant of Unknown Signifigance" - ] - }, - { - "field":"Zygosity", - "value":[ - "Compound Hetrozygous" - ] - } - ] - } - ] - } - ], - "sections":[ - { - "header":"Brief", - "content":[ - { - "type":"section-text", - "field":"Nominator", - "value":[ - "Precision Medicine Institute" - ] - }, - { - "type":"section-text", - "field":"Participant", - "value":[ - "Pediatric male (YOB: 2017), Local Participant" - ] - }, - { - "type":"section-text", - "field":"Phenotype", - "value":[ - "Postural instability, delayed gross motor development, generalized hypotonia, generalized hypotonia due to defect at the neuromuscular junction, motor delay, abnormality of the dentate nucleus, abnormality of the periventricular white matter, poor motor coordination, and congenital nystagmus " - ] - }, - { - "type":"section-text", - "field":"ACMG Classification", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"ACMG Classification Criteria", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"ACMG Criteria To Add", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Decision", - "value":[ - - ] - } - ] - }, - { - "header":"Clinical History", - "content":[ - { - "type":"section-text", - "field":"Clinical Diagnosis", - "value":[ - "Mild Zellweger Spectrum Disorder (a Peroxisome Biogenesis Disorder)", - "Current clinical manifestation is cerebellar ataxia that has impeded gross motor development." - ] - }, - { - "type":"section-text", - "field":"Affected Individuals Identified", - "value":[ - "Pediatric Male (YOB: 2017) Local Participant" - ] - }, - { - "type":"section-text", - "field":"Sequencing", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Testing", - "value":[ - " - Invitae Boosted Exome in 2019" - ] - }, - { - "type":"section-text", - "field":"Systems", - "value":[ - "Craniofacial, Eye Defects, Cutaneous, Musculoskeletal, Behavior, Cognition and Development, Neurological" - ] - }, - { - "type":"section-text", - "field":"Additional Details", - "value":[ - "Symptoms: postural instability, delayed gross motor development, generalized hypotonia, generalized hypotonia due to defect at the neuromuscular junction, motor delay, abnormality of the dentate nucleus, abnormality of the periventricular white matter, poor motor coordination, and congenital nystagmus" - ] - } - ] - }, - { - "header":"Pedigree", - "attachment_field":"Pedigree", - "content":[ - { - "type":"images-dataset", - "field":"Pedigree", - "value":[ - - ] - } - ] - }, - { - "header":"PEX10 Gene To Phenotype", - "attachment_field":"PEX10 Gene To Phenotype", - "content":[ - { - "type":"images-dataset", - "field":"PEX10 Gene To Phenotype", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"HPO Terms", - "value":[ - "Craniofacial, Eye Defects, Cutaneous, Musculoskeletal, Behavior, Cognition and Development, Neurological" - ] - } - ] - }, - { - "header":"PEX10 Molecular Mechanism", - "content":[ - { - "type":"section-text", - "field":"Function Overview", - "value":[ - - ] - } - ] - }, - { - "header":"PEX10 Function", - "attachment_field":"PEX10 Function", - "content":[ - { - "type":"images-dataset", - "field":"PEX10 Function", - "value":[ - - ] - } - ] - }, - { - "header":"Model Goals", - "content":[ - { - "type":"section-text", - "field":"Model of Interest", - "value":[ - "Zebrafish" - ] - }, - { - "type":"section-text", - "field":"Goals", - "value":[ - "Functional impact confirmation (animal/cell modeling)", - "Therapeutic predictions (in-silico predictions)", - "Downstream applications", - " - Downstream applications" - ] - }, - { - "type":"section-text", - "field":"Proposed Model/Project", - "value":[ - "Parental fibroblasts and iPSCs in process", - "S. Cerevisiae: no meaningful phenotype found for H303D (human H310D)", - "C Elegans: InVivo made model but there looks to be off-target mutations; Andy Golden (NIH) is planning to make another one", - "Mice: JAX models in process", - "H288D mice have phenotype (personal communication)", - "B6 mice", - "Conditional KOMP B6", - "5050 B6 and 129", - "Previous mice models C294Y (human C316Y; same RING finger domain) – homozygous and heterozygous have phenotype", - " http://www.informatics.jax.org/allele/MGI:5638060", - "H. Polymorpha: in process", - "Drosophila: in process", - "Zebrafish: in negotiations (ensures if a model is created by CPAM, there will be collaborator lined up)" - ] - }, - { - "type":"section-text", - "field":"Existing Collaborations", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Existing Funding", - "value":[ - - ] - } - ] - } - ], - "timeline":[ - { - "event":"create", - "timestamp":"2022-10-09T21:13:22.687000", - "username":"vrr-prep" - }, - { - "event":"ready", - "timestamp":"2022-10-09T21:14:22.687000", - "username":"vrr-prep" - } - ] - }, - { - "name":"CPAM0065", - "description":"Congenital variant of Rett syndrome", - "genomic_units":[ - { - "gene":"FOXG1", - "transcripts":[ - { - "transcript":"NM_005249.5" - } - ], - "variants":[ - { - "hgvs_variant":"NM_005249.5:c.924G>A", - "c_dot":"c.924G>A", - "p_dot":"p.Trp308Ter", - "build":"hg19", - "case":[ - - ] - }, - { - "hgvs_variant":"NM_005249.5:c.256dup", - "c_dot":"c.256dup", - "p_dot":"p.Gln86fs", - "build":"hg19", - "case":[ - - ] - } - ] - } - ], - "nominated_by":"Believe in a Cure Foundation", - "sections":[ - { - "header":"Brief", - "content":[ - { - "type":"section-text", - "field":"Nominator", - "value":[ - "Believe in a Cure Foundation (nonprofit, FOXG1 syndrome)" - ] - }, - { - "type":"section-text", - "field":"Participant", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Phenotype", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"ACMG Classification", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"ACMG Classification Criteria", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"ACMG Criteria To Add", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Decision", - "value":[ - - ] - } - ] - }, - { - "header":"Clinical History", - "content":[ - { - "type":"section-text", - "field":"Clinical Diagnosis", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Affected Individuals Identified", - "value":[ - " - Frameshift – 3 published cases (Ellaway et al 2013, Takahashi et al 2012, Le Guen et al 2011)", - " - Nonsense – 1 published case (Philippe et al 2010)" - ] - }, - { - "type":"section-text", - "field":"Sequencing", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Testing", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Systems", - "value":[ - "Growth Parameters, Craniofacial. Eye Defects, Musculoskeletal, Behavior, Cognition, and Development, Digestive System, Neurological" - ] - }, - { - "type":"section-text", - "field":"Additional Details", - "value":[ - - ] - } - ] - }, - { - "header":"Pedigree", - "attachment_field":"Pedigree", - "content":[ - { - "type":"images-dataset", - "field":"Pedigree", - "value":[ - - ] - } - ] - }, - { - "header":"FOXG1 Gene To Phenotype", - "attachment_field":"FOXG1 Gene To Phenotype", - "content":[ - { - "type":"images-dataset", - "field":"FOXG1 Gene To Phenotype", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"HPO Terms", - "value":[ - "Microcephaly; Protruding tongue; Strabismus; Scoliosis; Absent speech; Feeding difficulties; Generalized hypotonia; Seizure; Irritability; Poor eye contact; Encephalopathy; Dysphagia; Hypoplasia of the corpus callosum; Sleep disturbance; Hyperkinetic movements;", - "Axial dystonia; Bruxism; Generalized dystonia; Hypoplasia of the frontal lobes; Generalized tonic seizure; Stereotypical hand wringing; Delayed myelination; Psychomotor impairment; Dyskinesia; Opisthotonus;" - ] - } - ] - }, - { - "header":"FOXG1 Molecular Mechanism", - "content":[ - { - "type":"section-text", - "field":"Function Overview", - "value":[ - - ] - } - ] - }, - { - "header":"FOXG1 Function", - "attachment_field":"FOXG1 Function", - "content":[ - { - "type":"images-dataset", - "field":"FOXG1 Function", - "value":[ - - ] - } - ] - }, - { - "header":"Model Goals", - "content":[ - { - "type":"section-text", - "field":"Model of Interest", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Goals", - "value":[ - " - Therapeutic predictions (in silico predictions)", - " - Downstream applications (studies funded out with C-PAM to generate downstream findings)" - ] - }, - { - "type":"section-text", - "field":"Proposed Model/Project", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Existing Collaborations", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Existing Funding", - "value":[ - - ] - } - ] - } - ], - "timeline":[ - { - "event":"create", - "timestamp":"2022-11-09T21:13:22.687001", - "username":"vrr-prep" - }, - { - "event":"ready", - "timestamp":"2022-11-09T21:13:22.687002", - "username":"vrr-prep" - }, - { - "event":"opened", - "timestamp":"2022-11-09T21:13:22.687003", - "username":"vrr-prep" - }, - { - "event":"decline", - "timestamp":"2022-11-09T21:13:22.687004", - "username":"vrr-prep" - } - ] - }, - { - "name":"CPAM0084", - "description":"", - "nominated_by":"", - "timeline":[ - { - "event":"create", - "timestamp":"2023-05-09T19:10:31.369000", - "username":"developer" - } - ], - "third_party_links":[ - - ], - "genomic_units":[ - { - "gene":"DLG4", - "transcripts":[ - { - "transcript":"NM_001365.4" - }, - { - "transcript":"NM_001360016.2" - } - ], - "variants":[ - { - "hgvs_variant":"NM_001365.4:c.1039del", - "c_dot":"c.1039del", - "p_dot":"p.Glu347ArgTer12", - "build":"GRCh37", - "case":[ - { - "field":"Interpretation", - "value":[ - "likely_pathogenic" - ] - }, - { - "field":"Zygosity", - "value":[ - "heterozygous" - ] - }, - { - "field":"Inheritance", - "value":[ - "unknown" - ] - } - ] - } - ] - }, - { - "gene":"G6PD", - "transcripts":[ - { - "transcript":"NM_001365.4" - }, - { - "transcript":"NM_001360016.2" - } - ], - "variants":[ - { - "hgvs_variant":"NM_001360016.2:c.563C>T", - "c_dot":"c.563C>T", - "p_dot":"p.Ser188Phe", - "build":"GRCh37", - "case":[ - { - "field":"Interpretation", - "value":[ - "pathogenic" - ] - }, - { - "field":"Zygosity", - "value":[ - "heterozygous" - ] - }, - { - "field":"Inheritance", - "value":[ - "NA" - ] - } - ] - } - ] - } - ], - "sections":[ - { - "header":"Brief", - "content":[ - { - "type":"section-text", - "field":"Nominator", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Participant", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Phenotype", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"ACMG Classification", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"ACMG Classification Criteria", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"ACMG Criteria To Add", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Decision", - "value":[ - - ] - } - ] - }, - { - "header":"Clinical History", - "content":[ - { - "type":"section-text", - "field":"Clinical Diagnosis", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Affected Individuals Identified", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Sequencing", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Testing", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Systems", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Additional Details", - "value":[ - - ] - } - ] - }, - { - "header":"Pedigree", - "attachment_field":"Pedigree", - "content":[ - { - "type":"images-dataset", - "field":"Pedigree", - "value":[ - - ] - } - ] - }, - { - "header":"DLG4 Gene To Phenotype", - "attachment_field":"DLG4 Gene To Phenotype", - "content":[ - { - "type":"images-dataset", - "field":"DLG4 Gene To Phenotype", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"HPO Terms", - "value":[ - "HP:0000739: Anxiety; HP:0000750: Delayed speech and language development; HP:0001249: Intellectual disability; HP:0001260: Dysarthria; HP:0001290: Generalized hypotonia; HP:0001298: Encephalopathy; HP:0002194: Delayed gross motor development; HP:0002370: Poor coordination; HP:0002425: Anarthria; HP:0007018: Attention deficit hyperactivity disorder; HP:0012758: Neurodevelopmental delay; HP:0100702: Arachnoid cyst" - ] - } - ] - }, - { - "header":"DLG4 Molecular Mechanism", - "content":[ - { - "type":"section-text", - "field":"Function Overview", - "value":[ - - ] - } - ] - }, - { - "header":"DLG4 Function", - "attachment_field":"DLG4 Function", - "content":[ - { - "type":"images-dataset", - "field":"DLG4 Function", - "value":[ - - ] - } - ] - }, - { - "header":"G6PD Gene To Phenotype", - "attachment_field":"G6PD Gene To Phenotype", - "content":[ - { - "type":"images-dataset", - "field":"G6PD Gene To Phenotype", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"HPO Terms", - "value":[ - "HP:0000739: Anxiety; HP:0000750: Delayed speech and language development; HP:0001249: Intellectual disability; HP:0001260: Dysarthria; HP:0001290: Generalized hypotonia; HP:0001298: Encephalopathy; HP:0002194: Delayed gross motor development; HP:0002370: Poor coordination; HP:0002425: Anarthria; HP:0007018: Attention deficit hyperactivity disorder; HP:0012758: Neurodevelopmental delay; HP:0100702: Arachnoid cyst" - ] - } - ] - }, - { - "header":"G6PD Molecular Mechanism", - "content":[ - { - "type":"section-text", - "field":"Function Overview", - "value":[ - - ] - } - ] - }, - { - "header":"G6PD Function", - "attachment_field":"G6PD Function", - "content":[ - { - "type":"images-dataset", - "field":"G6PD Function", - "value":[ - - ] - } - ] - }, - { - "header":"Model Goals", - "content":[ - { - "type":"section-text", - "field":"Model of Interest", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Goals", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Proposed Model/Project", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Existing Collaborations", - "value":[ - - ] - }, - { - "type":"section-text", - "field":"Existing Funding", - "value":[ - - ] - } - ] - } - ], - "supporting_evidence_files":[ - - ] - } + { + "name":"CPAM0002", + "description":"Vacuolar myopathy with autophagy, X-linked vacuolar myopathy with autophagy", + "nominated_by":"Dr. Person One", + "genomic_units":[ + { + "gene":"VMA21", + "transcripts":[ + { + "transcript":"NM_001017980.3" + } + ], + "variants":[ + { + "hgvs_variant":"NM_001017980.3:c.164G>T", + "c_dot":"c.164G>T", + "p_dot":"p.Gly55Val", + "build":"hg19", + "case":[ + { + "field":"Evidence", + "value":[ + "PVS1", + "PM2" + ] + }, + { + "field":"Other Datasource", + "value":[ + "PVS1", + "PM2" + ] + }, + { + "field":"Interpretation", + "value":[ + "Likely Pathogenic" + ] + } + ] + } + ] + } + ], + "sections":[ + { + "header":"Brief", + "content":[ + { + "type":"section-text", + "field":"Nominator", + "value":[ + "Dr. Person One" + ] + }, + { + "type":"section-text", + "field":"Participant", + "value":[ + "1 patient, carrier mother" + ] + }, + { + "type":"section-text", + "field":"Phenotype", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"ACMG Classification", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"ACMG Classification Criteria", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"ACMG Criteria To Add", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Decision", + "value":[ + + ] + } + ] + }, + { + "header":"Clinical History", + "content":[ + { + "type":"section-text", + "field":"Clinical Diagnosis", + "value":[ + "Vacuolor myopathy with autophagy, X-linked vacuolor myopathy with autophagy" + ] + }, + { + "type":"section-text", + "field":"Affected Individuals Identified", + "value":[ + "1 patient, carrier mother", + "Maternal grandfather with myopathy.", + "Mother has muscle signal changes on MRI", + "Thus presumed to be an X-linked myopathy" + ] + }, + { + "type":"section-text", + "field":"Sequencing", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Testing", + "value":[ + "- DMD, LAMP2, myofibrillar myopathy panel performed testing for BAG3, crystalline B, desmin, DNAJB6, FLH1, LDB3, and myotilin. Non diagnostic.", + "- DMD testing revealed a hemizygous variant of unknown significance in the DMD gene.", + "- Fulgent Diagnostics identified a hemizygous VUS in the VMA21(XMEA); c.164G>T (p.Gly55Val). His mother also carried this variant." + ] + }, + { + "type":"section-text", + "field":"Systems", + "value":[ + "Musculoskeletal and orthopedics" + ] + }, + { + "type":"section-text", + "field":"Additional Details", + "value":[ + "8 yo male at time of testing. Ambulatory. Myopathy starting from 2 years of age with falls, elevated CK, and myopathic muscle biopsy. Clinical course is slowly progressive.", + "Exam showed proximal limb girdle pattern of weakness. Proximal upper and lower extremity weakness. Myopathy Congenital myopathy. Diminished muscle bulk / eps. scapular, Lordotic gait.", + "Muscle biopsy (2014) showed fiber size variability with prominent perimysial fibrous tissue; scattered myofibers with vacuoles staining dark blue with trichome and positive PAS staining; normal enzyme activity for phosphorylase, myoadenylase and phosphofructokinase.", + "Electron microscopy (2014) showed membrane bound vacuoles which contain glycogen and degenerated mitochondria; some of these vacuoles contain secondary lysosomes.", + "CK level 1121U/L.", + "Mode of Inheritance", + "X linked" + ] + } + ] + }, + { + "header":"Pedigree", + "attachment_field":"Pedigree", + "content":[ + { + "type":"images-dataset", + "field":"Pedigree", + "value":[ + + ] + } + ] + }, + { + "header":"VMA21 Gene To Phenotype", + "attachment_field":"VMA21 Gene To Phenotype", + "content":[ + { + "type":"images-dataset", + "field":"VMA21 Gene To Phenotype", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"HPO Terms", + "value":[ + "HP:0003198; HP:0003797; HP:0003325; HP:0008997; HP:0008994; HP:0001288; HP:0009060; HP:0004303; HP:0012103; HP:0003736" + ] + } + ] + }, + { + "header":"VMA21 Molecular Mechanism", + "content":[ + { + "type":"section-text", + "field":"Function Overview", + "value":[ + + ] + } + ] + }, + { + "header":"VMA21 Function", + "attachment_field":"VMA21 Function", + "content":[ + { + "type":"images-dataset", + "field":"VMA21 Function", + "value":[ + + ] + } + ] + }, + { + "header":"Model Goals", + "content":[ + { + "type":"section-text", + "field":"Model of Interest", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Goals", + "value":[ + "Review of ACMG classification", + "Functional impact study (in silico/animal/cell modeling)", + "Therapeutic predictions (in silico predictions)" + ] + }, + { + "type":"section-text", + "field":"Proposed Model/Project", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Existing Collaborations", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Existing Funding", + "value":[ + + ] + } + ] + } + ], + "discussions":[ + { + "post_id":"9027ec8d-6298-4afb-add5-6ef710eb5e98", + "author_id":"3bghhsmnyqi6uxovazy07ryn9q1tqbnt", + "author_fullname":"Developer Person", + "publish_timestamp":"2023-10-09T21:13:22.687000", + "content":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse eget metus nec erat accumsan rutrum.", + "attachments":[ + + ], + "thread":[ + + ] + }, + { + "post_id":"a677bb36-acf8-4ff9-a406-b113a7952f7e", + "author_id":"kw0g790fdx715xsr1ead2jk0pqubtlyz", + "author_fullname":"Researcher Person", + "publish_timestamp":"2023-10-10T21:13:22.687000", + "content":"Mauris at mauris eu neque varius suscipit. Sed pretium sem at nunc sollicitudin, condimentum vestibulum nisl vehicula. Vestibulum consectetur mi sit amet ante molestie fermentum.", + "attachments":[ + + ], + "thread":[ + + ] + }, + { + "post_id":"e6023fa7-b598-416a-9f42-862c826255ef", + "author_id":"exqkhvidr7uh2ndslsdymbzfbmqjlunk", + "author_fullname":"Variant Review Report Preparer Person", + "publish_timestamp":"2023-10-13T21:13:22.687000", + "content":"Mauris at mauris eu neque varius suscipit. Sed pretium sem at nunc sollicitudin also.", + "attachments":[ + + ], + "thread":[ + + ] + } + ], + "supporting_evidence_files":[], + "timeline":[ + { + "event":"create", + "timestamp":"2022-10-09T21:13:22.687000", + "username":"vrr-prep" + }, + { + "event":"ready", + "timestamp":"2022-10-09T21:14:22.687000", + "username":"vrr-prep" + }, + { + "event":"opened", + "timestamp":"2022-10-09T21:15:22.687000", + "username":"vrr-prep" + }, + { + "event":"approve", + "timestamp":"2022-10-09T21:16:22.687000", + "username":"vrr-prep" + } + ] + }, + { + "name":"CPAM0046", + "description":": LMNA-related congenital muscular dystropy", + "nominated_by":"Dr. Person Two", + "genomic_units":[ + { + "gene":"LMNA", + "transcripts":[ + { + "transcript":"NM_170707.3" + } + ], + "variants":[ + { + "hgvs_variant":"NM_170707.3:c.745C>T", + "c_dot":"c.745C>T", + "p_dot":"p.R249W", + "build":"hg19", + "case":[ + { + "field":"Evidence", + "value":[ + "PS2", + "PS3", + "PM2", + "PP3", + "PP5" + ] + }, + { + "field":"Interpretation", + "value":[ + "Pathogenic" + ] + }, + { + "field":"Inheritance", + "value":[ + "De Novo" + ] + } + ] + } + ] + } + ], + "sections":[ + { + "header":"Brief", + "content":[ + { + "type":"section-text", + "field":"Nominator", + "value":[ + "Dr. Person Two (Local) - working with Dr. Person Three in Person Four Lab" + ] + }, + { + "type":"section-text", + "field":"Participant", + "value":[ + "Male, YOB: 2019" + ] + }, + { + "type":"section-text", + "field":"Phenotype", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"ACMG Classification", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"ACMG Classification Criteria", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"ACMG Criteria To Add", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Decision", + "value":[ + + ] + } + ] + }, + { + "header":"Clinical History", + "content":[ + { + "type":"section-text", + "field":"Clinical Diagnosis", + "value":[ + "LMNA-related congenital muscular dystropy" + ] + }, + { + "type":"section-text", + "field":"Affected Individuals Identified", + "value":[ + "Male, YOB: 2019" + ] + }, + { + "type":"section-text", + "field":"Sequencing", + "value":[ + "WES" + ] + }, + { + "type":"section-text", + "field":"Testing", + "value":[ + "WES - February 2020;" + ] + }, + { + "type":"section-text", + "field":"Systems", + "value":[ + "Growth Parameters; Craniofacial; Musculoskeletal; Gastrointestinal; Behavior, Cognition and Development; Neurological" + ] + }, + { + "type":"section-text", + "field":"Additional Details", + "value":[ + "Review of VUSes (Why not considered)", + "NEB (NM_001164508.1) | c.7385C>G (p.A2462G) (Pat.) and c.16625A>G (p.H5542R) (Mat.).", + " - Associated with Nemaline myopathy 2, autosomal recessive", + " - Both variants are still classified as VUS (last evaluated Feb 2020)", + " - 195 out of 203 (96.1%) non-VUS missense variants in gene NEB are benign", + " ", + "LYZL6 (NM_020426.2) | c.228G>C (p.Q76H) (Mat./Pat.)", + " - Lysozyme Like 6.", + " - No currently known disease associations.", + " ", + "NOL6 (NM_022917.4) | c.518G>A (p.R173Q) (Pat.) and c.91G>A (p.G31R) (Mat.).", + " - Nucleolar protein 6.", + " - No currently known disease associations" + ] + } + ] + }, + { + "header":"Pedigree", + "attachment_field":"Pedigree", + "content":[ + { + "type":"images-dataset", + "field":"Pedigree", + "value":[ + + ] + } + ] + }, + { + "header":"LMNA Gene To Phenotype", + "attachment_field":"LMNA Gene To Phenotype", + "content":[ + { + "type":"images-dataset", + "field":"LMNA Gene To Phenotype", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"HPO Terms", + "value":[ + "HP:0001508:Failure to thrive; HP:0001357:Plagiocephaly; HP:0000473:Torticollis; HP:0003560:Muscular dystrophy; HP:0003701:Proximal muscle weakness; HP:0009062:Infantile axial hypotonia; HP:0012389:Appendicular hypotonia; HP: 0003236:Elevated serum creatine kinase; HP:0002020:Gastroesophageal reflux; HP:0011471:Gastrostomy tube feeding in infancy; HP:0011968:Feeding difficulties; HP:0001263:Global developmental delay; HP:0001265:Hyproflexia; HP:0032988:Persistent head lag; HP:0000960:Sacral dimple;" + ] + } + ] + }, + { + "header":"LMNA Molecular Mechanism", + "content":[ + { + "type":"section-text", + "field":"Function Overview", + "value":[ + + ] + } + ] + }, + { + "header":"LMNA Function", + "attachment_field":"LMNA Function", + "content":[ + { + "type":"images-dataset", + "field":"LMNA Function", + "value":[ + + ] + } + ] + }, + { + "header":"Model Goals", + "content":[ + { + "type":"section-text", + "field":"Model of Interest", + "value":[ + "Zebrafish" + ] + }, + { + "type":"section-text", + "field":"Goals", + "value":[ + "Functional impact confirmation (animal/cell modeling)", + "Therapeutic predictions (in-silico predictions)", + "Downstream applications (sharing model to conduct larger drug screens)" + ] + }, + { + "type":"section-text", + "field":"Proposed Model/Project", + "value":[ + "Contribute a dominant negative patient-variant model to the existing zebrafish model (LOF; in-progress)", + "Will be used in NBL 240: a research-based undergraduate course at UAB" + ] + }, + { + "type":"section-text", + "field":"Existing Collaborations", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Existing Funding", + "value":[ + + ] + } + ] + } + ], + "discussions":[ + { + "post_id":"9027ec8d-6298-4afb-add5-6ef710eb5e98", + "author_id":"3bghhsmnyqi6uxovazy07ryn9q1tqbnt", + "author_fullname":"Developer Person", + "publish_timestamp":"2023-10-09T21:13:22.687000", + "content":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse eget metus nec erat accumsan rutrum.", + "attachments":[ + + ], + "thread":[ + + ] + }, + { + "post_id":"e6023fa7-b598-416a-9f42-862c826255ef", + "author_id":"exqkhvidr7uh2ndslsdymbzfbmqjlunk", + "author_fullname":"Variant Review Report Preparer Person", + "publish_timestamp":"2023-10-13T21:13:22.687000", + "content":"Mauris at mauris eu neque varius suscipit. Sed pretium sem at nunc sollicitudin also.", + "attachments":[ + + ], + "thread":[ + + ] + } + ], + "supporting_evidence_files":[], + "timeline":[ + { + "event":"create", + "timestamp":"2022-10-09T21:13:22.687000", + "username":"vrr-prep" + }, + { + "event":"ready", + "timestamp":"2022-10-09T21:14:22.687000", + "username":"vrr-prep" + }, + { + "event":"opened", + "timestamp":"2022-10-09T21:15:22.687000", + "username":"vrr-prep" + }, + { + "event":"approve", + "timestamp":"2022-10-09T21:16:22.687000", + "username":"vrr-prep" + } + ] + }, + { + "name":"CPAM0047", + "description":"Congenital variant of Rett syndrome", + "genomic_units":[ + { + "gene":"SBF1", + "transcripts":[ + { + "transcript":"NM_002972.2" + } + ], + "variants":[ + { + "hgvs_variant":"NM_002972.2:c.3493_3494dupTA", + "c_dot":"c.3493_3494dupTA", + "p_dot":"Pro1166ThrfsX5", + "build":"hg19", + "case":[ + + ] + }, + { + "hgvs_variant":"NM_002972.2:c.5474_5475delTG", + "c_dot":"c.5474_5475delTG", + "p_dot":"Val1825GlyfsX27", + "build":"hg19", + "case":[ + + ] + } + ] + } + ], + "nominated_by":"CMT4B3 Foundation", + "sections":[ + { + "header":"Brief", + "content":[ + { + "type":"section-text", + "field":"Nominator", + "value":[ + "CMT4B3 Foundation" + ] + }, + { + "type":"section-text", + "field":"Participant", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Phenotype", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"ACMG Classification", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"ACMG Classification Criteria", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"ACMG Criteria To Add", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Decision", + "value":[ + + ] + } + ] + }, + { + "header":"Clinical History", + "content":[ + { + "type":"section-text", + "field":"Clinical Diagnosis", + "value":[ + "Mild Zellweger Spectrum Disorder (a Peroxisome Biogenesis Disorder)", + "Current clinical manifestation is cerebellar ataxia that has impeded gross motor development." + ] + }, + { + "type":"section-text", + "field":"Affected Individuals Identified", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Sequencing", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Testing", + "value":[ + " - Invitae Boosted Exome in 2019" + ] + }, + { + "type":"section-text", + "field":"Systems", + "value":[ + "Craniofacial, Eye Defects, Cutaneous, Musculoskeletal, Behavior, Cognition and Development, Neurological" + ] + }, + { + "type":"section-text", + "field":"Additional Details", + "value":[ + "Symptoms: postural instability, delayed gross motor development, generalized hypotonia, generalized hypotonia due to defect at the neuromuscular junction, motor delay, abnormality of the dentate nucleus, abnormality of the periventricular white matter, poor motor coordination, and congenital nystagmus " + ] + } + ] + }, + { + "header":"Pedigree", + "attachment_field":"Pedigree", + "content":[ + { + "type":"images-dataset", + "field":"Pedigree", + "value":[ + + ] + } + ] + }, + { + "header":"SBF1 Gene To Phenotype", + "attachment_field":"SBF1 Gene To Phenotype", + "content":[ + { + "type":"images-dataset", + "field":"SBF1 Gene To Phenotype", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"HPO Terms", + "value":[ + + ] + } + ] + }, + { + "header":"SBF1 Molecular Mechanism", + "content":[ + { + "type":"section-text", + "field":"Function Overview", + "value":[ + + ] + } + ] + }, + { + "header":"SBF1 Function", + "attachment_field":"SBF1 Function", + "content":[ + { + "type":"images-dataset", + "field":"SBF1 Function", + "value":[ + + ] + } + ] + }, + { + "header":"Model Goals", + "content":[ + { + "type":"section-text", + "field":"Model of Interest", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Goals", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Proposed Model/Project", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Existing Collaborations", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Existing Funding", + "value":[ + + ] + } + ] + } + ], + "discussions":[ + { + "post_id":"9027ec8d-6298-4afb-add5-6ef710eb5e98", + "author_id":"3bghhsmnyqi6uxovazy07ryn9q1tqbnt", + "author_fullname":"Developer Person", + "publish_timestamp":"2023-10-09T21:13:22.687000", + "content":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse eget metus nec erat accumsan rutrum.", + "attachments":[ + + ], + "thread":[ + + ] + }, + { + "post_id":"a677bb36-acf8-4ff9-a406-b113a7952f7e", + "author_id":"kw0g790fdx715xsr1ead2jk0pqubtlyz", + "author_fullname":"Researcher Person", + "publish_timestamp":"2023-10-10T21:13:22.687000", + "content":"Mauris at mauris eu neque varius suscipit. Sed pretium sem at nunc sollicitudin, condimentum vestibulum nisl vehicula. Vestibulum consectetur mi sit amet ante molestie fermentum.", + "attachments":[ + + ], + "thread":[ + + ] + }, + { + "post_id":"e6023fa7-b598-416a-9f42-862c826255ef", + "author_id":"exqkhvidr7uh2ndslsdymbzfbmqjlunk", + "author_fullname":"Variant Review Report Preparer Person", + "publish_timestamp":"2023-10-13T21:13:22.687000", + "content":"Mauris at mauris eu neque varius suscipit. Sed pretium sem at nunc sollicitudin also.", + "attachments":[ + + ], + "thread":[ + + ] + } + ], + "supporting_evidence_files":[], + "timeline":[ + { + "event":"create", + "timestamp":"2022-10-09T21:13:22.687000", + "username":"vrr-prep" + }, + { + "event":"ready", + "timestamp":"2022-10-09T21:14:22.687000", + "username":"vrr-prep" + }, + { + "event":"opened", + "timestamp":"2022-10-09T21:15:22.687000", + "username":"vrr-prep" + }, + { + "event":"decline", + "timestamp":"2022-10-09T21:16:22.687000", + "username":"vrr-prep" + } + ] + }, + { + "name":"CPAM0053", + "description":"Mild Zellweger Spectrum Disorder, a Peroxisome Biogenesis Disorder", + "nominated_by":"Precision Medicine Institute", + "genomic_units":[ + { + "gene":"PEX10", + "transcripts":[ + { + "transcript":"NM_153818.2" + } + ], + "variants":[ + { + "hgvs_variant":"NM_153818.2:c.28dup", + "c_dot":"c.28dup", + "p_dot":"p.Glu10fs", + "build":"hg19", + "case":[ + { + "field":"Evidence", + "value":[ + "PVS1", + "PM2", + "PP5" + ] + }, + { + "field":"Interpretation", + "value":[ + "Pathogenic" + ] + }, + { + "field":"Zygosity", + "value":[ + "Compound Hetrozygous" + ] + }, + { + "field":"Inheritance", + "value":[ + "Autosomal Recesive" + ] + } + ] + }, + { + "hgvs_variant":"NM_153818.2:c.928C>G", + "c_dot":"c.928G>G", + "p_dot":"p.His310Asp", + "build":"hg19", + "case":[ + { + "field":"Evidence", + "value":[ + "PM2", + "PM5", + "PP3" + ] + }, + { + "field":"Interpretation", + "value":[ + "Variant of Unknown Signifigance" + ] + }, + { + "field":"Zygosity", + "value":[ + "Compound Hetrozygous" + ] + } + ] + } + ] + } + ], + "sections":[ + { + "header":"Brief", + "content":[ + { + "type":"section-text", + "field":"Nominator", + "value":[ + "Precision Medicine Institute" + ] + }, + { + "type":"section-text", + "field":"Participant", + "value":[ + "Pediatric male (YOB: 2017), Local Participant" + ] + }, + { + "type":"section-text", + "field":"Phenotype", + "value":[ + "Postural instability, delayed gross motor development, generalized hypotonia, generalized hypotonia due to defect at the neuromuscular junction, motor delay, abnormality of the dentate nucleus, abnormality of the periventricular white matter, poor motor coordination, and congenital nystagmus " + ] + }, + { + "type":"section-text", + "field":"ACMG Classification", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"ACMG Classification Criteria", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"ACMG Criteria To Add", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Decision", + "value":[ + + ] + } + ] + }, + { + "header":"Clinical History", + "content":[ + { + "type":"section-text", + "field":"Clinical Diagnosis", + "value":[ + "Mild Zellweger Spectrum Disorder (a Peroxisome Biogenesis Disorder)", + "Current clinical manifestation is cerebellar ataxia that has impeded gross motor development." + ] + }, + { + "type":"section-text", + "field":"Affected Individuals Identified", + "value":[ + "Pediatric Male (YOB: 2017) Local Participant" + ] + }, + { + "type":"section-text", + "field":"Sequencing", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Testing", + "value":[ + " - Invitae Boosted Exome in 2019" + ] + }, + { + "type":"section-text", + "field":"Systems", + "value":[ + "Craniofacial, Eye Defects, Cutaneous, Musculoskeletal, Behavior, Cognition and Development, Neurological" + ] + }, + { + "type":"section-text", + "field":"Additional Details", + "value":[ + "Symptoms: postural instability, delayed gross motor development, generalized hypotonia, generalized hypotonia due to defect at the neuromuscular junction, motor delay, abnormality of the dentate nucleus, abnormality of the periventricular white matter, poor motor coordination, and congenital nystagmus" + ] + } + ] + }, + { + "header":"Pedigree", + "attachment_field":"Pedigree", + "content":[ + { + "type":"images-dataset", + "field":"Pedigree", + "value":[ + + ] + } + ] + }, + { + "header":"PEX10 Gene To Phenotype", + "attachment_field":"PEX10 Gene To Phenotype", + "content":[ + { + "type":"images-dataset", + "field":"PEX10 Gene To Phenotype", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"HPO Terms", + "value":[ + "Craniofacial, Eye Defects, Cutaneous, Musculoskeletal, Behavior, Cognition and Development, Neurological" + ] + } + ] + }, + { + "header":"PEX10 Molecular Mechanism", + "content":[ + { + "type":"section-text", + "field":"Function Overview", + "value":[ + + ] + } + ] + }, + { + "header":"PEX10 Function", + "attachment_field":"PEX10 Function", + "content":[ + { + "type":"images-dataset", + "field":"PEX10 Function", + "value":[ + + ] + } + ] + }, + { + "header":"Model Goals", + "content":[ + { + "type":"section-text", + "field":"Model of Interest", + "value":[ + "Zebrafish" + ] + }, + { + "type":"section-text", + "field":"Goals", + "value":[ + "Functional impact confirmation (animal/cell modeling)", + "Therapeutic predictions (in-silico predictions)", + "Downstream applications", + " - Downstream applications" + ] + }, + { + "type":"section-text", + "field":"Proposed Model/Project", + "value":[ + "Parental fibroblasts and iPSCs in process", + "S. Cerevisiae: no meaningful phenotype found for H303D (human H310D)", + "C Elegans: InVivo made model but there looks to be off-target mutations; Andy Golden (NIH) is planning to make another one", + "Mice: JAX models in process", + "H288D mice have phenotype (personal communication)", + "B6 mice", + "Conditional KOMP B6", + "5050 B6 and 129", + "Previous mice models C294Y (human C316Y; same RING finger domain) – homozygous and heterozygous have phenotype", + " http://www.informatics.jax.org/allele/MGI:5638060", + "H. Polymorpha: in process", + "Drosophila: in process", + "Zebrafish: in negotiations (ensures if a model is created by CPAM, there will be collaborator lined up)" + ] + }, + { + "type":"section-text", + "field":"Existing Collaborations", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Existing Funding", + "value":[ + + ] + } + ] + } + ], + "discussions":[ + { + "post_id":"e6023fa7-b598-416a-9f42-862c826255ef", + "author_id":"exqkhvidr7uh2ndslsdymbzfbmqjlunk", + "author_fullname":"Variant Review Report Preparer Person", + "publish_timestamp":"2023-10-13T21:13:22.687000", + "content":"Mauris at mauris eu neque varius suscipit. Sed pretium sem at nunc sollicitudin also.", + "attachments":[ + + ], + "thread":[ + + ] + } + ], + "supporting_evidence_files":[], + "timeline":[ + { + "event":"create", + "timestamp":"2022-10-09T21:13:22.687000", + "username":"vrr-prep" + }, + { + "event":"ready", + "timestamp":"2022-10-09T21:14:22.687000", + "username":"vrr-prep" + } + ] + }, + { + "name":"CPAM0065", + "description":"Congenital variant of Rett syndrome", + "genomic_units":[ + { + "gene":"FOXG1", + "transcripts":[ + { + "transcript":"NM_005249.5" + } + ], + "variants":[ + { + "hgvs_variant":"NM_005249.5:c.924G>A", + "c_dot":"c.924G>A", + "p_dot":"p.Trp308Ter", + "build":"hg19", + "case":[ + + ] + }, + { + "hgvs_variant":"NM_005249.5:c.256dup", + "c_dot":"c.256dup", + "p_dot":"p.Gln86fs", + "build":"hg19", + "case":[ + + ] + } + ] + } + ], + "nominated_by":"Believe in a Cure Foundation", + "sections":[ + { + "header":"Brief", + "content":[ + { + "type":"section-text", + "field":"Nominator", + "value":[ + "Believe in a Cure Foundation (nonprofit, FOXG1 syndrome)" + ] + }, + { + "type":"section-text", + "field":"Participant", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Phenotype", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"ACMG Classification", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"ACMG Classification Criteria", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"ACMG Criteria To Add", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Decision", + "value":[ + + ] + } + ] + }, + { + "header":"Clinical History", + "content":[ + { + "type":"section-text", + "field":"Clinical Diagnosis", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Affected Individuals Identified", + "value":[ + " - Frameshift – 3 published cases (Ellaway et al 2013, Takahashi et al 2012, Le Guen et al 2011)", + " - Nonsense – 1 published case (Philippe et al 2010)" + ] + }, + { + "type":"section-text", + "field":"Sequencing", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Testing", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Systems", + "value":[ + "Growth Parameters, Craniofacial. Eye Defects, Musculoskeletal, Behavior, Cognition, and Development, Digestive System, Neurological" + ] + }, + { + "type":"section-text", + "field":"Additional Details", + "value":[ + + ] + } + ] + }, + { + "header":"Pedigree", + "attachment_field":"Pedigree", + "content":[ + { + "type":"images-dataset", + "field":"Pedigree", + "value":[ + + ] + } + ] + }, + { + "header":"FOXG1 Gene To Phenotype", + "attachment_field":"FOXG1 Gene To Phenotype", + "content":[ + { + "type":"images-dataset", + "field":"FOXG1 Gene To Phenotype", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"HPO Terms", + "value":[ + "Microcephaly; Protruding tongue; Strabismus; Scoliosis; Absent speech; Feeding difficulties; Generalized hypotonia; Seizure; Irritability; Poor eye contact; Encephalopathy; Dysphagia; Hypoplasia of the corpus callosum; Sleep disturbance; Hyperkinetic movements;", + "Axial dystonia; Bruxism; Generalized dystonia; Hypoplasia of the frontal lobes; Generalized tonic seizure; Stereotypical hand wringing; Delayed myelination; Psychomotor impairment; Dyskinesia; Opisthotonus;" + ] + } + ] + }, + { + "header":"FOXG1 Molecular Mechanism", + "content":[ + { + "type":"section-text", + "field":"Function Overview", + "value":[ + + ] + } + ] + }, + { + "header":"FOXG1 Function", + "attachment_field":"FOXG1 Function", + "content":[ + { + "type":"images-dataset", + "field":"FOXG1 Function", + "value":[ + + ] + } + ] + }, + { + "header":"Model Goals", + "content":[ + { + "type":"section-text", + "field":"Model of Interest", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Goals", + "value":[ + " - Therapeutic predictions (in silico predictions)", + " - Downstream applications (studies funded out with C-PAM to generate downstream findings)" + ] + }, + { + "type":"section-text", + "field":"Proposed Model/Project", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Existing Collaborations", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Existing Funding", + "value":[ + + ] + } + ] + } + ], + "discussions":[], + "supporting_evidence_files":[], + "timeline":[ + { + "event":"create", + "timestamp":"2022-11-09T21:13:22.687001", + "username":"vrr-prep" + }, + { + "event":"ready", + "timestamp":"2022-11-09T21:13:22.687002", + "username":"vrr-prep" + }, + { + "event":"opened", + "timestamp":"2022-11-09T21:13:22.687003", + "username":"vrr-prep" + }, + { + "event":"decline", + "timestamp":"2022-11-09T21:13:22.687004", + "username":"vrr-prep" + } + ] + }, + { + "name":"CPAM0084", + "description":"", + "nominated_by":"", + "timeline":[ + { + "event":"create", + "timestamp":"2023-05-09T19:10:31.369000", + "username":"developer" + } + ], + "third_party_links":[], + "genomic_units":[ + { + "gene":"DLG4", + "transcripts":[ + { + "transcript":"NM_001365.4" + }, + { + "transcript":"NM_001360016.2" + } + ], + "variants":[ + { + "hgvs_variant":"NM_001365.4:c.1039del", + "c_dot":"c.1039del", + "p_dot":"p.Glu347ArgTer12", + "build":"GRCh37", + "case":[ + { + "field":"Interpretation", + "value":[ + "likely_pathogenic" + ] + }, + { + "field":"Zygosity", + "value":[ + "heterozygous" + ] + }, + { + "field":"Inheritance", + "value":[ + "unknown" + ] + } + ] + } + ] + }, + { + "gene":"G6PD", + "transcripts":[ + { + "transcript":"NM_001365.4" + }, + { + "transcript":"NM_001360016.2" + } + ], + "variants":[ + { + "hgvs_variant":"NM_001360016.2:c.563C>T", + "c_dot":"c.563C>T", + "p_dot":"p.Ser188Phe", + "build":"GRCh37", + "case":[ + { + "field":"Interpretation", + "value":[ + "pathogenic" + ] + }, + { + "field":"Zygosity", + "value":[ + "heterozygous" + ] + }, + { + "field":"Inheritance", + "value":[ + "NA" + ] + } + ] + } + ] + } + ], + "sections":[ + { + "header":"Brief", + "content":[ + { + "type":"section-text", + "field":"Nominator", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Participant", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Phenotype", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"ACMG Classification", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"ACMG Classification Criteria", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"ACMG Criteria To Add", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Decision", + "value":[ + + ] + } + ] + }, + { + "header":"Clinical History", + "content":[ + { + "type":"section-text", + "field":"Clinical Diagnosis", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Affected Individuals Identified", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Sequencing", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Testing", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Systems", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Additional Details", + "value":[ + + ] + } + ] + }, + { + "header":"Pedigree", + "attachment_field":"Pedigree", + "content":[ + { + "type":"images-dataset", + "field":"Pedigree", + "value":[ + + ] + } + ] + }, + { + "header":"DLG4 Gene To Phenotype", + "attachment_field":"DLG4 Gene To Phenotype", + "content":[ + { + "type":"images-dataset", + "field":"DLG4 Gene To Phenotype", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"HPO Terms", + "value":[ + "HP:0000739: Anxiety; HP:0000750: Delayed speech and language development; HP:0001249: Intellectual disability; HP:0001260: Dysarthria; HP:0001290: Generalized hypotonia; HP:0001298: Encephalopathy; HP:0002194: Delayed gross motor development; HP:0002370: Poor coordination; HP:0002425: Anarthria; HP:0007018: Attention deficit hyperactivity disorder; HP:0012758: Neurodevelopmental delay; HP:0100702: Arachnoid cyst" + ] + } + ] + }, + { + "header":"DLG4 Molecular Mechanism", + "content":[ + { + "type":"section-text", + "field":"Function Overview", + "value":[ + + ] + } + ] + }, + { + "header":"DLG4 Function", + "attachment_field":"DLG4 Function", + "content":[ + { + "type":"images-dataset", + "field":"DLG4 Function", + "value":[ + + ] + } + ] + }, + { + "header":"G6PD Gene To Phenotype", + "attachment_field":"G6PD Gene To Phenotype", + "content":[ + { + "type":"images-dataset", + "field":"G6PD Gene To Phenotype", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"HPO Terms", + "value":[ + "HP:0000739: Anxiety; HP:0000750: Delayed speech and language development; HP:0001249: Intellectual disability; HP:0001260: Dysarthria; HP:0001290: Generalized hypotonia; HP:0001298: Encephalopathy; HP:0002194: Delayed gross motor development; HP:0002370: Poor coordination; HP:0002425: Anarthria; HP:0007018: Attention deficit hyperactivity disorder; HP:0012758: Neurodevelopmental delay; HP:0100702: Arachnoid cyst" + ] + } + ] + }, + { + "header":"G6PD Molecular Mechanism", + "content":[ + { + "type":"section-text", + "field":"Function Overview", + "value":[ + + ] + } + ] + }, + { + "header":"G6PD Function", + "attachment_field":"G6PD Function", + "content":[ + { + "type":"images-dataset", + "field":"G6PD Function", + "value":[ + + ] + } + ] + }, + { + "header":"Model Goals", + "content":[ + { + "type":"section-text", + "field":"Model of Interest", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Goals", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Proposed Model/Project", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Existing Collaborations", + "value":[ + + ] + }, + { + "type":"section-text", + "field":"Existing Funding", + "value":[ + + ] + } + ] + } + ], + "discussions":[], + "supporting_evidence_files":[] + } ] \ No newline at end of file diff --git a/etc/fixtures/migrations/migrate-insert-discussion-and-supporting-keys.js b/etc/fixtures/migrations/migrate-insert-discussion-and-supporting-keys.js new file mode 100644 index 00000000..eab46a8e --- /dev/null +++ b/etc/fixtures/migrations/migrate-insert-discussion-and-supporting-keys.js @@ -0,0 +1,66 @@ +const usage = ` +mongosh /tmp/fixtures/migrations/migrate-insert-discussion-and-supporting-keys.js + + Script Options: + help : Bool : Optional + - If True print this help message + databaseName : String : Optional + - Default: rosalution_db + + Run mongosh help for mongosh connection and authentication usage. + + Example: + + mongosh --host localhost --port 27017 --eval 'var help=True;' /tmp/fixtures/migrations/migrate-insert-discussion-and-supporting-keys.js + + docker exec -it mongosh /tmp/fixtures/migrations/migrate-insert-discussion-and-supporting-keys.js +` + +if (help === true) { + print(usage); + quit(1); +} + +if (typeof databaseName === 'undefined') { + databaseName = 'rosalution_db'; +} else if (typeof databaseName !== 'string') { + print('databaseName must be a string'); + print(usage); + quit(1); +} + +db = db.getSiblingDB(databaseName) + +function keyCheck(analyses) { + for(analysis in analyses) { + // console.log(analyses[analysis]) + const analysisName = analyses[analysis]['name'] + const discussionsKeyExist = "discussions" in analyses[analysis] + const supportingKeyExist = "supporting_evidence_files" in analyses[analysis] + console.log(`${analysisName}: + 'supporting' - ${supportingKeyExist}, 'discussions' - ${discussionsKeyExist}`); + } +} + +try { + let analyses = db.analyses.find({}).toArray(); + + console.log("=== Before ===") + keyCheck(analyses) + + for(i in analyses) { + if(!("supporting_evidence_files" in analyses[i])) + analyses[i]['supporting_evidence_files'] = [] + if(!("discussions" in analyses[i])) + analyses[i]['discussions'] = [] + + db.analyses.updateOne({'_id': analyses[i]._id}, {'$set': analyses[i]}) + } + + console.log("=== After ===") + keyCheck(analyses) +} catch(e) { + console.log(e.stack); + console.log(usage); + quit(1); +} diff --git a/frontend/src/components/AnalysisView/DiscussionPost.vue b/frontend/src/components/AnalysisView/DiscussionPost.vue new file mode 100644 index 00000000..ce99c8e7 --- /dev/null +++ b/frontend/src/components/AnalysisView/DiscussionPost.vue @@ -0,0 +1,202 @@ +