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
| Package | Contents |
|---|---|
com.sureclinical.suredms.ui.views | QualityView — the main Quality module view |
com.sureclinical.suredms.ui.gadgets | All Quality gadgets: audit viewer, discrepancy items, mode selector, quality tree, report viewer, report actions |
com.sureclinical.suredms.ui.quality | GadgetChart, QualityCharts, QualityChartType — chart rendering harness |
com.sureclinical.suredms.ui.quality.wizard.audit | Wizard infrastructure: AuditWizardBuilder, AuditWizardContext, 4 step classes, AuditData, AuditModelFactory |
com.sureclinical.suredms.nuxeo | DocDiscrepancyManager, 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:
| Gadget | Gadget ID / Name | Purpose |
|---|---|---|
GadgetQualityModeSelector | modeSelector | Mode toggle — discrepancy list, audit wizard, or chart |
WorkArea | workArea | Internal panel that swaps its content based on active mode |
GadgetStack | viewerArea | Stack holding the PDF viewer and report viewer |
GadgetIcePDFViewer | embedded in stack | In-process PDF renderer for the selected document |
GadgetReportViewer | embedded in stack | Report HTML/PDF viewer |
GadgetDiscrepancyViewer | — | Per-document discrepancy editor embedded in WorkArea |
GadgetDocumentNavigator | — | Document navigator filtered to the active audit list |
GadgetAuditViewer | — | Tabular list of all audits for the active archives |
GadgetDiscrepancyItems | — | Filterable discrepancy table across all documents |
GadgetQualityTree | — | Tree navigator over the quality context |
GadgetMetadata | — | Read-only metadata panel for the selected document |
GadgetChart | — | Quality 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:
| Value | What it shows |
|---|---|
VIEW_DISCREPANCY_ITEM | Discrepancy item list + viewer |
ARCHIVE_AUDIT_WIZARD | Audit wizard launcher panel |
ARCHIVE_AUDIT_SAMPLE_LIST | Generated audit document sample list |
CHART_QC_TOTAL_DISCREPANCIES_VS_DOCUMENTS | Chart: discrepancies vs. document count |
CHART_QC_STUDY_DOC_TOTALS_OVER_TIME | Chart: documents over time |
CHART_QC_TOTAL_DOCS_BY_ROLE | Chart: documents grouped by role |
CHART_QC_TOTAL_DOCS_BY_STUDY | Chart: documents grouped by study |
CHART_QC_DOCUMENTS_BY_MILESTONE | Chart: 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):
- Retrieves
AuditDatafromAuditWizardContext.getAudit(). - Calls
DocDiscrepancyManager.getInstance().getDiscrepancies(audit.getAuditDocuments())to load existing discrepancies for the sampled documents. - Sets the discrepancy multimap on the
AuditData. - Sets
wizardResult = audit, which is passed toDialogResultListenercallbacks.
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:
| Field | Type | Default |
|---|---|---|
archive | Archive | Selected in Step 1 |
documents | List<Document> | All documents in the archive content types |
filteredDocuments | List<Document> | Sampled subset (cached until sampleSize changes) |
sampleSize | double | 10.0 (10%) |
auditName | String | User-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 Class | Dialog Header Key | Responsibility |
|---|---|---|
AuditWizardStep1SelectStudy | wizard.audit.step1 | Presents archive/study picker; sets context.archive |
AuditWizardStep2SelectContent | wizard.audit.step2 | Presents content type multi-select; populates context.documents |
AuditWizardStep3SelectSampleSize | wizard.audit.step3 | Numeric percentage spinner; sets context.sampleSize |
AuditWizardStep4CreateAuditList | wizard.audit.step4 | Displays 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
JXTableusing anAbstractTableModel. - Subscribes to
DocDiscrepancyManagerevents 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 usingNuxeoClientPool.
GadgetDiscrepancyItems
SC/suredms-desktop-client-quality/src/main/java/com/sureclinical/suredms/ui/gadgets/GadgetDiscrepancyItems.java
Extends DiscrepancyGadget. Implements EntityDataUpdatedListener, DiscrepancyManagerEventListener, QuickFindListener.
- Renders all
DocDiscrepancyrecords in aJXTable. - Two filter combo boxes:
ctrlDiscrepancySource(JTypedComboBox<Archive>) andctrlDiscrepancyView(JTypedComboBox<DiscrepancyStatus>). - Quick-find search panel for text filtering.
GadgetReportActionscontrol for generating discrepancy reports.- Subscribes to
DocDiscrepancyManagerviaaddEventListener. 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
| Field | Type | Description |
|---|---|---|
docDiscrepancies | Map<Document, Set<DocDiscrepancy>> | All discrepancies keyed by document |
managerEventListeners | List<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
| Method | Behaviour |
|---|---|
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:
| Method | Transport | Description |
|---|---|---|
saveAudit(AuditData) | NuxeoClientPool.executeSilentQuery | Creates 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):
| Type | Description |
|---|---|
QC_TOTAL_DISCREPANCIES_VS_DOCUMENTS | Stacked bar or scatter: discrepancy count vs. document count |
QC_STUDY_DOC_TOTALS_OVER_TIME | Line: document and discrepancy totals over calendar time |
QC_TOTAL_DOCS_BY_ROLE | Bar: document count per organizational role |
QC_TOTAL_DOCS_BY_STUDY | Bar: document count per archive/study |
QC_DOCUMENTS_BY_MILESTONE | Bar: 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-connector — com.sureclinical.suredms.services.compliance
| Method | Description |
|---|---|
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
| Gadget | Class | Location | Purpose |
|---|---|---|---|
| Required documents | GadgetRequiredDocuments | HomeView | Summary of missing required documents across all archives |
| Expired documents | GadgetExpiredDocuments | HomeView | Documents past their expiation date |
GadgetRequiredDocuments subscribes to EntityDataUpdatedListenerV2 and calls ComplianceClientService.getComplianceSnapshot() to rebuild its list on each data update.
Dependencies
| Module | Role |
|---|---|
suredms-desktop-client | Shell hosting, BaseView, WizardBuilder, NavigationHelper, JobManager |
suredms-desktop-client-data | Archive, Document, DocDiscrepancy, Audit, AuditData entities |
suredms-desktop-client-connector | DocDiscrepancyManager, NuxeoClientPool, AuditController persistence |
Constraints and Notes
QualityViewis a singleton; it is created the first timegetInstance()is called and destroyed on logout.AuditWizardContext.getFilteredDocuments()is deterministic within a session (same input, same random seed perThreadLocalRandom), 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
DocDiscrepancyManagerevents. In remote mode, changes are persisted immediately; in local mode, they apply to the in-memory tree only until the archive is re-exported. GadgetDiscrepancyItemsre-subscribes toDocDiscrepancyManageron creation and unsubscribes indestroy(). Failure to calldestroy()will create a listener leak.