Skip to main content

Quality Review and Auditing

Module: suredms-desktop-client-quality
Source root: SC/suredms-desktop-client-quality/src/main/java/com/sureclinical/suredms/

This module implements the Quality module of the desktop application. It provides the QualityView dashboard, a four-step audit creation wizard, discrepancy management gadgets, quality metric charts, and integration with the signing report pipeline.

Purpose

suredms-desktop-client-quality gives quality reviewers a structured workflow for auditing clinical documents. Users navigate to the Quality section via the ribbon, create audits with a sampling wizard, review documents, log discrepancies, and track resolution. All UI is mounted into the shell's docking frame as gadgets within QualityView.

Package Structure

PackageContents
com.sureclinical.suredms.ui.viewsQualityView — the main Quality module view
com.sureclinical.suredms.ui.gadgetsAll Quality gadgets: audit viewer, discrepancy items, mode selector, quality tree, report viewer, report actions
com.sureclinical.suredms.ui.qualityGadgetChart, QualityCharts, QualityChartType — chart rendering harness
com.sureclinical.suredms.ui.quality.wizard.auditWizard infrastructure: AuditWizardBuilder, AuditWizardContext, 4 step classes, AuditData, AuditModelFactory
com.sureclinical.suredms.nuxeoDocDiscrepancyManager, AuditController — server-side persistence

QualityView

SC/suredms-desktop-client-quality/src/main/java/com/sureclinical/suredms/ui/views/QualityView.java

Singleton view (lazy via getInstance()). Extends BaseView from the shell module. Mounted into the shell's main frame when the user navigates to Quality.

Gadgets hosted by QualityView:

GadgetGadget ID / NamePurpose
GadgetQualityModeSelectormodeSelectorMode toggle — discrepancy list, audit wizard, or chart
WorkAreaworkAreaInternal panel that swaps its content based on active mode
GadgetStackviewerAreaStack holding the PDF viewer and report viewer
GadgetIcePDFViewerembedded in stackIn-process PDF renderer for the selected document
GadgetReportViewerembedded in stackReport HTML/PDF viewer
GadgetDiscrepancyViewerPer-document discrepancy editor embedded in WorkArea
GadgetDocumentNavigatorDocument navigator filtered to the active audit list
GadgetAuditViewerTabular list of all audits for the active archives
GadgetDiscrepancyItemsFilterable discrepancy table across all documents
GadgetQualityTreeTree navigator over the quality context
GadgetMetadataRead-only metadata panel for the selected document
GadgetChartQuality metric chart panel

QualityView maps QualityViewMode to QualityChartType for chart-mode selections:

MODE_TO_CHART_MAP = {
CHART_QC_STUDY_DOC_TOTALS_OVER_TIME → QC_STUDY_DOC_TOTALS_OVER_TIME,
CHART_QC_TOTAL_DISCREPANCIES_VS_DOCUMENTS → QC_TOTAL_DISCREPANCIES_VS_DOCUMENTS,
CHART_QC_TOTAL_DOCS_BY_ROLE → QC_TOTAL_DOCS_BY_ROLE,
CHART_QC_TOTAL_DOCS_BY_STUDY → QC_TOTAL_DOCS_BY_STUDY,
CHART_QC_DOCUMENTS_BY_MILESTONE → QC_DOCUMENTS_BY_MILESTONE
}

QualityViewMode Enum

SC/suredms-desktop-client-quality/src/main/java/com/sureclinical/suredms/ui/gadgets/QualityViewMode.java

Controls which content appears in QualityView's work area:

ValueWhat it shows
VIEW_DISCREPANCY_ITEMDiscrepancy item list + viewer
ARCHIVE_AUDIT_WIZARDAudit wizard launcher panel
ARCHIVE_AUDIT_SAMPLE_LISTGenerated audit document sample list
CHART_QC_TOTAL_DISCREPANCIES_VS_DOCUMENTSChart: discrepancies vs. document count
CHART_QC_STUDY_DOC_TOTALS_OVER_TIMEChart: documents over time
CHART_QC_TOTAL_DOCS_BY_ROLEChart: documents grouped by role
CHART_QC_TOTAL_DOCS_BY_STUDYChart: documents grouped by study
CHART_QC_DOCUMENTS_BY_MILESTONEChart: documents by milestone

Audit Wizard

AuditWizardBuilder

SC/suredms-desktop-client-quality/src/main/java/com/sureclinical/suredms/ui/quality/wizard/audit/AuditWizardBuilder.java

Extends WizardBuilder from the shell. Dialog size: 1000 × 650 pixels, resizable.

AuditWizardBuilder.showWizard(listener);  // static entry point

Constructs:

  • AuditWizardContext — shared mutable state passed to all steps.
  • AuditWizardStep1SelectStudy — study/archive selection.
  • AuditWizardStep2SelectContent — content type selection within the chosen archive.
  • AuditWizardStep3SelectSampleSize — numeric sample percentage entry.
  • AuditWizardStep4CreateAuditList — generates and displays the sampled document list.

performWizardAction() (called when the user clicks Finish):

  1. Retrieves AuditData from AuditWizardContext.getAudit().
  2. Calls DocDiscrepancyManager.getInstance().getDiscrepancies(audit.getAuditDocuments()) to load existing discrepancies for the sampled documents.
  3. Sets the discrepancy multimap on the AuditData.
  4. Sets wizardResult = audit, which is passed to DialogResultListener callbacks.

AuditWizardContext

SC/suredms-desktop-client-quality/src/main/java/com/sureclinical/suredms/ui/quality/wizard/audit/AuditWizardContext.java

Shared context object passed through all four wizard steps. Key fields and behavior:

FieldTypeDefault
archiveArchiveSelected in Step 1
documentsList<Document>All documents in the archive content types
filteredDocumentsList<Document>Sampled subset (cached until sampleSize changes)
sampleSizedouble10.0 (10%)
auditNameStringUser-entered name

getFilteredDocuments() sampling algorithm:

sampleDocCount = ceil(totalDocCount × sampleSize / 100)
sampleDocCount = clamp(sampleDocCount, 0, totalDocCount)
randomly select sampleDocCount documents from the full list

Uses ThreadLocalRandom for random selection. Result is cached until setSampleSize() is called.

Audit Wizard Steps

Step ClassDialog Header KeyResponsibility
AuditWizardStep1SelectStudywizard.audit.step1Presents archive/study picker; sets context.archive
AuditWizardStep2SelectContentwizard.audit.step2Presents content type multi-select; populates context.documents
AuditWizardStep3SelectSampleSizewizard.audit.step3Numeric percentage spinner; sets context.sampleSize
AuditWizardStep4CreateAuditListwizard.audit.step4Displays sampled documents; user confirms and assigns audit name

AuditData

SC/suredms-desktop-client-quality/src/main/java/com/sureclinical/suredms/ui/quality/wizard/audit/AuditData.java

The result object produced by the wizard. Holds:

  • The archive under audit.
  • The full list of audit documents (the sampled subset).
  • A Multimap<Document, DocDiscrepancy> of pre-existing discrepancies.
  • The audit name and creation metadata.

Consumed by GadgetAuditViewer for display and passed to AuditController.saveAudit() for persistence.

Gadgets

GadgetAuditViewer

SC/suredms-desktop-client-quality/src/main/java/com/sureclinical/suredms/ui/gadgets/GadgetAuditViewer.java

Extends DiscrepancyGadget. Implements EntityDataUpdatedListener and DiscrepancyManagerEventListener.

  • Maintains an ordered Set<AuditData> of all active audits.
  • Renders audits in a JXTable using an AbstractTableModel.
  • Subscribes to DocDiscrepancyManager events so the table updates when discrepancies change.
  • Actions: create new audit (opens AuditWizardBuilder), save audit (AuditController.saveAudit()), delete audit (AuditController.deleteAudit()), generate report.
  • AuditController.getAudits() queries by active archive IDs using NuxeoClientPool.

GadgetDiscrepancyItems

SC/suredms-desktop-client-quality/src/main/java/com/sureclinical/suredms/ui/gadgets/GadgetDiscrepancyItems.java

Extends DiscrepancyGadget. Implements EntityDataUpdatedListener, DiscrepancyManagerEventListener, QuickFindListener.

  • Renders all DocDiscrepancy records in a JXTable.
  • Two filter combo boxes: ctrlDiscrepancySource (JTypedComboBox<Archive>) and ctrlDiscrepancyView (JTypedComboBox<DiscrepancyStatus>).
  • Quick-find search panel for text filtering.
  • GadgetReportActions control for generating discrepancy reports.
  • Subscribes to DocDiscrepancyManager via addEventListener.
  • fillData() re-applies filters and rebuilds the table model whenever archive or status selection changes.

DocDiscrepancyManager — Discrepancy Cache

SC/suredms-desktop-client-quality/src/main/java/com/sureclinical/suredms/nuxeo/DocDiscrepancyManager.java

DocDiscrepancyManager is a singleton that maintains an in-memory cache of DocDiscrepancy records across the application session. It is the authoritative client-side store for all discrepancy data.

Lifecycle

DocDiscrepancyManager.getInstance()  // lazy singleton
DocDiscrepancyManager.shutdown() // clears all state (called on logout)

Internal state

FieldTypeDescription
docDiscrepanciesMap<Document, Set<DocDiscrepancy>>All discrepancies keyed by document
managerEventListenersList<DiscrepancyManagerEventListener>UI observers notified on state change

Implements EndPointListener — when IDocument.onDataUpdated() fires, the manager reloads discrepancy data from the server (remote endpoint) or from the local document set (offline mode).

CRUD operations

MethodBehaviour
addDocDiscrepancy(discrepancy)Persists via Nuxeo NuxeoClientPool query (remote) or direct local insert; fires change event
updateDocDiscrepancy(discrepancy)Updates server entity and local cache; fires change event
getDiscrepancies()Returns full List<DocDiscrepancy> from the local cache
getDiscrepancies(archive, resolved)Returns discrepancies filtered by archive and optional resolved flag

DiscrepancyManagerEventListener

UI components (e.g., GadgetDiscrepancyItems) implement this interface and register via addEventListener(listener). The listener is notified with an DiscrepancyManagerEvent after any CRUD operation completes.

GadgetDiscrepancyViewer

SC/suredms-desktop-client-quality/src/main/java/com/sureclinical/suredms/ui/gadgets/GadgetDiscrepancyViewer.java

Detail panel for a single DocDiscrepancy. Allows the reviewer to:

  • View discrepancy type, content, assignment.
  • Set resolution status and enter resolution notes.
  • Assign the discrepancy to another reviewer.
  • Set email reminder type.

GadgetQualityTree

SC/suredms-desktop-client-quality/src/main/java/com/sureclinical/suredms/ui/gadgets/GadgetQualityTree.java

Tree navigator over quality data. Renders archives and their quality summary below each archive node. Fires QualityModeSelectorEvent when the user selects a node to trigger a mode or chart change.

GadgetQualityModeSelector

Controls which panel the WorkArea shows. Dispatches QualityModeSelectorEvent to listeners (including QualityView) when the user switches modes via toolbar buttons.

AuditController

SC/suredms-desktop-client-quality/src/main/java/com/sureclinical/suredms/ui/gadgets/AuditController.java

Server-side persistence for audits:

MethodTransportDescription
saveAudit(AuditData)NuxeoClientPool.executeSilentQueryCreates or updates the audit record
deleteAudit(AuditData)NuxeoClientPool.getClient().deleteEntity()Deletes the audit entity
getAudits()NuxeoClientPool.getClient().getAudits(archiveIds)Loads all audits for active archives

Quality Charts

SC/suredms-desktop-client-quality/src/main/java/com/sureclinical/suredms/ui/quality/GadgetChart.java

Wraps QualityCharts (the data queries) and renders output using GadgetChartDocumentsAndDiscrepanciesOverTime.

Available chart types (QualityChartType enum):

TypeDescription
QC_TOTAL_DISCREPANCIES_VS_DOCUMENTSStacked bar or scatter: discrepancy count vs. document count
QC_STUDY_DOC_TOTALS_OVER_TIMELine: document and discrepancy totals over calendar time
QC_TOTAL_DOCS_BY_ROLEBar: document count per organizational role
QC_TOTAL_DOCS_BY_STUDYBar: document count per archive/study
QC_DOCUMENTS_BY_MILESTONEBar: document count per milestone

Signing Report Integration

The quality module also contributes two signing report classes:

  • ReportSignatureValidation — generates a signature validation report for a document or audit.
  • ReportSigningHistoryAuditTrail — generates a signing-history audit trail report.

Both integrate with ReportService from the shell module.

Full Workflow

Ribbon: Quality tab → QualityView (singleton)

└── GadgetQualityModeSelector

├── Mode: ARCHIVE_AUDIT_WIZARD
│ └── AuditWizardBuilder.showWizard(listener)
│ ├── Step 1: select archive
│ ├── Step 2: select content types
│ ├── Step 3: set sample size (default 10%)
│ └── Step 4: generate sampled document list
│ ↓ on Finish
│ AuditData → GadgetAuditViewer
│ → AuditController.saveAudit()

├── Mode: VIEW_DISCREPANCY_ITEM
│ └── GadgetDiscrepancyItems (all archives, filterable)
│ ↓ select discrepancy
│ └── GadgetDiscrepancyViewer (per-discrepancy detail)

└── Mode: CHART_*
└── GadgetChart → QualityCharts → JFreeChart

Compliance and Required Documents (GAP-19)

The compliance subsystem tracks required documents per archive milestone and surfaces overdue items in the HomeView dashboard and the ComplianceClientService API.

ComplianceClientService

Source: suredms-desktop-client-connectorcom.sureclinical.suredms.services.compliance

MethodDescription
getComplianceSnapshot()Returns the full compliance snapshot for all active archives — which required documents are present, overdue, or missing
getMilestonesByArchive(String archiveId)Returns List<Milestone> for a given archive
updateRequiredDocument(RequiredDocument requiredDocument)Persists changes to a required document record

Dashboard Gadgets

GadgetClassLocationPurpose
Required documentsGadgetRequiredDocumentsHomeViewSummary of missing required documents across all archives
Expired documentsGadgetExpiredDocumentsHomeViewDocuments past their expiation date

GadgetRequiredDocuments subscribes to EntityDataUpdatedListenerV2 and calls ComplianceClientService.getComplianceSnapshot() to rebuild its list on each data update.


Dependencies

ModuleRole
suredms-desktop-clientShell hosting, BaseView, WizardBuilder, NavigationHelper, JobManager
suredms-desktop-client-dataArchive, Document, DocDiscrepancy, Audit, AuditData entities
suredms-desktop-client-connectorDocDiscrepancyManager, NuxeoClientPool, AuditController persistence

Constraints and Notes

  • QualityView is a singleton; it is created the first time getInstance() is called and destroyed on logout.
  • AuditWizardContext.getFilteredDocuments() is deterministic within a session (same input, same random seed per ThreadLocalRandom), but randomness changes across re-runs.
  • AuditController.getAudits() returns an empty list if no archives are active — callers should always check active archive count first.
  • Discrepancy resolution writes optimistically to the entity model and syncs via DocDiscrepancyManager events. In remote mode, changes are persisted immediately; in local mode, they apply to the in-memory tree only until the archive is re-exported.
  • GadgetDiscrepancyItems re-subscribes to DocDiscrepancyManager on creation and unsubscribes in destroy(). Failure to call destroy() will create a listener leak.