-
Notifications
You must be signed in to change notification settings - Fork 24
O3-5088: Add Automatic Calculation for PHQ-9 Total Score in Mental Health Assessment Form #44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
… score 1) Added a calculate object with a calculateExpression to the PHQ-9 score field that automatically sums all 9 questions Scoring Logic. 2) Each answer is mapped to its correct score: Not at all (160215AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) = 0 Several days (167000AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) = 1 More than half the days (167001AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) = 2 Nearly every day (167002AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) = 3 3) Read-only Field - Added a readonly behavior to the score field so users can't manually edit it
| "max": "27", | ||
| "min": "0", | ||
| "showDate": "", | ||
| "calculate": { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The inline calculateExpression here is quite long (~1000 chars) and repeats the UUID-to-score mapping 9 times. Could we consider factoring it out into a reusable custom expression helper function in the form engine instead?
We could add a calcPHQ9Score() helper to common-expression-helpers.ts (similar to calcBMI(), calcEDD(), etc) that looks like this:
/**
* Calculates PHQ-9 (Patient Health Questionnaire-9) depression screening score
* Supports both PHQ-2 (questions 1-2) and full PHQ-9 (questions 1-9)
* Handles hidden/conditional questions by treating undefined/null values as 0
*
* @param responses - Variable number of PHQ question responses (concept UUIDs)
* @returns Total score (0-27 for full PHQ-9, 0-6 for PHQ-2 only)
*
* @example
* // PHQ-2 negative screen (questions 3-9 hidden)
* calcPHQ9Score(phq2_1, phq2_2, phq9_3, phq9_4, phq9_5, phq9_6, phq9_7, phq9_8, phq9_9)
* // Returns: 0 if both answered "Not at all"
*
* @example
* // Full PHQ-9
* calcPHQ9Score(phq2_1, phq2_2, phq9_3, phq9_4, phq9_5, phq9_6, phq9_7, phq9_8, phq9_9)
* // Returns: Sum of all 9 responses (0-27)
*/
calcPHQ9Score = (...responses: (string | null | undefined)[]): number => {
const scoreMap: Record<string, number> = {
'160215AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA': 0, // Not at all
'167000AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA': 1, // Several days
'167001AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA': 2, // More than half the days
'167002AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA': 3, // Nearly every day
};
return responses.reduce((sum, answer) => {
return sum + (answer ? (scoreMap[answer] ?? 0) : 0);
}, 0);
};And then we could simplify the calculateExpression in this form by leveraging the new expression helper as follows:
"calculate": {
"calculateExpression": "calcPHQ9Score(phq2_1, phq2_2, phq9_3, phq9_4, phq9_5, phq9_6, phq9_7, phq9_8, phq9_9)"
}Benefits of this approach:
- Easier to read, test, and maintain
- Centralizes the UUID mapping logic
- Follows DRY principle
- Matches the architectural pattern used elsewhere in the codebase
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@denniskigen thanks for your feedback, are you suggesting that the change (custom expression helper function) should be implemented in the form engine’s codebase, not directly in the form JSON? @samuelmale is this something you can assist us?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. And here's the PR openmrs/openmrs-esm-form-engine-lib#650
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update: PR merged. Should be available soon.
…ssessment Form Summary of Changes Automated PHQ-9 Scoring Forms now support automatic calculation of PHQ-9 scores (range: 0–27) without manual entry. The score is computed based on responses to the nine PHQ items at the point of form entry. Refactor to Reusable Calculation Function Instead of repeating long inline calculateExpression logic across forms, the scoring logic has been moved into a clean, reusable helper function within the front-end form engine. This simplifies form JSON, improves maintainability, and ensures consistent application of depression screening logic. This update aligns with and builds on the enhancement implemented in PR: openmrs/openmrs-esm-patient-chart#2787
|
@denniskigen please review the changes i have made based on the changes you implemented on this PR |
configuration/backend_configuration/ampathforms/Mental Health Assessment Form.json
Outdated
Show resolved
Hide resolved
configuration/backend_configuration/ampathforms/Mental Health Assessment Form.json
Show resolved
Hide resolved
configuration/backend_configuration/ampathforms/Mental Health Assessment Form.json
Outdated
Show resolved
Hide resolved
Converted PHQ-2 Score field from obs to a display-only calculated field
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Thanks, @VeronicaMuthee!
Added calculateExpression for the Mental Health Assessment PHQ-9 Score
Added a calculate object with a calculateExpression to the PHQ-9 score field that automatically sums all 9 questions Scoring Logic.
Each answer is mapped to its correct score:
Not at all (160215AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) = 0 Several days (167000AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) = 1 More than half the days (167001AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) = 2 Nearly every day (167002AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) = 3
Read-only Field - Added a readonly behavior to the score field so users can't manually edit it