Skip to main content
Version: 3.0.1

SDD Architecture

Product design

Space for SDD and related design spec pages.

Context
Purpose of the System

The purpose of the application is to enable diagnostic infection tests to be run in a more efficient manner. By combining modern medical technologies with a highly accurate AI algorithm to automatically highlight any testing issues, better QC and results are provided with less time spent manually reviewing data.

The audience of this application is meant for clinical laboratories, and the personnel (CLS) including. Also, IT team (e.g., for setting up new users), and managers looking at trends and performing quality control.

No PII (Personally Identifiable Information) or PHI (Protected Health Information) is intended to be stored anywhere in the solution. All information handled and analyzed is anonymized prior to the analysis, meaning that no data can be attributed to any particular person.

The architecture is divided into frontend and backend, where the frontend is the client-facing part with user interfaces and connected APIs, whilst in the backend all required algorithms can perform the necessary actions.

System Architecture

The server-side infrastructure is based on serverless Compute service AWS Lambda, using the Laravel-based deployment platform Vapor. Vapor is used for managing Laravel infrastructures using Lambda in a more convenient way. AWS Cognito is used for all user authentication.

The Web client side is based on Laravel and Vue. When information is sent by the client from the frontend, it arrives in an AWS Lambda which sends information back to the client. For authentication, each client gets their own, monitored AWS account with AWS S3 and AWS Cognito enabled, as well as API functionality (on request) for S3. For authentication, clients can either use AWS Cognito-managed identities or, optionally, integrate their corporate Identity Provider into their Cognito account to achieve identity federation. Both OpenID Connect SAML are supported for corporate user directory integration.

The AWS S3 API provides a convenient method for automating upload to and download from the system to enable automated workflow integration with thermocyclers and LIMS/LIS systems. Optionally, AWS File Transfer service can be used in place of the direct S3 API, this enables FTP, SFTP and FTPS file transfer protocols. When using AWS Transfer clients can use their own software for uploading and downloading files using software that supports the aforementioned protocols (e.g., WinSCP, which also supports direct S3 connections, and FileZilla).

Key features of PCR.AI
  • High accuracy fully automated analysis, QC and reporting for any real-time PCR data
  • Ease regulatory compliance to ISO 15189, UKAS, etc.
  • Machine-learning setup, inference based routine analysis
  • Accessible through any web browser
  • Secure, Standards compliant
  • Clinically validated
  • Review, comment and amend functionality (with secure access controls)
  • Result and statistical control performance tracking in real-time
  • Tracking results across multiple devices and sites
Workflow using PCR.AI

image12

Workflow Description:

The diagram illustrates the end-to-end processing workflow for run files in PCRI.AI:

  1. Run File Import: A run file from the thermocycler is imported into PCRI.AI via S3 upload (automated or manual).

  2. Classification Path:

    • If the laboratory has already analyzed the run, PCRI.AI compares the machine's classifications and CT values against its own analysis
    • If not pre-analyzed, PCRI.AI classifies all readings using configured rules
  3. QC Rules Evaluation: Quality control rules are applied to validate:

    • Inhibition detection
    • Control validity (positive/negative controls)
    • Target-specific thresholds
  4. Westgard Calculation: Statistical QC is performed using configured Westgard limits (mean, SD) to detect systematic or random errors in control samples.

  5. Error Handling Decision:

    • No Errors: Results are exported to LIMS
    • Errors Present: Laboratory scientist follows the corrective action workflow:
      • Reviews error codes and applies resolutions
      • Determines if results can be reported after resolution
      • If reportable: exports to LIMS
      • If not reportable: data is stored for audit and further analysis
  6. Audit Storage: All processed data is stored in Aurora MySQL for audit trail and subsequent analysis regardless of final disposition.


Architecture Patterns

Domain-Driven Design (DDD) Elements

The system implements several DDD patterns for organizing business logic:

Domain Services

DirectoryPurpose
app/Analyzer/Core analysis engine - coordinates rule execution and result aggregation
app/Services/Business logic services - encapsulates complex operations
app/Actions/Single-responsibility actions - one action class per use case

Domain Models

ModelContractDescription
WellAnalyzableWellCore well entity with observations
ObservationAnalyzableObservationTarget observation entity
Run-Run file entity
Target-Target configuration entity

Value Objects

ClassPurpose
WellNumberImmutable well position (A1-H12)
HasUuidUUID trait for entity identification

Repository Pattern

Configuration data is accessed through repository contracts, enabling testing and alternative implementations:

ContractImplementationPurpose
ConfigurationRepositoryEloquentConfigurationRepositoryMain configuration access
ClientConfigurationRepositoryEloquentClientConfigurationRepositoryClient-specific settings

Location: app/Analyzer/Contracts/ (contracts), app/Analyzer/ (implementations)

Strategy Pattern

Analysis rules are implemented as pluggable strategies, allowing new rules to be added without modifying the engine:

ComponentLocationPurpose
Rule Contractapp/Analyzer/Contracts/AnalyzerRuleContract.phpDefines rule interface
Rule Classesapp/Analyzer/Rules/*.phpConcrete rule implementations
Rule Modelapp/Rule.phpDatabase model with strategy mapping

Mapping: The programmatic_rule_name field maps to PHP class names via App\Analyzer\Rules\{StudlyCase}Rule.

Factory Pattern

FactoryLocationPurpose
Analyzer Factoryapp/Analyzer/Creates analysis components
RunFileConverter Factoriesapp/RunFileConverter/Creates file conversion components
Normalizer Factoryapp/Analyzer/Normalizer/Creates data normalizers

Analysis Flow (6-Stage Pipeline)

1. DATA IMPORT
Raw PCR data imported from run file (.sds, .pcrd, .eds, .ixo)


2. NORMALIZATION
Data normalized to standard format via JsonTemplateNormalizer


3. VALIDATION
Data validated against business rules (accession, labels, dates)


4. ANALYSIS
Rules applied in precedence order to analyze results


5. QUALITY CONTROL
Westgard rules applied to control observations


6. RESULT GENERATION
Final outcomes, error codes, and export status determined

AWS Services Summary

The following AWS services and third-party platforms form the infrastructure backbone of PCRI.AI:

ServicePurpose in PCRI.AIKey Benefit
AWS LambdaServerless compute for API and processingAuto-scaling, pay-per-use
Amazon CognitoUser authentication (native + SAML/SSO)Enterprise auth features, MFA
Amazon ElastiCacheRedis caching layerImproved page load performance
Aurora Serverless v2Primary MySQL databaseAuto-scaling, cost optimization
Amazon S3Run file storage, LIMS exports, archivesDurable, scalable object storage
Amazon SQSMessage queuing for async processingDecoupled import processing
Amazon SESEmail delivery (notifications, alerts)High deliverability
Amazon DynamoDBSession storage (Vapor default)Low-latency session management
PusherReal-time WebSocket communicationLive notifications, progress updates

Detailed Rationale: Technology selection rationale with comparison tables (Lambda vs EC2, Cognito vs Laravel Native, Aurora Serverless vs Standard Aurora) is documented in SDS Architecture Overview.


Rules Engine

The Rules Engine is the core analytical component responsible for evaluating run data against configured rules.

Responsibility Boundaries:

  • Rule Mapper: Resolves programmatic rule names to PHP handler classes
  • Execution Engine: Processes rules in precedence order per configuration
  • Error Propagator: Assigns error codes at well/target/mix levels based on rule outcomes

Dependencies:

  • Aurora MySQL: Rule configuration, execution state
  • Configuration schemas: Rule precedence, error mappings (see sdd-configuration.md)

Interfaces:

  • Input: Parsed run file data (JSON), configuration context
  • Output: Well/target/mix classifications, error codes, Westgard violations

See: sdd-algorithms.md "Rule Mapping Architecture" for execution details.

Alert Notification System

Alerts configured in sdd-configuration.md are delivered through a dual-channel architecture:

Delivery Channels:

  • Email: Amazon SES for threshold violation notifications
  • Real-time: Pusher WebSocket for in-app notifications

Evaluation Trigger: Alert evaluation runs on scheduled intervals (configurable per alert type).

Ownership Separation:

  • Alert configuration and trigger rules: See sdd-configuration.md "Alerts Configuration"
  • Alert evaluation logic: Scheduled Lambda function queries trends data
  • Alert delivery: SES (email) and Pusher (real-time) based on user preferences

See: sdd-configuration.md for alert trigger definitions and aggregation modes.

Progress Feedback System

The Progress Feedback System provides real-time visual feedback during long-running operations (e.g., Reanalysis).

Design Decisions:

DecisionRationale
10-second display thresholdOperations under 10s complete fast enough that progress UI adds no value
2-second update intervalBalances responsiveness with server load; configurable per deployment
Blocking overlay with navigationPrevents conflicting user actions while allowing escape to other screens
Background tracking on navigate-awayUsers should not lose progress visibility by navigating; state persists

Architecture:

[Long-running Operation]


[Server calculates duration]

┌─────┴─────┐
│ < 10s │ ≥ 10s
│ │
▼ ▼
No progress [Pusher WebSocket]
display │
┌──────┴──────┐
▼ ▼
[User A session] [User B session]
(progress UI) (progress UI)

Multi-User Synchronization:

  • Pusher broadcasts progress updates to all sessions viewing the affected resource
  • Users joining mid-operation see current progress state
  • No distinction between initiator and observers in the UI

Navigation Persistence:

  • Progress tracking continues in background when user navigates away
  • On return to originating screen, progress indicator resumes with current state
  • Multiple concurrent operations tracked independently

Configuration (environment-level):

PropertyDefaultDescription
progress.display_threshold_seconds10Minimum calculated duration to show progress
progress.update_interval_seconds2Frequency of percentage updates

Related SRS Requirements:

  • REQ-PROGRESS-001 through REQ-PROGRESS-004 (progress display, navigation, concurrency, multi-user)

See: sdd-configuration.md for deployment-level configuration options.

Comment Notification System

The Comment Notification System enables user mentions (@-tagging) in comments with dual-channel delivery and role-based access control.

Delivery Architecture:

[User submits comment with @mention]


[Server processes tags]

┌───────────┴───────────┐
▼ ▼
[Check recipient [External email?]
preferences] │
│ ▼
│ [SES Email]
│ (always sent)

├── "In-app" ──→ [Pusher only]

├── "Email" ───→ [SES only]

└── "Both" ────→ [Pusher + SES]
(default)

Dual-Channel Delivery:

ChannelTechnologyUse Case
In-appPusher WebSocketReal-time notification badge, pane updates
EmailAmazon SESOffline notification, deep link to comment

Role-Based Mention Access:

Initiator RoleCan Mention
SUPER_ADMINAll roles
MANAGERMANAGER, SENIOR, JUNIOR
SENIORMANAGER, SENIOR, JUNIOR
JUNIORMANAGER, SENIOR, JUNIOR
CLIENT_ADMIN(none)

Notification State Machine:

┌─────────┐                    ┌────────┐
│ UNREAD │───[navigate to]───→│ READ │
│ │ comment │ │
└────┬────┘ └───┬────┘
│ │
└──────[toggle action]────────┘
  • Unread → Read: Automatic on navigation to linked comment; explicit toggle
  • Read → Unread: Explicit toggle only
  • Mark All Read: Bulk action, resets unread count to zero

External User Invitation:

  • Users not in system can be invited by email
  • Email invitation bypasses preference check (always sends email)
  • Validates email format before submission

Email Content Structure:

  • Subject: Identifies requesting user
  • Body: Run ID, Well ID (if applicable), comment text, direct link

Configuration:

PropertyDefaultDescription
notifications.default_preferenceBothDefault delivery method for new users
notifications.comment_preview_length200Characters shown in notification preview

Related SRS Requirements:

  • REQ-COMMENTS-001 through REQ-COMMENTS-010 (tagging, delivery, preferences, display, navigation, access control)

See: sdd-configuration.md for notification configuration options.

Data Ownership and Persistence

Authoritative Sources:

  • Aurora MySQL: All transactional data (runs, wells, observations, configurations)
  • S3: Archived run files, LIMS exports, problem files

Derived Data:

  • ElastiCache (Redis): Session cache, temporary computation results
  • DynamoDB: Session tokens (managed by Laravel/Vapor)

Data is authoritative in Aurora MySQL. Cache layers (ElastiCache, DynamoDB) contain derived or temporary data that can be regenerated from authoritative sources.

Server Database Type Migration

Two Possible Solutions

ApproachProsCons
* Moving from Aurora Serverless v1 to Aurora Serverless v2 From Aws https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/aurora-serverless-v2.upgrade.html#aurora-serverless-v2.move-from-serverless-v1Loses ability of database management from vapor
* use Vapor to provision a new serverless v2Need to migrate data manually
Diagram/s and explanations
High Level Use Case Diagrams
User Management Use Case Diagram

The User Management subsystem enables role-based access control for user lifecycle operations.

Role Access Matrix:

Use CaseSuper AdminClient AdminJunior/Senior/Manager
Create UserYesYesNo
Modify UserYesYes (except Super Admin)No
Block/Unblock UserYesYesNo
Delete UserYesYesNo
Reset Password (Admin)YesYesNo
Reset Password (Self)YesYesYes
Restore Deleted UserYesNoNo
Configure MFAYesYesYes (own account)

Design Notes:

  • User deletion is soft delete (uses deleted_at timestamp); audit trail preserved
  • Password reset supports both self-service (Cognito "Forgot Password") and admin-initiated flows
  • Client Admin cannot modify Super Admin accounts (REQ-USERMGMT-013 AC-09)

See: sdd-security.md for authentication flow details.


Audit Use Case Diagram

The Audit subsystem provides audit trail visibility with site-based access control.

Access Control:

RoleAudit Access LevelSites Visible
JuniorView, Filter, ExportAssigned site only
SeniorView, Filter, ExportAssigned site only
ManagerView, Filter, ExportAll assigned sites
Client AdminView, Filter, ExportAll client sites

Design Notes:

  • All roles can view audit logs (REQ-AUDIT-004)
  • Audit data is site-filtered based on user's site access permissions
  • Export format: Excel only (XLSX) per REQ-AUDIT-003
  • Audit records are immutable; referencing deleted users preserved

See: REQ-AUDIT-001 for audit trail requirements.

Sequence Diagrams
Login Sequence Diagram

The authentication system supports two login paths: native application login and Cognito Hosted UI. Both integrate with AWS Cognito for session management.

Native Login Flow:

SAML/SSO Login Flow:

Session Management Details:

AspectImplementation
Session StorageDynamoDB (Laravel Vapor default, SESSION_DRIVER=dynamodb)
Session IdentifierJWT token from Cognito
Single-Device EnforcementCognito GlobalSignOut on new login (REQ-USERMGMT-011 AC-02)
Lockout Threshold5 failed attempts (configurable via max_login_attempts)
Lockout Duration~15 minutes (Cognito default, time-based auto-unlock)
Lockout ManagementCognito-managed (not application-level tracking)

Design Notes:

  • Native login is the default; Cognito Hosted UI available at client request
  • Both OpenID Connect and SAML supported for corporate IdP federation
  • Callback URL pattern: ${APP_URL}/login/samlcallback

See: sdd-security.md for detailed authentication architecture.

State Diagrams
Well State Diagram

Wells transition through mutually exclusive states based on analysis results, error assignment, resolution application, and export.

State Definitions:

StateDatabase ConditionDescription
UNANALYZEDerror_code_id=NULL, lims_status=NULLNewly imported, pending analysis
HAS_ERRORerror_code_id setError assigned by rules (mutually exclusive with LIMS status)
HAS_LIMS_STATUSlims_status setLIMS outcome assigned by rules
RESOLVEDresolution_codes setResolution code(s) applied
EXPORTEDexport_date setExported to LIMS (terminal state)

LIMS Status Values (from lims_statuses table):

CodeTypeMeaning
DETECTEDInformation (4)Target successfully detected
NOT DETECTEDInformation (4)Target not detected
INCONCLUSIVEInformation (4)Result inconclusive
REAMPWarning (1)Re-amplify required
REXCTWarning (1)Re-extraction required
TNPWarning (1)Test Not Performed
EXCLUDEExclude (2)Well excluded from analysis

Error Type Constants (from ErrorCode.php):

Type IDNameOutcome Color
0Label ErrorRED
1ErrorRED
2WarningYELLOW
3InformationGREEN
4Associate Control ErrorRED

Key Implementation Files:

  • app/Well.php - Core well model with state methods
  • app/ErrorCode.php - Error type constants
  • app/LimsStatus.php - LIMS status types
  • app/Analyzer/Rules/Concerns/SetLimsStatusToWell.php - State transitions
  • app/Analyzer/Rules/Concerns/SetErrorToWell.php - Error assignment

High Level Entity Relationship Diagram

Core Entity Relationships:

Entity Descriptions:

EntityPurposeKey Relationships
ClientOrganization/tenantHas many Sites
SitePhysical laboratory locationHas many Runs, Users
UserSystem user with roleBelongs to Site(s), performs Audit actions
RunSingle instrument run fileContains many Wells
WellSample position (A1-H12)Contains Observations, assigned to Mix, has one Error OR LIMS status
ObservationSingle target measurementLinks to Target, stores CT/quantity
MixCombination of targets/dyesMany-to-many with Targets
TargetAnalytical target (gene, marker)Uses Dye for detection
DyeFluorescent reporterUsed by Targets
Error_CodeError code definitionOne-to-one with Well via error_code_id
LIMS_StatusLIMS outcome definitionOne-to-one with Well via lims_status (code-based join)
Audit_LogImmutable audit recordLinks to Run, User

Verified Storage Patterns (from code review 2026-01-20):

AspectImplementationColumn
Error code storageSingle UUID FK (not junction table)wells.error_code_id
LIMS status storageString FK (code-based join)wells.lims_statuslims_statuses.code
Export trackingDatetime columnwells.export_date (null = not exported)
Resolution trackingText field (pipe-delimited)wells.resolution_codes

Additional Entities (per Q-012):

  • control_labels - Control type definitions
  • roles - User role configuration
  • westgard_limits - Westgard QC thresholds
  • lots - Reagent lot tracking

See SDD dev questions Q-011, Q-012 for full entity details.


Application Feasibility Test

Historical (2026-01-18): Aurora MySQL 8.0 was selected and deployed as the database platform. Test result: PASSED - System operational in production. See: Runtime Dependencies table in sdd-algorithms.md for current database configuration.

Cost Analysis

Historical (2026-01-18): Cost analysis completed; Aurora Serverless v2 selected. Decision: On-demand scaling provides cost optimization for variable workloads. See: "Amazon RDS with Aurora Serverless v2" section in this document for architecture details.


Vue Component Architecture

The frontend is built as a Vue.js Single Page Application (SPA) with the following structure:

Directory Structure

resources/frontend/src/
├── components/ # Reusable UI components
├── mixins/ # Shared component logic
│ ├── resolution/ # Error resolution workflows
│ ├── well-multiselect/# Well selection handling
│ └── client-configurations/
├── store/modules/ # Vuex state management
│ ├── auth.js # Authentication state
│ ├── runs.js # Run file tracking
│ ├── features.js # Feature flags
│ └── auditOptions.js # Audit filtering
├── views/ # Page-level components
└── router/ # Vue Router configuration

State Management

Vuex stores manage application state:

  • auth: User authentication and session
  • runs: Recent runs and upload progress
  • features: Feature flag toggles
  • auditOptions: Audit trail filtering

Key Component Patterns

PatternPurposeExample
MixinsShared logic across componentsWells.js, FilterWells.js
Store ModulesCentralized stateauth.js, runs.js
Resolution ComponentsError handling workflowsWellResolutionProposalForm.js

The following SRS requirements are implemented by the design described in this document:

Authentication and User Management (Amazon Cognito)

RequirementDomainDescriptionRelevance
REQ-USERMGMT-009User ManagementAuthenticate UsersCognito provides native and federated (SAML) authentication as described in SDD
REQ-USERMGMT-011User ManagementManage User SessionsDynamoDB used for session management; Cognito global sign-out for session termination
REQ-USERMGMT-004User ManagementConfigure User MFACognito MFA/TOTP implementation
REQ-USERMGMT-006User ManagementControl User Account StatusCognito global sign-out for session termination on user disable
REQ-USERMGMT-015User ManagementEnforce Authentication Security PoliciesCognito enforces password complexity, history, expiry, and lockout policies

File Storage and Import (Amazon S3)

RequirementDomainDescriptionRelevance
REQ-FILEIMPORT-001File ImportImport Run Files from Monitored FolderS3 triggers on toPcrai folder initiate Lambda processing
REQ-FILEIMPORT-010File ImportManage Import Folder StructureS3 folder structure (toPcrai, Processing, Problem_Files, archive bucket)
REQ-FILEIMPORT-003File ImportAnalyze Run Data Using DXAI AnalyserCalibration files stored in S3 bucket (chill-rabbit-calibrations)
REQ-SITE-001Site ManagementProvision Storage on Site CreationS3 folder creation for LIMS_Reports per site
REQ-SITE-002Site ManagementConfigure S3 Structure PreservationS3 folder structure configuration options
REQ-SITE-003Site ManagementSpecify Custom S3 Folder NameS3 path customization for LIMS_Export and Runs folders
REQ-UPLOAD-001Upload RunsAccept Run File UploadsFiles uploaded to S3 via application or S3 API

Performance and Scalability (AWS Lambda, Aurora Serverless)

RequirementDomainDescriptionRelevance
REQ-NFR-001Non-FunctionalPage Load TimeLambda auto-scaling ensures consistent performance under load
REQ-NFR-002Non-FunctionalReanalysis Operation TimeLambda compute for analysis operations
REQ-NFR-003Non-FunctionalConcurrent User CapacityServerless architecture (Lambda, Aurora Serverless) enables 30+ concurrent users with graceful degradation
REQ-USERMGMT-016User ManagementEnsure System Readiness Before LoginAurora Serverless cold start handling (database wakeup)

Email Services (Amazon SES)

RequirementDomainDescriptionRelevance
REQ-AUDIT-003Audit LogExport Audit DataSES delivers export download links via email
REQ-USERMGMT-005User ManagementRequest Email VerificationSES sends verification emails
REQ-USERMGMT-008User ManagementCreate User AccountSES sends notification emails on account creation

Real-Time Communication (Pusher)

RequirementDomainDescriptionRelevance
REQ-NOTIF-001NotificationsDisplay Runfile Status NotificationsPusher enables real-time notification updates
REQ-UPLOAD-003Upload RunsDisplay Upload ProgressReal-time progress updates via Pusher

Message Queue Processing (Amazon SQS)

RequirementDomainDescriptionRelevance
REQ-FILEIMPORT-001File ImportImport Run Files from Monitored FolderSQS decouples S3 triggers from Lambda processing
REQ-AUDIT-003Audit LogExport Audit DataBackground job queuing for large exports

Caching (Amazon ElastiCache)

RequirementDomainDescriptionRelevance
REQ-NFR-001Non-FunctionalPage Load TimeElastiCache improves response times for frequently accessed data

Database (Amazon RDS/Aurora Serverless)

RequirementDomainDescriptionRelevance
REQ-AUDIT-001Audit LogDisplay Audit TrailAurora stores immutable audit records
REQ-ANALYTICS-001AnalyticsExecute Rules on Error WellsAurora stores rule execution state and well data

Data Privacy (No PII/PHI Storage)

RequirementDomainDescriptionRelevance
All DomainsSystem-wideData handlingArchitecture explicitly states no PII/PHI storage; all data anonymized prior to analysis

High-Level Entity Relationship Diagram

Core Entity Relationships

Wells Table Schema (Key Columns)

ColumnTypeDescription
idUUIDPrimary key
run_idUUIDFK to runs
run_mix_idUUIDFK to run_mixes (nullable)
specimen_idUUIDFK to specimens (nullable)
error_code_idUUIDFK to error_codes (nullable) - single error per well
lims_statusVARCHARLIMS status code string (not FK, lookup to lims_statuses.code)
export_dateDATETIMENull = not exported
excludeBOOLEANManual exclusion flag
is_flaggedBOOLEANFlagged for review
resolution_codesTEXTPipe-delimited resolution codes applied

Error Code Storage Pattern

Architecture Decision: Simple foreign key relationship, not a junction table.

  • wells.error_code_iderror_codes.id (BelongsTo)
  • One error code per well maximum
  • Error codes are site-scoped (error_codes.site_id)
  • Soft-deleted error codes preserved for historical wells

LIMS Status Storage Pattern

Architecture Decision: String column with lookup table for metadata.

  • wells.lims_status stores the status code directly (e.g., "DETECTED", "RPT", "RXT")
  • lims_statuses table provides: code, message template, type (Warning/Exclude/Information), result (DETECTED/NOT_DETECTED)
  • Lookup is via string match (lims_statuses.code), not FK constraint
  • Allows flexibility for site-specific LIMS status definitions

Implementation

ComponentLocation
Well Modelapp/Well.php
ErrorCode Modelapp/ErrorCode.php
LimsStatus Modelapp/LimsStatus.php
Wells Migrationdatabase/migrations/app/2020_02_01_064128_create_wells_table.php
Error Codes Migrationdatabase/migrations/app/2020_01_24_113210_create_error_codes_table.php

Well State Model

State Composition

Wells do not have a single status enum. State is computed from multiple indicators:

Error Code Types (from ErrorCode::ERROR_TYPE)

TypeValueOutcome TypeBlocks Export
Label Error0ErrorYes
Error1ErrorYes
Warning2WarningNo
Information3InformationNo
Associate Control Error4ErrorYes

LIMS Status Types (from LimsStatus::TYPES)

TypeValueDescription
Warning1Re-test recommended (RPT, RXT)
Exclude2Well excluded from export
Information4Normal result (DETECTED, NOT_DETECTED)

LIMS Status Results (from LimsStatus::RESULTS)

ResultValueDescription
DETECTED1Target detected
NOT_DETECTED2Target not detected

Computed Run Status (from GetRunStatus.php)

The overall run status is computed from well states:

Run StatusCondition
ALL_WELLS_EXPORTEDAll wells have export_date set
ALL_WELLS_READY_FOR_EXPORTNo wells with blocking errors, none exported yet
NO_EXPORT_ERRORS_TO_RESOLVEWells have errors but no LIMS status assigned
SOME_WELLS_READY_FOR_EXPORT_WITH_ERRORS_TO_RESOLVEMixed state: some ready, some with errors

Implementation

ComponentLocation
Run Status Calculatorapp/GetRunStatus.php
Outcome Type LogicWell@outcomeType()
Error Type ConstantsErrorCode::ERROR_TYPE
LIMS Type ConstantsLimsStatus::TYPES

Complete Database Schema Inventory

Core Data Tables

TableKey ColumnsForeign KeysNotes
usersid (UUID), username, email, user_type, mfa_secret, blocked, logged_in_site_idlogged_in_site_id → sitesSoft deletes; Core user authentication
runsid (UUID), run_name, uploaded_user_id, modified_user_id, thermocycler_id, num_label_errors, num_pending_resolutionsuploaded_user_id, modified_user_id, thermocycler_id → FKRoot data entity; Tracks error/resolution counts
wellsid (UUID), run_id, run_mix_id, specimen_id, error_code_id, lims_status, export_date, exclude, is_flagged, resolution_codesrun_id, run_mix_id, specimen_id, error_code_id → FKPrimary analytical unit; Microsecond timestamps
observationsid (UUID), well_id, role_id, target_id, dye_id, machine_cls, dxai_cls, final_cls, machine_ct, final_ct, readingswell_id, role_id, target_id, dye_id → FKPer-well results; Multiple classification systems
error_codesid (UUID), error_code, error_message, error_level, error_type, lims_statusNoneError enumeration; Soft deleted for history
lims_statusesid (UUID), code, message, typeNoneLIMS integration status codes
resolution_codesid (UUID), error_code_id, resolution_message_id, is_patient, is_default, lims_statuserror_code_id, resolution_message_id → FKError → resolution workflow mapping

Configuration Tables

TableKey ColumnsNotes
mixesid, mix_name, use_passive_dyePCR reaction mix catalog
dyesid, dye_name, quencher, colourFluorophore catalog
targetsid, mix_id, dye_id, target_name, type, is_passiveAnalyte definitions
rolesid, role_nameSample classification (positive control, patient, etc.)
role_to_target_mappingsid, role_id, target_id, mix_id, role_aliasJunction table for role-mix-target
control_labelsid, role_id, mix_id, role_alias, is_strict, site_id, backup_mixes_idsv3.0.0+ enhanced role mapping
specimensid, specimen_nameSample type catalog
thermocyclersid, thermocycler_type, thermocycler_serial_number, thermocycler_plate_sizeInstrument registry
extraction_instrumentsid, extraction_model_id, extraction_instrument_nameExtraction instrument instances
lotsid, lot_name, in_useReagent lot tracking

Quality Control Tables

TableKey ColumnsNotes
westgard_eventsid, code, messageWestgard rule violation catalog
westgard_limitsid, extraction_instrument_id, lot_id, role_to_target_mapping_id, sd, mean, in_errorQC statistics per instrument-lot-target
control_range_settingsid, role_to_target_mapping_id, lot_id, low_bound, up_bound, quant_or_ctControl acceptance limits

Multi-Site & Workflow Tables

TableKey ColumnsNotes
sitesid, namePhysical lab locations; Soft deletes
user_visible_sitesuser_id, site_idJunction for site access control
run_mixesid, run_id, mix_id, num_wells, export_statusMix composition per run
run_targetsid, run_id, target_id, error_codes, std_curve_gradPer-target metrics
client_configurationsid, name, valueKey-value application settings
tagsid, name, archive, site_idRun categorization
commentsid, user_id, parent_id, commentable_id, commentable_type, textPolymorphic threaded comments

Key Schema Characteristics

  • UUIDs for all primary keys (ordered UUIDs)
  • Decimals for QC statistics: decimal(32,10) for precision
  • Smallint enums for status fields
  • JSON text fields for arrays (error_codes, mix_ids)
  • Soft deletes on users, sites, control_labels, tags

Audit Trail System

Overview

PCRI.AI logs all significant user actions to an audits table via the LogIntoDatabase listener.

Audit Table Schema

ColumnTypeDescription
idUUIDPrimary key
usernameStringUser who performed action
areaStringFunctional area (Configuration, User Management, Runfile Report)
change_typeStringType of change (User Account, Mix, Well)
actionStringSpecific action (Created, Edit, Delete)
change_locationStringContext (resource name, location)
value_beforeStringPrevious value
value_afterStringNew value
site_nameStringSite context (nullable)
created_atTimestampMicrosecond-precision timestamp

Audit Event Categories (71 Total)

User Management (11 events):

  • UserLoggedIn, UserLoggedOut
  • UserAccountCreated, UserAccountDeleted, UserAccountDisabled, UserAccountEnabled
  • UserAssociatedWithRole, RoleChangedForUser
  • PasswordChanged, EmailVerificationSent, EmailVerified

Configuration (42 events):

  • Dye: DyeCreated, DyeMappedToTarget
  • Target: TargetCreated, EcSetToTarget, IcSetToTarget, RoleToTargetMapCreated
  • Mix: MixCreated, MixEnabled, MixDisabled, MixMappedToTarget, SpecimenMappedToMix, RoleToMixMapCreated
  • Westgard: LotSetToWestgardLimits, MeanSetToWestgardLimits, SDSetToWestgardLimits, HistoricCvSetToWestgardLimits
  • Rules: RuleCreated, RuleMapped
  • Instruments: ThermocyclerCreated, ExtractionInstrumentCreated, ExtractionModelCreated

Runfile Report (15 events):

  • Well edits: AccessionSetToWell, BatchNumberSetToWell, SpecimenNameSetToWell, SampleNameSetToWell, RoleAliasSetToWell, ExtractionDateSetToWell
  • Resolution: ResolutionCodeAppendToWell
  • Run operations: RunFileImported, RunFileOpened, RunFileExported, WellExported

Implementation

ComponentLocation
Event Interfaceapp/Events/AuditableEvent.php
Database Listenerapp/Listeners/LogIntoDatabase.php
Audit Modelapp/Audit.php

External Integrations Inventory

Integration Summary

ServiceTypeStatusPrimary UseConfig File
Amazon S3Cloud StorageActiveFile storage, run imports/exportsconfig/filesystems.php
Amazon SESEmailAvailableAlternative email deliveryconfig/mail.php
SendGridEmailPrimaryEmail notificationsconfig/mail.php
PusherReal-timeActiveWebSocket broadcastingconfig/broadcasting.php
Amazon CognitoAuthenticationActiveUser auth, MFA, SSOconfig/aws-cognito.php
Microsoft GraphDocument MgmtActiveSharePoint integrationconfig/microsoft-graph.php
SentryError TrackingActiveError/performance monitoringconfig/sentry.php

Amazon S3 (Object Storage)

Configuration: config/filesystems.php

Operations:

  • Run file storage and retrieval
  • LIMS export file storage
  • Multi-site folder management
  • Lambda trigger management for automated imports

Environment Variables: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_DEFAULT_REGION, AWS_BUCKET

Amazon Cognito (Authentication)

Configuration: config/aws-cognito.php, config/aws-super-admin-cognito.php

Operations:

  • ADMIN_USER_PASSWORD_AUTH flow
  • User CRUD (create, update attributes, disable, delete)
  • MFA management (enable/disable software token)
  • SAML/SSO integration

Key Files: app/Support/CognitoAuthenticator.php, app/CognitoUserManager.php

Custom Attributes: custom:UserGroup, custom:VisibleSites

Pusher (Real-time Messaging)

Configuration: config/broadcasting.php

Channels (already documented):

  • Run.Create, Run.Analyse, Run.Calibrate
  • run-export, run-file-import
  • control-label-updated, notifications
  • App.User.{userId} (private)

SendGrid (Email)

Configuration: config/mail.php

Purpose: Primary email delivery for notifications, alerts, audit exports

From Address: hello@ivd.ai / Pcr.ai

Microsoft Graph (SharePoint)

Configuration: config/microsoft-graph.php

Purpose: SharePoint drive operations for document management

Key Files: app/Support/MicrosoftGraph/GraphService.php

Sentry (Error Tracking)

Configuration: config/sentry.php

Features:

  • Error/exception tracking
  • Performance monitoring
  • Client replay transfer

Breadcrumb Capture: Laravel logs, SQL queries, queue jobs


Note: This traceability section maps architecture components to functional requirements. Requirements are linked to their SRS domain documents for detailed specifications.