Skip to content

Commit

Permalink
[MINT-2720] Data Exchange Approach (#1380)
Browse files Browse the repository at this point in the history
* feat: added feature migration, data models, gql

* chore: updated sql queries

* feat: several major improvements to first semi-functional data exchange approach in-app notification

* chore: updated postman collection to get all notifications

* chore: updated frontend gql and backend gql for user notification preferences

* chore: added simple resolver helper to dispatch emails and email test to validate email templates

* chore: removed resolved question

* chore: Reset all frontend files to main branch as we split the frontend work to EASI-4491

* chore: reran gql gen

* fix: forcing a commit for rebasing purposes

* chore: removed tmp file

* [EASI-4473] Notification: Data Exchange Approach Completed (#1209)

* feat: added feature migration, data models, gql

* chore: updated sql queries

* feat: several major improvements to first semi-functional data exchange approach in-app notification

* chore: updated postman collection to get all notifications

* chore: updated frontend gql and backend gql for user notification preferences

* chore: added simple resolver helper to dispatch emails and email test to validate email templates

* chore: removed resolved question

* chore: Reset all frontend files to main branch as we split the frontend work to EASI-4491

* chore: reran gql gen

* chore: email unit test for data exchange approach completed

* chore: removed unnecessary Scan and Value methods

* chore: added unit test for activity data exchange complete notification

* chore: implemented resolver for data exchange approach completed notification preferences

* fix: updated various test definitions to match new user account preferences spec

* chore: removed outdated comment

* chore: updated postman collection renaming markedCompletedBy -> markedCompleteBy

* chore: converted data exchange approach complete meta to id

* chore: updated migration version

* wip: data exchange approach

* wip: data exchange approach gql, store, and resolvers

* feat: working data exchange approach creation and updates

* feat: several feedback elements implemented

* chore: implementing PR feedback

* chore: implementing PR feedback

* wip: marked complete by user account and dts tracking

* feat: first working version of plan data exchange approach

* chore: ran linter and fixed cache helper reference

* run eslint

* fix: corrected cyclic dependency and several linter guidances

* merging changes

* ran sql fluff linter on migrations

* run lint

* fix: restructed logic for is marked complete to utilize null state of MarkedByDts rather than explicit boolean field

* feat: added status handling

* chore: corrected file name

* chore: removed old debug print

* fix: fixed lagging status

* fix: added status to sql queries

* fix: corrected enum references from COMPLETE to COMPELETED

* chore: removed delete logic for dea

* chore: refactored IsDataExchangeApproachComplete resolver

* chore: updated enum to READY to conform more closely with other task list sections

---------

Co-authored-by: ClayBenson94 <clay.benson@oddball.io>
Co-authored-by: Steven Wade <steven.wade@oddball.io>
  • Loading branch information
3 people authored Oct 2, 2024
1 parent d9d02ac commit efc5617
Show file tree
Hide file tree
Showing 49 changed files with 6,656 additions and 1,353 deletions.
165 changes: 31 additions & 134 deletions MINT.postman_collection.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"opsEvalAndLearningID = responseData.opsEvalAndLearning.id",
"modelLeadID = responseData.collaborators[0].id",
"paymentsID = responseData.payments.id",
"dataExchangeApproachID = responseData.dataExchangeApproach.id",
"firstOpNeed = responseData.operationalNeeds[0].id",
"userID = responseData.createdByUserAccount.id",
"",
Expand All @@ -36,6 +37,7 @@
"pm.collectionVariables.set(\"opsEvalAndLearningID\", opsEvalAndLearningID);",
"pm.collectionVariables.set(\"modelLeadID\", modelLeadID);",
"pm.collectionVariables.set(\"paymentsID\", paymentsID);",
"pm.collectionVariables.set(\"dataExchangeApproachID\", dataExchangeApproachID)",
"pm.collectionVariables.set(\"operationalNeedID\", firstOpNeed);",
"pm.collectionVariables.set(\"userID\", userID);"
],
Expand All @@ -50,7 +52,7 @@
"body": {
"mode": "graphql",
"graphql": {
"query": "mutation createModelPlan{\n \n createModelPlan(modelName:\"Excellent Model\" ){\n id\n modelName\n createdByUserAccount{\n givenName\n id\n }\n operationalNeeds {\n id\n modelPlanID\n name\n key\n nameOther\n needed\n section \n } \n basics{\n id \n }\n generalCharacteristics {\n id\n }\n participantsAndProviders {\n id\n }\n beneficiaries {\n id\n }\n opsEvalAndLearning {\n id\n }\n collaborators {\n id\n }\n payments{\n id\n }\n }\n}\n ",
"query": "mutation createModelPlan{\n \n createModelPlan(modelName:\"Excellent Model\" ){\n id\n modelName\n createdByUserAccount{\n givenName\n id\n }\n operationalNeeds {\n id\n modelPlanID\n name\n key\n nameOther\n needed\n section \n } \n basics{\n id \n }\n generalCharacteristics {\n id\n }\n participantsAndProviders {\n id\n }\n beneficiaries {\n id\n }\n opsEvalAndLearning {\n id\n }\n collaborators {\n id\n }\n payments{\n id\n }\n dataExchangeApproach{\n id\n }\n }\n}\n ",
"variables": ""
}
},
Expand Down Expand Up @@ -411,6 +413,27 @@
},
"response": []
},
{
"name": "Update Data Exchange Approach",
"request": {
"method": "POST",
"header": [],
"body": {
"mode": "graphql",
"graphql": {
"query": "mutation updatePlanDataExchangeApproach {\n updatePlanDataExchangeApproach(id: \"{{dataExchangeApproachID}}\", changes: {\n # Page 1\n dataToCollectFromParticipants: [CLINICAL_DATA, OTHER]\n dataToCollectFromParticipantsReportsDetails: \"Detailed reports information\"\n dataToCollectFromParticipantsOther: \"Additional data to collect from participants\"\n dataWillNotBeCollectedFromParticipants: false\n dataToCollectFromParticipantsNote: \"Notes regarding data collection from participants\"\n\n # Page 2\n dataToSendToParticipants: [DATA_FEEDBACK_DASHBOARD]\n dataToSendToParticipantsNote: \"Notes about data being sent to participants\"\n\n # Page 3\n doesNeedToMakeMultiPayerDataAvailable: YES\n anticipatedMultiPayerDataAvailabilityUseCase: MORE_COMPETENT_ALERT_DISCHARGE_TRANSFER_NOTIFICATION\n doesNeedToMakeMultiPayerDataAvailableNote: \"Notes on multi-payer data availability\"\n\n doesNeedToCollectAndAggregateMultiSourceData: YES\n multiSourceDataToCollect: [COMMERCIAL_CLAIMS]\n multiSourceDataToCollectOther: \"Additional multi-source data to collect\"\n doesNeedToCollectAndAggregateMultiSourceDataNote: \"Notes on multi-source data collection\"\n\n # Page 4\n willImplementNewDataExchangeMethods: YES\n newDataExchangeMethodsDescription: \"Description of new data exchange methods\"\n newDataExchangeMethodsNote: \"Notes on new data exchange methods\"\n\n # Meta\n isDataExchangeApproachComplete: false\n }) {\n # Meta Fields\n id\n modelPlanID\n isDataExchangeApproachComplete\n\n # Page 1\n dataToCollectFromParticipants\n dataToCollectFromParticipantsReportsDetails\n dataToCollectFromParticipantsOther\n dataWillNotBeCollectedFromParticipants\n dataToCollectFromParticipantsNote\n\n # Page 2\n dataToSendToParticipants\n dataToSendToParticipantsNote\n\n # Page 3\n doesNeedToMakeMultiPayerDataAvailable\n anticipatedMultiPayerDataAvailabilityUseCase\n doesNeedToMakeMultiPayerDataAvailableNote\n doesNeedToCollectAndAggregateMultiSourceData\n multiSourceDataToCollect\n multiSourceDataToCollectOther\n doesNeedToCollectAndAggregateMultiSourceDataNote\n\n # Page 4\n willImplementNewDataExchangeMethods\n newDataExchangeMethodsDescription\n newDataExchangeMethodsNote\n additionalDataExchangeConsiderationsDescription\n isDataExchangeApproachComplete\n\n # User Accounts\n createdBy\n createdDts\n modifiedBy\n modifiedDts\n markedCompleteDts\n markedCompleteBy\n markedCompleteByUserAccount {\n id\n email\n }\n\n createdByUserAccount {\n commonName\n }\n modifiedByUserAccount {\n commonName\n }\n \n status\n }\n}\n",
"variables": ""
}
},
"url": {
"raw": "{{url}}",
"host": [
"{{url}}"
]
}
},
"response": []
},
{
"name": "Get Plan Payments (Deprecated)",
"request": {
Expand Down Expand Up @@ -650,7 +673,7 @@
"body": {
"mode": "graphql",
"graphql": {
"query": "mutation createDiscussionReply {\n createDiscussionReply (input: {\n discussionID: \"{{discussionID}}\"\n content: \"Let me look into it, ok? <span data-type=\\\"mention\\\" tag-type=\\\"USER_ACCOUNT\\\" class=\\\"mention\\\" data-id=\\\"ADMI\\\" data-label=\\\"ADMI\\\">@Audrey Abrams</span>!\"\n userRole: SOLUTION_ARCHITECT\n }) {\n id\n discussionID\n content{\n rawContent\n tags{\n id\n taggedField\n taggedContentTable\n taggedContentID\n entityUUID\n entityIntID\n entity{\n __typename\n ... on UserAccount{\n id\n commonName\n email\n }\n ... on PossibleOperationalSolution {\n name\n key\n }\n }\n }\n }\n isAssessment\n createdBy\n createdDts\n modifiedBy\n modifiedDts\n createdByUserAccount \n {\n commonName\n } \n modifiedByUserAccount\n {\n commonName\n } \n }\n}",
"query": "mutation createDiscussionReply {\n createDiscussionReply (input: {\n discussionID: \"{{discussionID}}\"\n content: \"Let me look into it, ok? <span data-type=\\\"mention\\\" tag-type=\\\"USER_ACCOUNT\\\" class=\\\"mention\\\" data-id=\\\"ADMI\\\" data-label=\\\"ADMI\\\">@Audrey Abrams</span>!\"\n userRole: IT_ARCHITECT\n }) {\n id\n discussionID\n content{\n rawContent\n tags{\n id\n taggedField\n taggedContentTable\n taggedContentID\n entityUUID\n entityIntID\n entity{\n __typename\n ... on UserAccount{\n id\n commonName\n email\n }\n ... on PossibleOperationalSolution {\n name\n key\n }\n }\n }\n }\n isAssessment\n createdBy\n createdDts\n modifiedBy\n modifiedDts\n createdByUserAccount \n {\n commonName\n } \n modifiedByUserAccount\n {\n commonName\n } \n }\n}",
"variables": ""
}
},
Expand Down Expand Up @@ -2656,137 +2679,6 @@
"response": []
}
]
},
{
"name": "ECHIMP",
"item": [
{
"name": "CR Echimp by id",
"request": {
"method": "POST",
"header": [],
"body": {
"mode": "graphql",
"graphql": {
"query": "query echimpCR {\n echimpCR(id: \"FFS3550\") {\n id\n versionNum\n initiator\n firstName\n lastName\n title\n sensitiveFlag\n implementationDate\n crSummary {\n rawContent\n }\n crStatus\n emergencyCrFlag\n relatedCrNumbers\n relatedCrTdlNumbers\n associatedModelUids\n }\n}",
"variables": ""
}
},
"url": {
"raw": "{{url}}",
"host": [
"{{url}}"
]
}
},
"response": []
},
{
"name": "All CR Echimp data",
"request": {
"method": "POST",
"header": [],
"body": {
"mode": "graphql",
"graphql": {
"query": "query echimpCR {\n echimpCRs {\n id\n versionNum\n initiator\n firstName\n lastName\n title\n sensitiveFlag\n implementationDate\n crSummary {\n rawContent\n }\n crStatus\n emergencyCrFlag\n relatedCrNumbers\n relatedCrTdlNumbers\n associatedModelUids\n }\n}",
"variables": ""
}
},
"url": {
"raw": "{{url}}",
"host": [
"{{url}}"
]
}
},
"response": []
},
{
"name": "All Echimp CRS And TDLS",
"request": {
"method": "POST",
"header": [],
"body": {
"mode": "graphql",
"graphql": {
"query": "query echimpCRAndTDLS {\n echimpCRAndTDLS{\n __typename\n ... on EChimpCR {\n id\n versionNum\n initiator\n firstName\n lastName\n title\n sensitiveFlag\n implementationDate\n crSummary {\n rawContent\n }\n crStatus\n emergencyCrFlag\n relatedCrNumbers\n relatedCrTdlNumbers\n associatedModelUids\n }\n ... on EChimpTDL {\n id\n versionNum\n initiator\n firstName\n lastName\n title\n issuedDate\n status\n associatedModelUids\n }\n }\n}",
"variables": ""
}
},
"url": {
"raw": "{{url}}",
"host": [
"{{url}}"
]
}
},
"response": []
},
{
"name": "TDL Echimp by id",
"request": {
"method": "POST",
"header": [],
"body": {
"mode": "graphql",
"graphql": {
"query": "query echimpTDL {\n echimpTDL(id: \"TDL240535\") {\n id\n versionNum\n initiator\n firstName\n lastName\n title\n issuedDate\n status\n associatedModelUids\n }\n\n}",
"variables": ""
}
},
"url": {
"raw": "{{url}}",
"host": [
"{{url}}"
]
}
},
"response": []
},
{
"name": "ALL TDL Echimp data",
"request": {
"method": "POST",
"header": [],
"body": {
"mode": "graphql",
"graphql": {
"query": "query echimpTDL {\n echimpTDLs {\n id\n versionNum\n initiator\n firstName\n lastName\n title\n issuedDate\n status\n associatedModelUids\n }\n\n}",
"variables": ""
}
},
"url": {
"raw": "{{url}}",
"host": [
"{{url}}"
]
}
},
"response": []
}
]
},
{
"name": "Get Model Plan with ECHIMP data",
"request": {
"method": "POST",
"header": [],
"body": {
"mode": "graphql",
"graphql": {
"query": "query modelPlan ($id: UUID!) {\n modelPlan (id: $id) {\n id\n modelName\n echimpCRs{\n title\n }\n echimpTDLs{\n title\n }\n\n }\n}",
"variables": "{\n \"id\": \"{{modelPlanID}}\"\n}"
}
},
"url": {
"raw": "{{url}}",
"host": [
"{{url}}"
]
}
},
"response": []
}
],
"auth": {
Expand Down Expand Up @@ -2842,7 +2734,7 @@
},
{
"key": "modelPlanID",
"value": "082b49d3-b548-48cb-9119-77a281bc2a8c"
"value": ""
},
{
"key": "basicsID",
Expand Down Expand Up @@ -2872,6 +2764,11 @@
"key": "paymentsID",
"value": ""
},
{
"key": "dataExchangeApproachID",
"value": "",
"type": "string"
},
{
"key": "operationalNeedID",
"value": ""
Expand Down
40 changes: 39 additions & 1 deletion cmd/dbseed/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -441,10 +441,48 @@ func (s *Seeder) SeedData() {
"cmmiGroups": []string{"PATIENT_CARE_MODELS_GROUP", "SEAMLESS_CARE_MODELS_GROUP"},
"completeICIP": "2020-05-13T20:47:50.12Z",
"phasedIn": true,
"clearanceStarts": now.AddDate(0, 3, 0),
"clearanceStarts": time.Now().AddDate(0, 3, 0),
"highLevelNote": "Some high level note",
},
)

// Send a notification for Data Exchange Approach Completed
dataExchangeApproach := models.NewPlanDataExchangeApproach(
models.NewCoreTaskListSection(
planWithDocuments.CreatedBy,
planWithDocuments.ID,
),
)

dataExchangeApproach.ID = uuid.MustParse("01020304-0506-0708-090a-0b0c0d0e0f10")

// create an actor principal for testing notifications

actorPrincipal := s.getTestPrincipalByUsername("MINT")

// Use a test user to mark the data exchange approach as complete
testUser := s.getTestPrincipalByUsername("BTAL")

err = resolvers.SendDataExchangeApproachCompletedNotification(
s.Config.Context,
s.Config.EmailService,
s.Config.EmailTemplateService,
s.Config.AddressBook,
actorPrincipal.UserAccount.ID,
s.Config.Store,
[]*models.UserAccountAndNotificationPreferences{
{
UserAccount: *testUser.UserAccount,
PreferenceFlags: models.DefaultUserNotificationPreferencesFlags(),
},
},
planWithDocuments,
dataExchangeApproach,
testUser.UserAccount.ID,
)
if err != nil {
panic(fmt.Errorf("failed to send data exchange approach completed notification: %w", err))
}
}

func (s *Seeder) SetDefaultUserViews() {
Expand Down
26 changes: 26 additions & 0 deletions cmd/test_email/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@ func main() {
//DiscussionReply email
sendDiscussionReplyOriginatorTestEmail(emailService, templateService, addressBook)

// Model plan emails
sendModelPlanShareTest(emailService, templateService, addressBook)
sendDateChangedEmailsTest(emailService, templateService, addressBook)
sendCollaboratorAddedEmailTest(emailService, templateService, addressBook)
sendDataExchangeApproachCompletedEmailNotificationTest(emailService, templateService, addressBook)
sendFeedbackEmail(emailService, templateService, addressBook)
reportAProblemEmail(emailService, templateService, addressBook)

Expand Down Expand Up @@ -395,6 +397,30 @@ func sendCollaboratorAddedEmailTest(
noErr(err)
}

func sendDataExchangeApproachCompletedEmailNotificationTest(
emailService oddmail.EmailService,
templateService email.TemplateService,
addressBook email.AddressBook,
) {

modelPlan := models.NewModelPlan(
uuid.Nil,
"Retcon Plan",
)

err := resolvers.SendDataExchangeApproachCompletedEmailNotification(
emailService,
templateService,
addressBook,
modelPlan,
"marty.mcfly@delorean.88",
"Doc Brown",
true,
)

noErr(err)
}

func sendFeedbackEmail(
emailService oddmail.EmailService,
templateService email.TemplateService,
Expand Down
Loading

0 comments on commit efc5617

Please sign in to comment.