Skip to content

Feature: show providers' public and private documents in the attachment manager#2295

Open
LiamStanziani wants to merge 27 commits into
developfrom
feat/show-providers-private-documents-attachment-manager
Open

Feature: show providers' public and private documents in the attachment manager#2295
LiamStanziani wants to merge 27 commits into
developfrom
feat/show-providers-private-documents-attachment-manager

Conversation

@LiamStanziani

@LiamStanziani LiamStanziani commented Feb 17, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds provider-owned documents to the attachment manager so providers can attach their own private or public eDocs to consultations and eForms, alongside the existing patient-specific documents.

Closes #2282.

User-facing changes

  • Attachment manager now shows three document sections:
    • Patient Documents (renamed from "Documents")
    • Public eDocs — shared provider library
    • Private eDocs — current provider's private library
  • Private doc selections trigger a confirmation dialog warning that private documents will become visible to anyone with access to the record once attached. The warning only fires on new attachments per the spec.
  • Cross-provider private-doc attachments render in italics with an (attached by another provider) label, so reviewing providers can see that a doc they're looking at belongs to a different provider's library.
  • Soft-deleted attached docs remain retrievable and render in italics with a (deleted) label so they don't silently vanish from saved consults/eForms after a library cleanup.

New consultation attachment page:

image

Cross-provider consultation attachment page (deleted documents, attached documents by other providers):

image

Warning popup on attachment page when attaching new private provider documents

image

Note: since both consultation and eForm's use the same base JSP for the attachment manager, I have only shown screenshots based on the consultation flow since attaching both shouldn't show any differences.

Implementation approach

DAO layer — unchanged shape

The 3 attached-doc DAO methods (findDocsAndConsultDocsByConsultId, findDocsAndEFormDocsByFdid, findDocsAndConsultResponseDocsByConsultId) are unchanged versus develop. Their pre-PR 2-column contract is preserved so the 16 downstream callers (PDF printing, fax, REST APIs, etc.) see no behavioral change.

EDocUtil — ctl enrichment for attached docs

New enrichAttachedWithCtl helper runs after the DAO returns attached-doc tuples. It does one batch query via a new CtlDocumentDao.findByDocumentNos(List<Integer>) to fetch ctl rows for all attached docs and picks the preferred ctl per doc (provider bindings win over demographic so library docs classify correctly). Orphan docs with no ctl row pass through unclassified and fall through to the patient section.

DocumentPreview2Action — attached-state classification

New mergeAttachedContext / mergeSingleAttachedDoc walk the attached-doc list and classify each into the correct section (patient / provider public / provider private), re-injecting soft-deleted items and flagging cross-provider private docs via foreignPrivateDocIds.

JSP and JS

  • Three new sections in attachDocument.jsp with select-all + show-more + preview + deleted/foreign markers.
  • Shared helpers in the JSP <script> block: confirmPrivateDocsIfAny, buildDelegateInput, syncPreCheckedToDelegates — consumed by both the consult JSP and the eForm toolbar.
  • data-delegate-type="doc" attribute on doc delegate inputs so the toolbar JS resolves checkboxes by name+value across the three sections (a plain #docNo<id> selector would only match the patient section).
  • Dialog reopen sync: unchecks any server-pre-checked box whose delegate was removed in a prior dialog session (fixes the issue where an unchecked doc came back checked on reopen before the consult/eForm was saved).

Privacy and PHI considerations

The attachment uses a reference-based model: attaching a provider's private doc to a consult creates a row in consultdocs (or eform_docs) pointing at the original document_no, not a copy.

Key property: there is no reverse lookup in the application code that takes a document_no and returns every patient/consult/eForm it's attached to. Each forward lookup (DisplayDemographicConsultationRequests, eForm display, etc.) is scoped to a single request/fdid, so one provider document attached to multiple patients' records never becomes cross-patient visibility through app code.

Testing

Automated

  • DocumentDaoAttachedFindIntegrationTest — 14 cases across 3 nested classes covering each attached-doc query: happy path, multi-doc, orphan docs (no ctl row), soft-deleted, scope-by-id, non-DOC docType exclusion.
  • CtlDocumentDaoFindByDocumentNosIntegrationTest — 6 cases for the new batch method: null input, empty input, single doc, multiple docs, doc with multiple ctl rows, scope-by-doc-ids.
  • DocumentPreview2ActionMergeUnitTest — 12 cases across 5 nested classes covering the full matrix of mergeSingleAttachedDoc classification: patient / public provider / own private / foreign private × active / deleted, plus edge cases (null current provider, legacy "provider" vs "providers" module spelling).

Manual smoke tests performed

Covered all scenarios from the spec's "Testing Performed" section plus several derived ones:

  • Fresh attachment dialog renders all three sections ✓
  • Private-doc attach triggers warning; public-doc attach does not ✓
  • Warning does NOT fire when reopening a saved consult/eForm with pre-existing attachments and no changes (spec's no-change exemption) ✓
  • Dialog reopen sync: uncheck → close → reopen → stays unchecked ✓
  • Each provider only sees their own private docs in the picker (Provider B cannot browse Provider A's library) ✓
  • Provider B sees Provider A's attached private docs with "(attached by another provider)" label ✓
  • Soft-deleted attached docs remain retrievable with "(deleted)" label ✓
  • eForm save → reopen → provider-section boxes still pre-checked ✓
  • eForm Email workflow includes attached provider docs in the PDF ✓

Playwright verification

Confirmed the following at the DOM level in a running dev instance:

  • Dialog renders Patient Documents, Public eDocs, Private eDocs with correct items and CSS classes (providerPrivateDoc, foreign-doc, deleted-doc).
  • syncPreCheckedToDelegates correctly unchecks/reverts class/strips data-pre-attached when delegate is missing, and leaves state alone when delegate is present.
  • Cross-provider scenario on consult 106: all 6 of openodoc's private docs rendered under Private eDocs with foreign-doc class and "(attached by another provider)" label.

Design decisions worth noting

  • Reference vs. copy — reference for both eForm and consult. The spec flags this as a reviewable design question; per-workflow split ("copy for consult, reference for eForm") can be added in a follow-up once user feedback is gathered.
  • Provider-wins ctl tiebreaker — in the hypothetical case where a doc has multiple ctl bindings, the provider binding wins so library docs classify consistently. In the current data pattern this doesn't occur (invariant: one ctl per document_no, verified via GROUP BY document_no HAVING COUNT(*) > 1 → 0 rows).
  • Warning exemption on no-change — reopening a dialog on a pre-existing private attachment and making no changes does not re-trigger the warning (matches spec).

@LiamStanziani LiamStanziani self-assigned this Feb 17, 2026
@sourcery-ai

sourcery-ai Bot commented Feb 17, 2026

Copy link
Copy Markdown

Reviewer's Guide

Implements provider public/private eDoc sections in the attachment manager for consults and eForms, centralizes attached-doc classification, enforces _edoc read security, normalizes document metadata, and adds DAO helpers plus tests around attached-document querying and ctl classification.

Sequence diagram for closing attachment dialog with private eDoc warning and delegate sync

sequenceDiagram
    actor Provider
    participant Dialog as attachDocument.jsp
    participant Parent as ParentForm_or_Toolbar

    Provider->>Dialog: Click OK to close attachment dialog
    Dialog->>Dialog: confirmPrivateDocsIfAny('#attachDocumentsForm')
    alt one or more new private eDocs selected
        Dialog->>Provider: confirm(...) warning about sharing private eDocs
        alt Provider cancels
            Provider-->>Dialog: Cancel
            Dialog-->>Provider: Abort close (return false)
        else Provider confirms
            Provider-->>Dialog: OK
            Dialog->>Dialog: Build deduped selection with attachable_check
            Dialog->>Parent: For each checked box create hidden delegate via buildDelegateInput
            Dialog->>Parent: Populate entry_name+value rows for attachments
            Dialog->>Parent: Remove rows for unchecked _pre_check items
            Dialog->>Dialog: Downgrade *_pre_check to *_check and clear data-pre-attached
            Dialog-->>Provider: Close dialog
        end
    else no new private eDocs selected
        Dialog->>Dialog: Skip warning
        Dialog->>Parent: Sync delegates from checked attachable_check inputs
        Dialog->>Parent: Remove delegates for unchecked *_pre_check inputs
        Dialog-->>Provider: Close dialog
    end
Loading

Sequence diagram for fetching consult or eForm documents with provider sections

sequenceDiagram
    actor Provider
    participant UI as Consult_or_eForm_UI
    participant Action as DocumentPreview2Action
    participant Util as EDocUtil
    participant DAO as CtlDocumentDao

    Provider->>UI: Open attachment dialog
    UI->>Action: fetchConsultDocuments or fetchEFormDocuments(demographicNo, requestId or fdid)
    Action->>Action: LoggedInInfo.getLoggedInInfoFromSession(request)
    Action->>Action: securityInfoManager.hasPrivilege(_edoc, r)
    alt missing _edoc read privilege
        Action-->>UI: SecurityException
        UI-->>Provider: Show access denied
    else has privilege
        Action->>Action: positiveIntParamOrDefault on demographicNo
        Action->>Action: positiveIntParamOrNull on requestId or fdid
        Action->>Action: populateCommonDocs(loggedInInfo, demographicNo)
        Action->>Util: listDocs(demographic, demographicNo, PRIVATE, OBSERVATIONDATE)
        Util->>DAO: findDocuments via DocumentDao (implicit)
        DAO-->>Util: Document rows
        Util-->>Action: allDocuments as EDoc list
        Action->>Util: getProviderPrivateDocs(loggedInInfo)
        Util->>Util: listDocs(providers, providerNo, PRIVATE, OBSERVATIONDATE)
        Util-->>Action: providerPrivateDocs
        Action->>Util: getProviderPublicDocs(loggedInInfo)
        Util->>Util: listDocs(providers, providerNo, PUBLIC, OBSERVATIONDATE)
        Util-->>Action: providerPublicDocs
        Action->>Action: populateAttachedContextForConsult or populateAttachedContextForEForm
        Action->>Util: listDocs attached for consult or eForm (EDocUtil.ATTACHED)
        Util->>DAO: findByDocumentNos for ctl_document
        DAO-->>Util: CtlDocument rows
        Util->>Util: enrichAttachedWithCtl attach module and moduleId
        Util-->>Action: attachedDocs with classification data
        Action->>Action: mergeAttachedContext(loggedInInfo, attachedDocs)
        Action-->>UI: Forward to attachDocument.jsp with request attributes
        UI-->>Provider: Render Patient Documents, Public eDocs, Private eDocs sections
    end
Loading

Entity relationship diagram for documents and ctl_document classification

erDiagram
    DOCUMENT {
        int document_no PK
        string description
        date observationdate
        int public1
        char status
        string contenttype
        datetime contentdatetime
    }

    CTL_DOCUMENT {
        int document_no PK
        string module PK
        int module_id PK
    }

    PROVIDER {
        int provider_no PK
    }

    DEMOGRAPHIC {
        int demographic_no PK
    }

    DOCUMENT ||--o{ CTL_DOCUMENT : has_binding
    PROVIDER ||--o{ CTL_DOCUMENT : provider_binding
    DEMOGRAPHIC ||--o{ CTL_DOCUMENT : demographic_binding

    %% Classification rules implemented in code:
    %% - CTL_DOCUMENT.module in {provider, providers} => provider document
    %% - DOCUMENT.public1 = 1 => public provider document
    %% - DOCUMENT.public1 = 0 and provider binding => private provider document
    %% - No provider binding or module not provider => patient document
Loading

Class diagram for updated document attachment and classification logic

classDiagram
    class DocumentPreview2Action {
        -HttpServletRequest request
        -DocumentAttachmentManager documentAttachmentManager
        -FormsManager formsManager
        -SecurityInfoManager securityInfoManager
        -ObjectMapper objectMapper
        +String fetchConsultDocuments()
        +String fetchEFormDocuments()
        -void populateCommonDocs(LoggedInInfo loggedInInfo, String demographicNo)
        -void populateAttachedContextForConsult(LoggedInInfo loggedInInfo, String demographicNo, String requestId)
        -void populateAttachedContextForEForm(LoggedInInfo loggedInInfo, String demographicNo, String fdid)
        -void mergeAttachedContext(LoggedInInfo loggedInInfo, List~EDoc~ attachedDocs)
        +static void mergeSingleAttachedDoc(EDoc attachedDoc, String currentProviderNo, List~EDoc~ allDocuments, List~EDoc~ providerPrivateDocs, List~EDoc~ providerPublicDocs, Set~String~ foreignPrivateDocIds)
        +static boolean isOwnedByCurrentProvider(EDoc doc, String currentProviderNo)
        +static boolean isProviderModule(String module)
        -static String positiveIntParamOrNull(String value)
        -static String positiveIntParamOrDefault(String value, String defaultValue)
    }

    class EDocUtil {
        -static CtlDocumentDao ctlDocumentDao
        +static ArrayList~EDoc~ listDocs(LoggedInInfo loggedInInfo, String module, String moduleId, String docType, String publicDoc, EDocSort sort)
        -static ArrayList~EDoc~ listDocs(LoggedInInfo loggedInInfo, boolean attached, String module, String moduleId, String docType, String publicDoc, EDocSort sort, String includeOption)
        -static void enrichAttachedWithCtl(List~EDoc~ attachedDocs)
        -static boolean preferProvider(CtlDocument candidate, CtlDocument current)
        +static List~EDoc~ getProviderPrivateDocs(LoggedInInfo loggedInInfo)
        +static List~EDoc~ getProviderPublicDocs(LoggedInInfo loggedInInfo)
        +static EDoc getEDocFromDocId(String docId)
    }

    class CtlDocumentDao {
        +List~CtlDocument~ findByDocumentNoAndModule(Integer ctlDocNo, String module)
        +List~CtlDocument~ findByDocumentNos(List~Integer~ documentNos)
    }

    class CtlDocumentDaoImpl {
        -EntityManager entityManager
        +List~CtlDocument~ findByDocumentNoAndModule(Integer ctlDocNo, String module)
        +List~CtlDocument~ findByDocumentNos(List~Integer~ documentNos)
    }

    class CtlDocument {
        +CtlDocumentPK id
        +CtlDocumentPK getId()
    }

    class CtlDocumentPK {
        +Integer documentNo
        +String module
        +Integer moduleId
        +Integer getDocumentNo()
        +String getModule()
        +Integer getModuleId()
    }

    class EDoc {
        +String docId
        +String description
        +char status
        +String observationDate
        +String docPublic
        +String module
        +String moduleId
        +String getDocId()
        +char getStatus()
        +String getModule()
        +String getModuleId()
        +void setStatus(char status)
        +void setObservationDate(String observationDate)
        +void setDocPublic(String docPublic)
        +void setModule(String module)
        +void setModuleId(String moduleId)
    }

    class LoggedInInfo {
        +String getLoggedInProviderNo()
    }

    class SecurityInfoManager {
        +boolean hasPrivilege(LoggedInInfo loggedInInfo, String objectName, String privilege, Object extra)
    }

    class DocumentAttachmentManager {
        +List~AttachmentLabResultData~ getAllLabsSortedByVersions(LoggedInInfo loggedInInfo, String demographicNo)
        +List~EFormData~ getAllEFormsExpectFdid(LoggedInInfo loggedInInfo, int demographicNo, int fdid)
    }

    class FormsManager {
        +List~EctFormData.PatientForm~ getEncounterFormsbyDemographicNumber(LoggedInInfo loggedInInfo, int demographicNo, boolean showOnlySaved, boolean includeDeleted)
    }

    DocumentPreview2Action --> EDocUtil : uses
    DocumentPreview2Action --> SecurityInfoManager : checks _edoc privilege
    DocumentPreview2Action --> DocumentAttachmentManager : loads labs and eForms
    DocumentPreview2Action --> FormsManager : loads encounter forms
    DocumentPreview2Action --> EDoc : classifies and merges
    DocumentPreview2Action --> LoggedInInfo : gets provider number

    EDocUtil --> CtlDocumentDao : calls
    EDocUtil --> CtlDocument : enriches attached EDocs
    EDocUtil --> EDoc : builds and enriches

    CtlDocumentDaoImpl ..|> CtlDocumentDao
    CtlDocumentDaoImpl --> CtlDocument : returns entities
    CtlDocument --> CtlDocumentPK : embedded id
Loading

File-Level Changes

Change Details Files
Extend attachment manager UI to show patient, provider public, and provider private eDoc sections with consistent selection, preview, and warning behaviour.
  • Rename the patient document section, update select-all and show-more button labels, and visually mute deleted and foreign provider documents.
  • Pre-check already attached docs using server-provided attachedDocumentIds, tagging them with data-pre-attached and using *_pre_check vs *_check CSS classes.
  • Add new Public eDocs and Private eDocs sections, including select-all, show-more, preview buttons, and conditional labels for deleted and other-provider attachments.
  • Introduce shared JS helpers (confirmPrivateDocsIfAny, buildDelegateInput, syncPreCheckedToDelegates) and a common attachable_check class for all attachable checkbox types.
src/main/webapp/documentManager/attachDocument.jsp
Keep attachment selections in sync between the dialog and parent consult/eForm forms across multiple openings, with cross-section deduping and proper handling of pre-attached vs newly attached docs.
  • Update consult request JSP to tag doc delegates with data-delegate-type="doc" and adjust dialog load logic to resolve DOCs by name+value, updating classes and expanding lists as needed.
  • On consult dialog beforeClose, warn on new private eDoc attachments, dedupe delegates across sections using a name+value key, build delegate inputs via the shared helper, and remove unchecked pre-attached entries while resetting classes and flags.
  • Update eForm floating toolbar JS to use name+value matching for DOC delegates, mark pre-attached checkboxes with data-pre-attached, call syncPreCheckedToDelegates, and on beforeClose dedupe via attachable_check and buildDelegateInput.
  • Ensure dynamically added form checkboxes are tagged as attachable_check so they participate in the unified selection/delegate handling.
src/main/webapp/oscarEncounter/oscarConsultationRequest/ConsultationFormRequest.jsp
src/main/webapp/eform/eformFloatingToolbar/eform_floating_toolbar.js
Populate attachment manager data for consults and eForms with provider public/private docs and attached-state context, enforcing _edoc privileges and robust parameter handling.
  • Inject SecurityInfoManager and enforce _edoc read privilege in fetchConsultDocuments and fetchEFormDocuments, throwing on missing privilege.
  • Normalize demographicNo, requestId, and fdid parameters using positiveIntParamOrDefault/positiveIntParamOrNull helpers to avoid invalid IDs.
  • Refactor to populate common docs via populateCommonDocs, then call populateAttachedContextForConsult/EForm to fetch attached docs for the current consult/eForm when IDs are present.
  • Implement mergeAttachedContext/mergeSingleAttachedDoc to compute attachedDocumentIds and foreignPrivateDocIds and merge deleted and cross-provider provider docs into the appropriate patient/public/private lists for rendering.
src/main/java/ca/openosp/openo/documentManager/actions/DocumentPreview2Action.java
Extend EDocUtil and CtlDocumentDao to support provider library queries, consistent metadata, and efficient ctl-based classification for attached documents.
  • Set observationDate via ConversionUtils.toDateString and docPublic from Document.public1 in listDocs and getEDocFromDocId for consistent display and classification.
  • When listing attached docs in listDocs, batch-load ctl_document rows via new enrichAttachedWithCtl using CtlDocumentDao.findByDocumentNos and prefer provider bindings over demographic for multi-bound docs.
  • Add getProviderPrivateDocs and getProviderPublicDocs helpers to fetch the current provider's private docs and all public provider docs, and wire them into populateCommonDocs to expose providerPrivateDocs and providerPublicDocs to the request.
  • Add CtlDocumentDao.findByDocumentNos and its JPA implementation to support the batch ctl lookup used during enrichment.
src/main/java/ca/openosp/openo/documentManager/EDocUtil.java
src/main/java/ca/openosp/openo/commn/dao/CtlDocumentDao.java
src/main/java/ca/openosp/openo/commn/dao/CtlDocumentDaoImpl.java
Update test configuration and add integration/unit tests covering attached-document DAO queries, ctl batch lookup, and merge classification logic.
  • Register document-related entities and DAOs in test persistence and Spring contexts so DocumentDao/CtlDocumentDao integration tests can run.
  • Introduce DocumentDaoBaseIntegrationTest with helpers to persist Document, CtlDocument, and attachment rows for consults, eForms, and responses.
  • Add DocumentDaoAttachedFindIntegrationTest to verify attached-document queries scope by consult/eForm/response, ignore soft-deleted and non-DOC attachments, and include docs regardless of ctl presence.
  • Add CtlDocumentDaoFindByDocumentNosIntegrationTest to validate behaviour for null/empty input, multi-doc lookups, multi-binding docs, and scoping.
  • Add DocumentPreview2ActionMergeUnitTest to exercise mergeSingleAttachedDoc across patient/provider/public/private/foreign/deleted combinations and edge cases like null current provider and legacy module names.
src/test-modern/resources/META-INF/persistence.xml
src/test-modern/resources/test-context-full.xml
src/test-modern/java/ca/openosp/openo/documentManager/dao/DocumentDaoBaseIntegrationTest.java
src/test-modern/java/ca/openosp/openo/documentManager/dao/DocumentDaoAttachedFindIntegrationTest.java
src/test-modern/java/ca/openosp/openo/documentManager/dao/CtlDocumentDaoFindByDocumentNosIntegrationTest.java
src/test-modern/java/ca/openosp/openo/documentManager/actions/DocumentPreview2ActionMergeUnitTest.java
src/main/java/ca/openosp/openo/eform/data/EForm.java

Assessment against linked issues

Issue Objective Addressed Explanation
https://github.com/openo-beta/Open-O/issues/2282 Allow provider private documents to be attached via the attachment manager in a dedicated "Private eDocs" section, including visibility of attached cross‑provider and soft‑deleted private docs.
https://github.com/openo-beta/Open-O/issues/2282 Allow provider public documents to be attached via the attachment manager in a dedicated "Public eDocs" section, including visibility of attached soft‑deleted public docs.
https://github.com/openo-beta/Open-O/issues/2282 Display a confirmation warning when newly attaching private provider documents to consultations or eForms, informing that they will become visible in the patient record.

Possibly linked issues

  • #N/A: They match: PR adds private/public provider eDocs sections, warnings, and soft-deleted attachment handling requested by the issue.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Feb 17, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Two action classes are updated to retrieve provider-scoped private documents and expose them as request attributes. A JSP view is modified to display these provider-private documents in a new UI section alongside existing document listings.

Changes

Cohort / File(s) Summary
Backend Document Retrieval
src/main/java/ca/openosp/openo/documentManager/actions/DocumentPreview2Action.java, src/main/java/ca/openosp/openo/encounter/oscarConsultationRequest/pageUtil/ConsultationAttachDocs2Action.java
Added retrieval of provider-scoped private documents using EDocUtil.listDocs with type "providers", logged-in provider number, PRIVATE access level, and OBSERVATIONDATE sort. Documents exposed to view via request attribute.
Frontend Document Display
src/main/webapp/documentManager/attachDocument.jsp
New UI section rendering "Private Documents" with header, checkbox-enabled item list (first 20 shown), per-item Preview buttons, select-all functionality, and "Show More" toggle. Follows existing document section patterns.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Suggested reviewers

  • D3V41

Poem

🐰 A provider's secrets now shine bright,
Private docs bundled left and right,
New UI sections, mirrors so fine,
Fetch, display, and align,
The document dance—all working right! 📋

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ⚠️ Warning The title mentions 'public and private documents' but the changes only add provider private documents, not public documents. Update the title to 'Feature: show providers' private documents in the attachment manager' to accurately reflect that only private documents are being added.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/show-providers-private-documents-attachment-manager

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist

Copy link
Copy Markdown

Summary of Changes

Hello @LiamStanziani, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the attachment manager functionality by introducing a dedicated section for private documents owned by the logged-in provider. This allows providers to easily view and manage their personal documents directly within the attachment interface, improving accessibility and workflow efficiency.

Highlights

  • Attachment Manager Enhancement: Added a new section within the attachment manager page to display private documents belonging to the currently logged-in provider.
  • Provider Document Retrieval: Implemented logic to fetch and make available the private documents associated with the logged-in provider for display.
  • User Interface Update: Integrated UI components for listing, selecting, and previewing these private provider documents, including 'Select all' and 'Show More' features.
Changelog
  • src/main/java/ca/openosp/openo/documentManager/actions/DocumentPreview2Action.java
    • Retrieved the logged-in provider's number.
    • Fetched a list of private documents associated with the logged-in provider.
    • Made the fetched provider private documents available to the request attributes.
  • src/main/java/ca/openosp/openo/encounter/oscarConsultationRequest/pageUtil/ConsultationAttachDocs2Action.java
    • Retrieved the logged-in provider's number.
    • Fetched a list of private documents associated with the logged-in provider.
    • Made the fetched provider private documents available to the request attributes.
  • src/main/webapp/documentManager/attachDocument.jsp
    • Added a new conditional section to display 'Private Documents' if providerPrivateDocs are not empty.
    • Implemented a list (
        ) to iterate and display each private document.
      • Included 'Select all' checkbox functionality for private documents.
      • Added a 'Show More' button for lists exceeding 20 private documents.
      • Provided a 'Preview' button for each private document.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@LiamStanziani

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@LiamStanziani

Copy link
Copy Markdown
Collaborator Author

@SourceryAI review

@coderabbitai

coderabbitai Bot commented Feb 17, 2026

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • The logic to fetch provider private documents in both DocumentPreview2Action.populateCommonDocs and ConsultationAttachDocs2Action.fetchAll is duplicated; consider extracting a shared helper to reduce repetition and keep behavior consistent.
  • The 'Show X More Private Documents' button always computes ${providerPrivateDocs.size() - 20} even when size ≤ 20 and only hides via CSS; you may want to render the button and its title text conditionally so the DOM doesn’t contain negative or misleading counts.
  • The select-all checkbox calls toggleSelectAll(this, 'providerDocument_'); but the individual provider checkboxes use IDs starting with providerDocNo and class providerDocument_check; verify and align the selector/prefix so the select-all behavior works for this new section.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The logic to fetch provider private documents in both DocumentPreview2Action.populateCommonDocs and ConsultationAttachDocs2Action.fetchAll is duplicated; consider extracting a shared helper to reduce repetition and keep behavior consistent.
- The 'Show X More Private Documents' button always computes `${providerPrivateDocs.size() - 20}` even when size ≤ 20 and only hides via CSS; you may want to render the button and its title text conditionally so the DOM doesn’t contain negative or misleading counts.
- The select-all checkbox calls `toggleSelectAll(this, 'providerDocument_');` but the individual provider checkboxes use IDs starting with `providerDocNo` and class `providerDocument_check`; verify and align the selector/prefix so the select-all behavior works for this new section.

## Individual Comments

### Comment 1
<location> `src/main/webapp/documentManager/attachDocument.jsp:381-382` </location>
<code_context>
+                                           onclick="toggleSelectAll(this, 'providerDocument_');" value="providerDocument_check"
+                                           title="Select/un-select all private documents."/>
+                                    <label for="selectAllProviderDocuments">Select all</label>
+                                    <button class="show-all-button ${providerPrivateDocs.size() > 20 ? '' : 'hide'}"
+                                            type="button" title="Show ${providerPrivateDocs.size() - 20} More Private Documents"
+                                            onclick="showAll(this, 'providerDoc')">Show ${providerPrivateDocs.size() - 20} More
+                                        Private Documents
</code_context>

<issue_to_address>
**issue (bug_risk):** When there are fewer than 20 private documents, the hidden button will still contain a negative count in its text/title.

The button is visually hidden when `providerPrivateDocs.size() <= 20`, but the title and label still compute `size() - 20`, so with 5 docs the DOM contains “Show -15 More Private Documents”. This is misleading for assistive tech and could become visible if styles change. Consider only rendering the button when `size() > 20`, or clamping/omitting the count when `size() <= 20`.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread src/main/webapp/documentManager/attachDocument.jsp Outdated

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds the functionality to display a provider's private documents in the attachment manager. The changes in the Java action classes correctly fetch the private documents and pass them to the JSP. The JSP is updated to render these documents in a new section. My review has identified a couple of areas with significant code duplication, both in the Java action classes and in the JSP file. I've left comments with suggestions on how to refactor this duplicated code to improve maintainability and consistency. Addressing these points would make the code cleaner and easier to manage in the future.

Comment thread src/main/webapp/documentManager/attachDocument.jsp Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/java/ca/openosp/openo/encounter/oscarConsultationRequest/pageUtil/ConsultationAttachDocs2Action.java (1)

80-171: ⚠️ Potential issue | 🔴 Critical

Missing SecurityInfoManager.hasPrivilege() check in action methods.

The coding guidelines require all Struts2 actions to include SecurityInfoManager.hasPrivilege() checks before performing operations, with the security check as the first operation before any business logic. The fetchAll() method lacks this check. This method accesses sensitive patient health information (labs, documents, forms, eforms, HRM data) without privilege verification, creating a security gap.

Add a privilege check at the top of fetchAll():

Proposed fix
 public String fetchAll() {
+    if (!securityInfoManager.hasPrivilege(LoggedInInfo.getLoggedInInfoFromSession(request), "_con", "r", null)) {
+        throw new SecurityException("missing required sec object (_con)");
+    }
 
     LoggedInInfo loggedInInfo = LoggedInInfo.getLoggedInInfoFromSession(request);

Also inject SecurityInfoManager as a field:

 FaxManager faxManager = SpringUtils.getBean(FaxManager.class);
+SecurityInfoManager securityInfoManager = SpringUtils.getBean(SecurityInfoManager.class);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/main/java/ca/openosp/openo/encounter/oscarConsultationRequest/pageUtil/ConsultationAttachDocs2Action.java`
around lines 80 - 171, The fetchAll() action is missing the required privilege
check; inject a SecurityInfoManager field (e.g., private SecurityInfoManager
securityInfoManager; via SpringUtils.getBean or as a class member) and at the
very start of fetchAll() call securityInfoManager.hasPrivilege(loggedInInfo,
<appropriate-privilege-constant>) (use the same LoggedInInfo obtained by
LoggedInInfo.getLoggedInInfoFromSession(request)); if the check fails return the
appropriate security result (e.g., "security" or redirect/HTTP 403) immediately
before any business logic (before populating labs/docs/forms/HRM) to prevent
access to patient data. Ensure the call and early return are placed in
ConsultationAttachDocs2Action.fetchAll().
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/main/webapp/documentManager/attachDocument.jsp`:
- Line 391: The title attribute is inserting document.description directly into
HTML (title="${ document.description }") creating an XSS risk; change the
attribute to use an encoder such as OWASP Encoder's
Encode.forHtmlAttribute(document.getDescription()) or JSTL
fn:escapeXml(document.description) so the value is HTML-attribute-encoded;
update both occurrences that set title from document.description (the new code
at line ~391 and the pre-existing one around line ~355) to call the encoder
instead of embedding the raw property, keeping the existing <c:out> usage for
label content unchanged.
- Line 389: The private-document checkbox input currently includes the class
"document_check" so toggleSelectAll(this, 'document_') also toggles private
docs; update the input element in attachDocument.jsp (the checkbox with
class="providerDocument_check document_check") to remove the "document_check"
prefix (e.g., use "private_document_check" or just "providerDocument_check") so
it no longer matches the 'document_' selector used by toggleSelectAll; if you
introduce a new class like "private_document_check", ensure any JS that should
target private docs is updated accordingly.

---

Outside diff comments:
In
`@src/main/java/ca/openosp/openo/encounter/oscarConsultationRequest/pageUtil/ConsultationAttachDocs2Action.java`:
- Around line 80-171: The fetchAll() action is missing the required privilege
check; inject a SecurityInfoManager field (e.g., private SecurityInfoManager
securityInfoManager; via SpringUtils.getBean or as a class member) and at the
very start of fetchAll() call securityInfoManager.hasPrivilege(loggedInInfo,
<appropriate-privilege-constant>) (use the same LoggedInInfo obtained by
LoggedInInfo.getLoggedInInfoFromSession(request)); if the check fails return the
appropriate security result (e.g., "security" or redirect/HTTP 403) immediately
before any business logic (before populating labs/docs/forms/HRM) to prevent
access to patient data. Ensure the call and early return are placed in
ConsultationAttachDocs2Action.fetchAll().

Comment thread src/main/webapp/documentManager/attachDocument.jsp Outdated
Comment thread src/main/webapp/documentManager/attachDocument.jsp Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

… Patient Documents and Provider Documents, might be reverted depending on discussion about this change
@LiamStanziani LiamStanziani linked an issue Feb 17, 2026 that may be closed by this pull request
7 tasks
…Docs(), add OWASP encoding for doc title attributes, fix provider doc attachment save/restore in consultation requests and eForms when switching away from doc class to seperate class
…seperate UI sections, and added a JS warning when attaching a private provider document
…ctions, fix entry ID mismatch for provider doc detach in consultations, add deleted doc styling, and update confirm dialog wording
…n merge method, wrap allDocuments list consistently
@LiamStanziani LiamStanziani changed the title Feat: show providers' private documents in the attachment manager Feat: show providers' documents in the attachment manager Feb 20, 2026
…nvariant, removing fallback resolution as its not needed anymore
@LiamStanziani LiamStanziani changed the title Feat: show providers' documents in the attachment manager Feature: show providers' documents in the attachment manager Feb 24, 2026
@sebastian-j-ibanez sebastian-j-ibanez changed the base branch from hotfix/01232026 to maintenance March 20, 2026 16:03
@sebastian-j-ibanez sebastian-j-ibanez changed the base branch from maintenance to hotfix/01232026 March 20, 2026 17:16
@sebastian-j-ibanez

Copy link
Copy Markdown
Collaborator

@LiamStanziani just want to confirm: this PR is still being worked on, correct?

@LiamStanziani

LiamStanziani commented Mar 20, 2026

Copy link
Copy Markdown
Collaborator Author

@sebastian-j-ibanez This PR is waiting for testing by Keith, not currently working it at the moment but I might need to update it later on if something comes up.

Since this is in draft I will probably need to update it somewhat when setting it ready to review for AI comments, but I plan to do that after Keith has approved the feature behaviour.

@sebastian-j-ibanez

Copy link
Copy Markdown
Collaborator

Okay, sounds good!

Just wanted to make sure this should be kept open.

@LiamStanziani LiamStanziani changed the base branch from hotfix/01232026 to develop April 20, 2026 21:00
Comment thread src/main/java/ca/openosp/openo/documentManager/EDocUtil.java Dismissed
Comment thread src/main/java/ca/openosp/openo/documentManager/EDocUtil.java Dismissed

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="src/main/webapp/documentManager/attachDocument.jsp" line_range="393" />
<code_context>
-                                    <li class="doc ${loop.index > 19 ? 'hide' : ''}">
-                                        <input class="document_check" type="checkbox" name="docNo"
+                                    <c:set var="isDeleted" value="${fn:contains(document.status, 'D')}"/>
+                                    <c:set var="isAttached" value="${not empty attachedDocumentIds and attachedDocumentIds.contains(document.docId)}"/>
+                                    <li class="doc ${loop.index > 19 ? 'hide' : ''} ${isDeleted ? 'deleted-doc' : ''}">
+                                        <input class="document_${isAttached ? 'pre_check' : 'check'} attachable_check" type="checkbox" name="docNo"
</code_context>
<issue_to_address>
**issue (bug_risk):** Calling `attachedDocumentIds.contains(...)` in EL is likely invalid and will fail at runtime.

Standard JSP EL doesn’t support calling instance methods like `attachedDocumentIds.contains(...)`, so this is likely to fail with a property/method resolution error at render time. If `attachedDocumentIds` is a `Collection`, use the `in` operator instead (e.g. `${document.docId in attachedDocumentIds}`) or a JSTL function, and update the similar `foreignPrivateDocIds.contains(...)` usage as well.
</issue_to_address>

### Comment 2
<location path="src/test-modern/java/ca/openosp/openo/documentManager/dao/DocumentDaoAttachedFindIntegrationTest.java" line_range="38-47" />
<code_context>
+    @Autowired
+    private CtlDocumentDao ctlDocumentDao;
+
+    @Test
+    @DisplayName("returns an empty list when the input is null")
+    void shouldReturnEmpty_whenInputIsNull() {
</code_context>
<issue_to_address>
**suggestion (testing):** Add a negative test to confirm non-DOC attachment types are excluded

Since the query is intended to return only `docType = DOCTYPE_DOC` rows, consider persisting an attachment for the same consult/fdid/response with a different `docType` (e.g., letter) and asserting it is excluded from the results. This will help catch regressions if the query or `docType` constants change.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread src/main/webapp/documentManager/attachDocument.jsp

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.

Comment thread src/main/webapp/eform/eformFloatingToolbar/eform_floating_toolbar.js Outdated
Comment thread src/main/webapp/documentManager/attachDocument.jsp Dismissed
…ment doc consolidation, updated another provider text to be more specific on state of attachment
@LiamStanziani LiamStanziani marked this pull request as ready for review April 22, 2026 17:59
@LiamStanziani

Copy link
Copy Markdown
Collaborator Author

Testing this has gone very well, should be fully ready for review soon

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • In attachDocument.jsp and the related JS, there is still a lot of explicit class-based checkbox selection (e.g. .document*_check, .providerPrivateDocument*_check, etc.); now that you've introduced the shared attachable_check marker, consider refactoring the selectors and beforeClose handlers to rely on this one class to reduce duplication and avoid divergence when new attachment types/sections are added.
  • In mergeAttachedContext, when any of allDocuments, providerPrivateDocs, or providerPublicDocs is missing you skip the merge entirely; if this method is ever reused in a context that doesn't load provider lists, it might be safer to still populate attachedDocumentIds/foreignPrivateDocIds (and perhaps only guard the per-section injections) so that attached-state handling continues to work.
  • The OWASP encoder taglib is referenced via uri="https://www.owasp.org/index.php/OWASP_Java_Encoder_Project"; double-check that this matches the actual encoder configuration in the project (and OWASP’s recommended URI) to avoid runtime taglib resolution issues.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `attachDocument.jsp` and the related JS, there is still a lot of explicit class-based checkbox selection (e.g. `.document*_check`, `.providerPrivateDocument*_check`, etc.); now that you've introduced the shared `attachable_check` marker, consider refactoring the selectors and beforeClose handlers to rely on this one class to reduce duplication and avoid divergence when new attachment types/sections are added.
- In `mergeAttachedContext`, when any of `allDocuments`, `providerPrivateDocs`, or `providerPublicDocs` is missing you skip the merge entirely; if this method is ever reused in a context that doesn't load provider lists, it might be safer to still populate `attachedDocumentIds`/`foreignPrivateDocIds` (and perhaps only guard the per-section injections) so that attached-state handling continues to work.
- The OWASP encoder taglib is referenced via `uri="https://www.owasp.org/index.php/OWASP_Java_Encoder_Project"`; double-check that this matches the actual encoder configuration in the project (and OWASP’s recommended URI) to avoid runtime taglib resolution issues.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 14 files

Confidence score: 3/5

  • There is moderate merge risk because both reported issues are medium severity (6/10) with high confidence, and each can affect user-visible behavior.
  • In src/main/webapp/documentManager/attachDocument.jsp, inconsistent use of e:forHtmlAttribute for title attributes (document vs eForm/HRM/Form titles) could leave uneven output encoding and potential attribute-safety gaps.
  • In src/main/java/ca/openosp/openo/documentManager/EDocUtil.java, equal-priority multi-bound document selection is non-deterministic, so canonical CtlDocument choice may vary by query row order and cause inconsistent outcomes.
  • Pay close attention to src/main/webapp/documentManager/attachDocument.jsp and src/main/java/ca/openosp/openo/documentManager/EDocUtil.java - align attribute encoding and make canonical Ctl selection deterministic.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/main/webapp/documentManager/attachDocument.jsp">

<violation number="1" location="src/main/webapp/documentManager/attachDocument.jsp:383">
P2: Inconsistent HTML attribute encoding: the OWASP encoder (`e:forHtmlAttribute`) was applied to document title attributes but not to eForm, HRM, or Form titles on these same modified lines. Encode these consistently to prevent attribute injection.</violation>
</file>

<file name="src/main/java/ca/openosp/openo/documentManager/EDocUtil.java">

<violation number="1" location="src/main/java/ca/openosp/openo/documentManager/EDocUtil.java:538">
P2: Ctl selection for multi-bound documents is non-deterministic because equal-priority bindings fall back to query row order.

(Based on your team's feedback about deterministic canonical CtlDocument selection across attachment paths.) [FEEDBACK_USED]</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread src/main/webapp/documentManager/attachDocument.jsp
Comment thread src/main/java/ca/openosp/openo/documentManager/EDocUtil.java
… avoid potential issue if any document type is null and method returns early, add extra OWASP encoding to titles in attach document JSP
Comment thread src/main/webapp/documentManager/attachDocument.jsp Dismissed
@LiamStanziani LiamStanziani requested a review from D3V41 April 22, 2026 19:19
…ppropriate helper classes based on functionality
…eCommonDocs to avoid redundant attribute calls
Comment thread src/main/java/ca/openosp/openo/documentManager/actions/DocumentPreview2Action.java Dismissed
Comment thread src/main/java/ca/openosp/openo/documentManager/actions/DocumentPreview2Action.java Dismissed
…th provider public and private documents for Ocean, update and add new tests to account for recent changes

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 6 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/main/java/ca/openosp/openo/commn/dao/DocumentDaoImpl.java">

<violation number="1" location="src/main/java/ca/openosp/openo/commn/dao/DocumentDaoImpl.java:249">
P1: Validation now treats all provider-module docs as valid attachments, which can allow unauthorized private provider documents to pass patient-attachment checks.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread src/main/java/ca/openosp/openo/commn/dao/DocumentDaoImpl.java
@lacarmen

Copy link
Copy Markdown
Collaborator

QA testing for this looks good. The issues that I previously flagged have been resolved, and Deval reviewed the Ocean-related fix.

Waiting for @LiamStanziani to open the MHI PR for this, and we'll get this one merged in after it's tested at MHI.

…achment-manager

Signed-off-by: Liam Stanziani <102267755+LiamStanziani@users.noreply.github.com>
@LiamStanziani

Copy link
Copy Markdown
Collaborator Author

@lacarmen sounds good, PR has been opened for this feature towards release here: MagentaHealth#129

LiamStanziani and others added 2 commits June 9, 2026 12:19
…on headers via hasClass instead of a reversed indexOf that broke once checkboxes became multi-class
@LiamStanziani

Copy link
Copy Markdown
Collaborator Author

@D3V41 I have added a fix for: https://github.com/openo-beta/Open-O/issues/2470

In this branch, it has also been sent towards MagentaHealth release but it is fixed here for consistency:

Here is the commit if you would like to review: 2e566db


Below is information about the issue, from the corresponding MagentaHealth PR

Summary

When attaching items to a consultation request via Manage Attachments, labs, forms, eForms, and HRM documents were all displayed under the generic Documents header before the consultation was saved, instead of under their own section headings. They only appeared correctly categorized after saving and reopening. This fixes the pre-save categorization so each item lands under its correct header immediately.

Problem

The JavaScript that decides which section table each attached item goes into used a reversed indexOf check:

if ("lab_check".indexOf(element.attr("class")) !== -1) { target = "#attachedLabsTable"; }

This asks whether the element's entire class string is a substring of the literal "lab_check" — backwards. It only matched when the class attribute was exactly the single string "lab_check".

That latent bug was exposed by PR #2295 (provider public/private documents in the attachment manager), which added a second CSS class (attachable_check) to every attachment checkbox. With the class now "lab_check attachable_check", "lab_check".indexOf("lab_check attachable_check") returns -1, so the lab/form/eForm/HRM checks all failed and every item fell through to the default #attachedDocumentsTable. After save, the server re-renders from persisted data with correct per-type sections, which is why it self-corrected on reopen.

This affected the release branch (which has PR #2295) but not develop, where the checkboxes still carry a single class and the reversed check coincidentally matched.

Solution

Replaced the four reversed indexOf checks with element.hasClass(...), which correctly tests for the type token regardless of how many classes the element has or their order:

if (element.hasClass("lab_check"))   { target = "#attachedLabsTable"; }
if (element.hasClass("form_check"))  { target = "#attachedFormsTable"; }
if (element.hasClass("eForm_check")) { target = "#attachedEFormsTable"; }
if (element.hasClass("hrm_check"))   { target = "#attachedHRMDocumentsTable"; }
image

Documents and provider public/private docs continue to fall through to the default Documents table (unchanged behaviour — they are all documents).

Scope: one file, oscarEncounter/oscarConsultationRequest/ConsultationFormRequest.jsp. Pre-save display only — no change to what is persisted or submitted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Show providers' private documents in the attachment manager

5 participants