Investigate provider-to-patient email functionality in CARLOS#3096
Investigate provider-to-patient email functionality in CARLOS#3096Ben-Heerema wants to merge 1 commit into
Conversation
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: ASSERTIVE Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Finding: active provider-to-patient email pathThe provider-to-patient send path currently appears to be the eForm email workflow:
Relevant files:
|
Reviewer's GuideAdds a new investigation spec documenting the scope, validation plan, and placeholder for findings around provider-to-patient email functionality in CARLOS. File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Snapshot WarningsEnsure that dependencies are being submitted on PR branches and consider enabling retry-on-snapshot-warnings. See the documentation for more information and troubleshooting advice. Scanned FilesNone |
Finding: CARLOS Messenger is separate from patient emailThe internal Messenger UI can associate a demographic/patient with a message, but its recipient model is provider/group based. I did not find evidence that the Messenger compose flow directly sends patient-facing email. The patient-facing email route found so far is the eForm email workflow, not Relevant files:
|
There was a problem hiding this comment.
Code Review
This pull request adds a new specification document, provider-patient-email-investigation.md, to outline the scope and validation plan for investigating provider-to-patient email functionality. The reviewer's feedback focuses on adhering to the repository style guide by using 'CARLOS EMR' in documentation, focusing the investigation on active email pathways rather than decommissioned legacy modules, and documenting findings directly within the file instead of using ephemeral pull request comments.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| @@ -0,0 +1,28 @@ | |||
| # Provider-to-Patient Email Investigation | |||
There was a problem hiding this comment.
According to the repository style guide, 'CARLOS EMR' should be used in documentation headers and README files.
| # Provider-to-Patient Email Investigation | |
| # Provider-to-Patient Email Investigation in CARLOS EMR |
References
- Use 'CARLOS EMR' in README files, documentation headers, GitHub templates, workflow descriptions, and user-facing messages. (link)
|
|
||
| ## Purpose | ||
|
|
||
| Investigate how provider-to-patient email functionality works in CARLOS, including available user flows, backend routing, configuration requirements, and expected behavior in local development. |
There was a problem hiding this comment.
According to the repository style guide, 'CARLOS EMR' is preferred for documentation and user-facing content.
| Investigate how provider-to-patient email functionality works in CARLOS, including available user flows, backend routing, configuration requirements, and expected behavior in local development. | |
| Investigate how provider-to-patient email functionality works in CARLOS EMR, including available user flows, backend routing, configuration requirements, and expected behavior in local development. |
References
- Use 'CARLOS EMR' in README files, documentation headers, GitHub templates, workflow descriptions, and user-facing messages. (link)
| ## Scope | ||
|
|
||
| - Identify UI entry points for provider-to-patient email. | ||
| - Trace backend actions and services used to compose and send email. |
There was a problem hiding this comment.
When tracing the backend actions, please note that the legacy email notifications module was recently removed as part of the active code cleanup (as specified in the repository style guide). The investigation should focus on active email pathways, such as those associated with eForms or other modern modules, to avoid spending effort on decommissioned code.
References
- The repository style guide notes that legacy email notifications have been removed as part of the active code cleanup. (link)
|
|
||
| ## Findings | ||
|
|
||
| Detailed findings will be added as pull request comments as the workflow is traced and verified. |
There was a problem hiding this comment.
To preserve the findings of this investigation for future reference, please document the results directly within this file before merging the pull request, rather than relying solely on ephemeral pull request comments.
| Detailed findings will be added as pull request comments as the workflow is traced and verified. | |
| Detailed findings will be documented directly in this file as the workflow is traced and verified. |
Finding: email availability depends on several gatesThe eForm toolbar Email button and compose flow depend on these conditions:
If the email system is not configured, the toolbar disables the Email button with the title Relevant files:
|
Finding: local development SMTP failure is expected without a mail serviceIn the current local develop runtime, email delivery reached the SMTP send step but failed because the configured sender tried to connect to Observed error: Runtime/default properties point email at local SMTP: email.host=localhost
email.port=25This confirms the compose/send path is active, but local delivery requires either:
Relevant files/config:
|
Finding: no general chart-level email composer found yetI found the eForm-launched patient email workflow and the admin resend workflow, but I did not find a general provider chart action that opens a blank patient email composer directly from the chart without eForm context. This may be a product gap or a workflow decision worth confirming:
Relevant files:
|
Signed-off-by: Ben <ben@maplecreekmedical.ca>
2693ee6 to
a5cbedc
Compare
|
|
Current thoughts: |
Finding: email compose UI layout issue is existing
|
Apply reviewer (gemini, cubic) and SonarCloud feedback within the existing scope: - Render the disabled-encryption warning as a Bootstrap alert (alert-danger, role=alert) instead of a .card-footer placed between the card header and body, which produced double borders / stacked gray backgrounds and was semantically incorrect. - Drop the now-unused .encryptionDisabledWarning CSS rule (the alert supplies the danger styling). - Make the unencrypted subject and body PHI warnings visually prominent with text-danger and icon spacing (me-2). - Associate the encryption password/clue/encrypt-attachments labels with their controls via for= to clear SonarCloud Web:S6853 accessibility findings. Refs #3096 Signed-off-by: Ben Heerema <ben@maplecreekmedical.ca>
…ed section - Place the To (recipient) and From (sender) cards side by side in a responsive row, To first/leftmost, using equal-height cards so the row stays tidy as recipients are added. Switch both to a label-on-top layout and attach the recipient remove button as an input-group. - Reword the unencrypted-body warning to direct staff to put PHI in the encrypted section below (instead of the plain, unencrypted body), across all five locale bundles. Refs #3096 Signed-off-by: Ben Heerema <ben@maplecreekmedical.ca>
Address review/CI findings on the restructured To card:
- Encode the patient name and recipient email (visible inputs and the
submitted hidden field) with forHtmlAttribute for the HTML attribute
context, preventing attribute-injection/XSS from demographic-derived values.
- Replace ${loop.index + 1} with the equivalent space-free ${loop.count} in
the recipient id/for attributes so the generated id has no space character
(github-code-quality 'malformed id attribute').
Refs #3096
Signed-off-by: Ben Heerema <ben@maplecreekmedical.ca>
Apply the two remaining defense-in-depth cleanups in the email compose JSP:
- Replace ${loop.index + 1} with the equivalent space-free ${loop.count} in
the attachment accordion ids (header/body/object) and their data-bs-target /
aria-controls / aria-labelledby references, so generated id attributes carry
no space character. Rendered ids and the accordion wiring are unchanged.
- Encode the hidden emailConsentStatus value with forHtmlAttribute for the
attribute context, consistent with the other recipient fields.
Refs #3096
Signed-off-by: Ben Heerema <ben@maplecreekmedical.ca>
The PDF-preview <object> had no child content, so assistive tech and browsers that cannot render the inline preview were left with nothing (SonarCloud Web:S5264). Add a fallback paragraph showing the attachment file name, encoded with forHtml. Fallback only renders when the <object> cannot display the PDF; the inline preview and accordion behaviour are unchanged. Refs #3096 Signed-off-by: Ben Heerema <ben@maplecreekmedical.ca>
…UX (#3100) * fix: restore provider-to-patient email compose layout and encryption UX The email compose form was migrated to a flex container (d-flex flex-wrap), turning each major .card section into a content-sized flex item that wrapped into a scattered, masonry-like layout. Restore a deliberate vertical compose layout and clean up cramped controls: - Replace the flex form root with a scoped .email-compose-form (max-width 980px, full-width stacked cards). - Widen cramped To labels (col-sm-1 -> col-sm-3) and encryption labels (col-sm-2 -> col-sm-3) and vertically align rows. - Move the encryption toggle out of the <h5> into a flex card-header. - Add a visible 'subject is not encrypted' PHI warning (only the body was warned before). - Add an explicit warning whenever encryption is toggled off. New i18n keys (email.compose.msg.unencryptedSubject, email.compose.msg.encryptionDisabledWarning) added to all five locale bundles. Output uses existing fmt:message vars; no user input is rendered. Refs #3096 - Render the disabled-encryption warning as a Bootstrap alert (alert-danger, role=alert) instead of a .card-footer placed between the card header and body, which produced double borders / stacked gray backgrounds and was semantically incorrect. - Drop the now-unused .encryptionDisabledWarning CSS rule (the alert supplies the danger styling). - Make the unencrypted subject and body PHI warnings visually prominent with text-danger and icon spacing (me-2). - Associate the encryption password/clue/encrypt-attachments labels with their controls via for= to clear SonarCloud Web:S6853 accessibility findings. Refs #3096 Signed-off-by: Ben Heerema <ben@maplecreekmedical.ca> * feat: pair To/From side by side and point body PHI warning to encrypted section - Place the To (recipient) and From (sender) cards side by side in a responsive row, To first/leftmost, using equal-height cards so the row stays tidy as recipients are added. Switch both to a label-on-top layout and attach the recipient remove button as an input-group. - Reword the unencrypted-body warning to direct staff to put PHI in the encrypted section below (instead of the plain, unencrypted body), across all five locale bundles. - Encode the patient name and recipient email (visible inputs and the submitted hidden field) with forHtmlAttribute for the HTML attribute context, preventing attribute-injection/XSS from demographic-derived values. - Replace ${loop.index + 1} with the equivalent space-free ${loop.count} in the recipient id/for attributes so the generated id has no space character (github-code-quality 'malformed id attribute'). The PDF-preview <object> had no child content, so assistive tech and browsers that cannot render the inline preview were left with nothing (SonarCloud Web:S5264). Add a fallback paragraph showing the attachment file name, encoded with forHtml. Fallback only renders when the <object> cannot display the PDF; the inline preview and accordion behaviour are unchanged. Refs #3096 Signed-off-by: Ben Heerema <ben@maplecreekmedical.ca>
Production-readiness assessment: provider-to-patient emailFollowing up on the investigation findings above, here is a code-level assessment of what stands between the current email feature and production use with real patient data. This is based on reading the actual send path ( TL;DR: the plumbing works and privilege gating is solid ( Blockers (must fix before any real patient email)1. Consent is displayed but never enforced.
This is the single biggest compliance gap. Enforcement belongs in 2. The "encryption" scheme is weak and self-defeating.
This needs a design decision, not a patch: random per-message passwords delivered out-of-band (SMS/phone), a portal-link model, or dropping the "encrypted" claim from the UI entirely. PR #3100's warnings are honest UX but don't change the underlying scheme. 3. 4. Credentials and secrets stored in plaintext. 5. PHI temp files are never cleaned up. Operational gaps6. No admin UI for sender accounts. 7. Synchronous, fire-once sending. 8. No attachment size limits. No per-attachment or total-message cap before the SMTP send or the SendGrid Base64 encode — oversized messages just fail at the provider (SendGrid ~30 MB) with a runtime error. 9. Deliverability/ops prerequisites (outside the code). A production sender domain with SPF/DKIM/DMARC, a real relay or SendGrid account, and monitoring of FAILED rows in the email log. PR #3097's Postfix capture covers the devcontainer only. Hardening (important, not blocking)10. Test coverage on the core path is nearly empty. 11. Assorted send-path issues:
Positive findings, for balance
Suggested sequencing
Also still open from this investigation: whether a direct chart-level "email patient" entry point (outside the eForm flow) is a product requirement — that remains a question for discussion, not a defect. Assessment generated with Claude Code; file/line references verified against |





Summary
This PR investigates how provider-to-patient email functionality currently works in CARLOS, including the available user flows, backend routing, configuration requirements, and expected behavior in local development.
Scope
Validation Plan
Notes
Detailed findings will be added as PR comments as each part of the workflow is traced and verified.
Summary by Sourcery
Documentation:
Summary by cubic
Adds a documentation spec mapping provider‑to‑patient email in CARLOS: UI entry points, backend routes, required permissions/consent, sender config, and local setup. Includes a validation plan to test chart/eForm flows, edge cases (no email/consent, delivery outages), and review logs/status to capture gaps and failure modes.
Written for commit a5cbedc. Summary will update on new commits.