Skip to main content
Version: 3.0.0

Audit & Error Codes Design

Document Type: Domain Design (Tier 2) Domain: AUDIT, ERRORCODES Domain Character: Configuration-heavy SRS Reference: audit-log.md, errorcodes.md Status: Draft Last Updated: 2026-01-25


1. Overview

1.1 Purpose

The Audit & Error Codes domain provides two interconnected subsystems:

  1. Audit Trail System - Immutable logging of all system changes for compliance, accountability, and debugging
  2. Error Code Catalog - Configurable error conditions generated during analysis and validation

This domain is characterized by:

  • Configuration-heavy data models for error code taxonomy and properties
  • Immutable write-once storage for audit records
  • Multi-site isolation for both audit visibility and error code configuration
  • Event-driven architecture where domain events emit to a central audit listener

1.2 Requirements Covered

REQ IDTitleCategory
REQ-AUDIT-001Display Audit TrailAudit Display
REQ-AUDIT-002Filter Audit EntriesAudit Filtering
REQ-AUDIT-003Export Audit DataAudit Export
REQ-AUDIT-004Enforce Site-Based Access ControlAccess Control
REQ-ERRORCODES-001Generate Westgard Rule Error CodesQC Errors
REQ-ERRORCODES-002Generate Control Check Error CodesControl Errors
REQ-ERRORCODES-003Generate Inhibition Error CodesInhibition Errors
REQ-ERRORCODES-004Generate Quantification Error CodesQuant Errors
REQ-ERRORCODES-005Generate CT and Threshold Error CodesCT Errors
REQ-ERRORCODES-006Generate Classification Discrepancy Error CodesClassification Errors
REQ-ERRORCODES-007Generate Bacteremia Error CodesBacteremia Errors
REQ-ERRORCODES-008Generate Fluorescence Error CodesFluorescence Errors
REQ-ERRORCODES-009Generate Miscellaneous Analytical Error CodesMisc Errors
REQ-ERRORCODES-010Generate Parsing Validation Blocking Error CodesParsing Errors
REQ-ERRORCODES-011Generate Analysis Validation Blocking Error CodesAnalysis Errors

1.3 Constraints

Tier 2 Constraint: This document describes ownership, patterns, and design rationale. It links to reference docs for full schemas. It does not duplicate error code catalogs documented in the SRS.

1.4 Dependencies

DirectionDomain/ComponentPurpose
Audit receives fromAll domainsAuditableEvent implementations for change tracking
Audit provides toComplianceImmutable audit trail, export capability
Error codes consumed byRULESError code assignment during analysis
RUNRPTError display on run file reports
LIMSError codes in LIMS exports
KITCFGCombined outcomes, error resolutions

2. Component Architecture

2.1 Component Diagram

2.2 Component Responsibilities

ComponentTypeResponsibilityREQ Trace
AuditsControllerControllerQuery and display paginated audit entriesREQ-AUDIT-001, 002
AuditExportsControllerControllerInitiate audit export jobREQ-AUDIT-003
AuditFilterOptions/*ControllersProvide distinct filter valuesREQ-AUDIT-002
AuditableEventInterfaceContract for auditable domain eventsREQ-AUDIT-001
LogIntoDatabaseListenerPersist audit events to databaseREQ-AUDIT-001
GetAuditsActionActionEncapsulate audit query with filtersREQ-AUDIT-001, 002
AuditFiltersFilterApply filter criteria to queriesREQ-AUDIT-002, 004
AuditQueryBuilderQueryBuilderSite-scoped query buildingREQ-AUDIT-004
AuditExportJobJobBackground chunked export with emailREQ-AUDIT-003
ErrorCodesControllerControllerError code CRUD operationsREQ-ERRORCODES-*
GetErrorCodesActionActionQuery error codes with site scopeREQ-ERRORCODES-*
ErrorCodeModelError code entity with level/typeREQ-ERRORCODES-*
ErrorCodesRelationRelationMap error codes to run targetsREQ-ERRORCODES-*

2.3 Architectural Patterns

Pattern: Event-Driven Audit Capture

All auditable changes emit events implementing AuditableEvent:

Domain Action
└── emit(SomeEvent implements AuditableEvent)
└── LogIntoDatabase listener
└── Audit::create([...])
└── Aurora Audit DB

Pattern: Separate Audit Database

Audit records are stored in a dedicated Aurora database:

// Audit model constructor sets connection
$this->setConnection(config('database.audit')); // mysql_audit

This provides:

  • Immutability guarantee (no accidental deletes via main DB)
  • Independent scaling and backup policies
  • Compliance isolation

Pattern: Seed vs Custom Error Codes

Error codes fall into two categories:

  • Seed codes: Must exist because rule implementations are hardcoded to output them
  • Custom codes: Client-defined for Combined Outcomes and Resolutions

Pattern: Error Level Assignment

Error codes target three levels:

  • Well: Entire well affected
  • Target: Specific target within well
  • Mix: Entire mix affected

3. Data Design

3.1 Entity Ownership

This domain owns the following entities:

EntityTablePurposeKey Relationships
Auditaudits (audit DB)Immutable change recordsNone (standalone)
ErrorCodeerror_codesError condition definitions→ resolution_codes
ResolutionCoderesolution_codesResolution actions for errors→ error_code

See Database Reference for full schema.

3.2 Audit Entity Design

Audit Record Fields:

FieldPurposeSource
usernameUser who performed actionAuditableEvent::username()
areaSystem module affectedAuditableEvent::area()
change_typeClassification (create/update/delete)AuditableEvent::changeType()
actionSpecific action nameAuditableEvent::action()
change_locationAffected entity identifierAuditableEvent::changeLocation()
value_beforePrevious value (JSON or text)AuditableEvent::beforeValue()
value_afterNew value (JSON or text)AuditableEvent::afterValue()
site_nameSite where change occurredAuditableEvent::siteName()

3.3 Error Code Entity Design

Error Level Enumeration:

ValueLevelDescription
1WellError affects entire well
2MixError affects entire mix
3TargetError affects specific target

Error Type Enumeration:

ValueTypeMaps to Outcome
0Label ErrorError
1ErrorError
2WarningWarning
3InformationInformation
4Associate Control ErrorError

3.4 Error Code Categories

The error code taxonomy is organized by generation source:

CategoryPrefix/PatternExample Codes
Westgard QCWG*WG12S_HIGH_WELL, WG7T_LOW_TARGET
Control CheckFAILED_POS*, NEC_*FAILED_POS_WELL, NEC_FAILURE_TARGET
InhibitionINH*, IC*, BICQUAL*INH_WELL, ICQUAL_RPT
QuantificationRQUANT*, QUANT_*RQUANT_LIMITS_MISSED, BAD_R2
CT/ThresholdADJ_*, THRESHOLD_*ADJ_CT, THRESHOLD_WRONG
ClassificationCLSDISC*, CTDISC*CLSDISC_WELL, CONTROL_CLSDISC_TARGET
BacteremiaBACT_*, *_BACT*BACT_NO_MATCHING_SAMPLE, LOW_BACT
Fluorescence*_FL*, SIGMOID*UNEXPECTED_FL, INCORRECT_SIGMOID
ParsingINVALID_*, *_UNKNOWNINVALID_PASSIVE_READINGS, THERMOCYCLER_UNKNOWN
AnalysisUNKNOWN_*, *_MISSINGUNKNOWN_MIX, ACCESSION_MISSING

3.5 Seed vs Custom Codes

CategoryDescriptionExamples
Seed CodesSystem-defined, rule implementations hardcodedWG12S_HIGH_WELL, FAILED_POS_TARGET
Custom CodesClient-defined for combined outcomes/resolutionsClient-specific workflow codes

3.6 Naming Convention

Error codes follow the pattern: {CONDITION}_{DIRECTION}_{LEVEL}

ComponentValuesExample
CONDITIONWG12S, WG13S, INH, BCC, etc.WG12S
DIRECTIONHIGH, LOW, (none)HIGH
LEVELWELL, TARGET, MIXWELL

Result: WG12S_HIGH_WELL

3.7 Generation Formulas

RuleTrigger Condition
WG12Sdelta = ABS(control.ct - mean); delta > 2 * SD
WG13Sdelta > 3 * SD
WG22S2 consecutive CTs > 2 SD, same direction
WG7T7 consecutive CTs trending same direction
BCCControl CT outside configured min/max limits
INHInternal control indicates sample inhibition

3.8 Processing Control Flow

3.9 Error Resolution Workflow

  1. GENERATED - Rule outputs error code, assigned to well/target/mix
  2. DISPLAYED - Run File Report shows error code and message
  3. RESOLUTION APPLIED - User selects configured resolution action
  4. RE-ANALYSIS - System re-runs rules, skipping those specified in resolution
  5. FINAL STATE - Error resolved or persisted based on re-analysis

4. Interface Design

4.1 APIs Provided

Audit APIs:

EndpointMethodPurposeREQ Trace
/api/auditsGETList paginated audit entriesREQ-AUDIT-001
/api/audit-exportsPOSTInitiate export jobREQ-AUDIT-003
/api/audit-filter-options/actionsGETDistinct actionsREQ-AUDIT-002
/api/audit-filter-options/areasGETDistinct areasREQ-AUDIT-002
/api/audit-filter-options/change-typesGETDistinct change typesREQ-AUDIT-002
/api/audit-filter-options/usernamesGETDistinct usernamesREQ-AUDIT-002
/api/audit-filter-options/created-at-rangeGETDate range boundsREQ-AUDIT-002
/api/audit-filter-options/site-namesGETAccessible site namesREQ-AUDIT-004

Error Code APIs:

EndpointMethodPurposeREQ Trace
/api/error-codesGETList all error codesREQ-ERRORCODES-*
/api/error-codesPOSTCreate error codesREQ-ERRORCODES-*
/api/error-codesPUTUpdate error codesREQ-ERRORCODES-*

4.2 Events Consumed

EventSourcePurpose
* implements AuditableEventAll domainsRecord change to audit trail

AuditableEvent Interface Contract:

interface AuditableEvent {
public function username(): string;
public function area(): string;
public function changeType(): string;
public function action(): string;
public function changeLocation(): ?string;
public function beforeValue(): ?string;
public function afterValue(): ?string;
public function siteName(): ?string;
}

5. Behavioral Design

5.1 Audit Event Capture Flow

Algorithm: Capture Audit Event

Inputs:
- event: AuditableEvent implementation

Outputs:
- audit: Persisted Audit record

Assumptions:
- Audit database connection is available
- Event contains valid data

Steps:
1. LogIntoDatabase listener receives event
2. Extract audit fields from event interface methods
3. Create Audit record on audit database connection
4. Record is immutable (no update/delete methods exposed)

Notes:
- Failures logged but do not roll back originating transaction
- Audit storage is fire-and-forget for performance

5.2 Audit Export Flow

Algorithm: Export Audit Data

Inputs:
- filters: Active filter criteria
- user: Requesting user

Outputs:
- email: Email with download link(s)

Assumptions:
- User has export permissions
- S3 and SES are accessible

Steps:
1. Queue AuditExportJob with filter data and user
2. Job queries audit records matching filters
3. Chunk results by CHUNK_SIZE (25,000 records)
4. For each chunk:
a. Generate Excel file
b. Upload to S3
c. Generate temporary URL (7-day expiry)
5. Send email with all download links
6. Large exports produce multiple Excel files

Notes:
- Export includes all columns regardless of UI visibility
- Timeout: 900 seconds (15 minutes)
- Link expiry: 7 days

5.3 Error Code Assignment Flow

Algorithm: Assign Error Code to Target

Inputs:
- error_code: String identifier (e.g., "WG12S_HIGH_WELL")
- level: Well | Target | Mix
- target: RunTarget being analyzed

Outputs:
- void (error code added to target's error_codes array)

Assumptions:
- Error code exists in configuration
- Rule has authority to assign this code

Steps:
1. Rule execution detects condition
2. Rule looks up error code by identifier
3. If error_code.does_prevent_analyse:
a. Mark target as blocked
b. Prevent further rule processing
4. Add error_code to target's error_codes collection
5. Persist to run_targets.error_codes JSON column

Notes:
- Multiple error codes can be assigned to same target
- Blocking errors halt processing; non-blocking continue

6. Error Handling

6.1 Audit Error Handling

ConditionDetectionResponseUser Impact
Audit DB unavailableConnection exceptionLog error, continue operationAudit not recorded (temporary)
Export job failsJob exception handlerLog error, no email sentUser must retry
Email delivery failsSES errorLog error, file still in S3Manual retrieval possible

6.2 Error Code Error Handling

ConditionDetectionResponseUser Impact
Unknown error codeLookup returns nullLog warning, skip assignmentError not shown on report
Duplicate error codeUnique constraintReject creation, return errorMust use different code
Site mismatchQuery returns empty404 responseError code not found

7. Configuration

7.1 Audit Configuration

SettingLocationDefaultEffectREQ Trace
DB_AUDIT_CONNECTION.envmysql_auditAudit database connection nameREQ-AUDIT-001
DB_AUDIT_HOST.env127.0.0.1Audit database hostREQ-AUDIT-001
DB_AUDIT_DATABASE.envvapor_auditAudit database nameREQ-AUDIT-001
per_pageRequest param10Audit entries per pageREQ-AUDIT-001

See Configuration Reference for full list.

7.2 Error Code Entity Properties

PropertyTypeEffect
error_codestringUnique identifier (e.g., WG12S_HIGH_WELL)
error_messagestringHuman-readable description
error_levelenumWell (1), Mix (2), Target (3)
error_typeenumLabel Error, Error, Warning, Information, Associate Control Error
does_prevent_analyseboolBlocks further processing when true
is_inhibitedboolMarks as inhibition-related
causes_missing_mixesboolMarks as missing mix error
lims_statusstringOverride LIMS status when assigned

8. Implementation Mapping

8.1 Code Locations

ComponentTypePath
AuditModelapp/Audit.php
AuditableEventInterfaceapp/Events/AuditableEvent.php
LogIntoDatabaseListenerapp/Listeners/LogIntoDatabase.php
AuditsControllerControllerapp/Http/Controllers/AuditsController.php
AuditExportsControllerControllerapp/Http/Controllers/AuditExportsController.php
AuditExportJobJobapp/Jobs/AuditExportJob.php
AuditFiltersFilterapp/Filters/AuditFilters.php
AuditQueryBuilderQueryBuilderapp/QueryBuilders/AuditQueryBuilder.php
GetAuditsActionActionapp/Actions/Audits/GetAuditsAction.php
AuditExportExportapp/Exports/AuditExport.php
ErrorCodeModelapp/ErrorCode.php
ErrorCodesRelationRelationapp/ErrorCodesRelation.php
ErrorCodesControllerControllerapp/Http/Controllers/ErrorCodesController.php
GetErrorCodesActionActionapp/Actions/KitConfigurations/ErrorCodes/GetErrorCodesAction.php
ErrorCodeQueryBuilderQueryBuilderapp/QueryBuilders/ErrorCodeQueryBuilder.php

8.2 Requirement Traceability

REQ IDDesign SectionPrimary Code
REQ-AUDIT-001§3.2, §5.1Audit, AuditsController, AuditableEvent
REQ-AUDIT-002§4.1AuditFilters, AuditFilterOptions/*
REQ-AUDIT-003§5.2AuditExportJob, AuditExportsController
REQ-AUDIT-004§2.3AuditQueryBuilder, AuditFilters::siteNames
REQ-ERRORCODES-001§3.3, §3.4ErrorCode, Westgard rules
REQ-ERRORCODES-002§3.3, §3.4ErrorCode, BCC/BNC rules
REQ-ERRORCODES-003§3.3, §3.4ErrorCode, INH/IC rules
REQ-ERRORCODES-004§3.3, §3.4ErrorCode, RQUAL/RQUANT rules
REQ-ERRORCODES-005§3.3, §3.4ErrorCode, ADJ/THRESHOLD rules
REQ-ERRORCODES-006§3.3, §3.4ErrorCode, WDCLS/WDCT rules
REQ-ERRORCODES-007§3.3, §3.4ErrorCode, RBACT/SBCHECK rules
REQ-ERRORCODES-008§3.3, §3.4ErrorCode, FL/SIGMOID rules
REQ-ERRORCODES-009§3.3, §3.4ErrorCode, AMB/INCONCLUSIVE rules
REQ-ERRORCODES-010§3.3, §5.3ErrorCode, Parser validation
REQ-ERRORCODES-011§3.3, §5.3ErrorCode, Analyzer validation

9. Design Decisions

DecisionRationaleAlternatives Considered
Separate audit databaseImmutability guarantee, compliance isolationSame DB (rejected: accidental deletes possible)
Event-driven audit captureDecoupled from domain logic, consistent interfaceDirect inserts (rejected: coupling, inconsistency)
Fire-and-forget audit writesPerformance, don't block business operationsSync writes (rejected: latency impact)
Chunked export (25K records)Memory management, multiple file strategySingle file (rejected: memory issues), streaming (rejected: complexity)
Error code as string identifierRule implementations hardcode identifiersInteger IDs (rejected: not human-readable in rules)
Soft delete for error codesPreserve historical data integrityHard delete (rejected: breaks existing references)

10. Performance Considerations

ScenarioConcernMitigation
Large audit tableQuery performanceIndex on created_at, site_name; pagination
Export of full auditMemory, timeoutChunked processing, 15-minute timeout
Many error codes per targetJSON column sizeArray storage, not normalized
Error code lookup in rulesQuery per rulePreload all error codes at analysis start

DocumentRelevant Sections
SRS: audit-log.mdRequirements source for audit trail
SRS: errorcodes.mdRequirements source for error codes
SDS: ArchitectureAurora audit database, SES integration
SDS: Security ArchitectureSite-based access control
SDS: Data ArchitectureAudit and error code schemas
SDS: Rules EngineError code generation during analysis
SDS: KITCFG DomainError code management, error resolutions
SDS: Configuration ReferenceAudit and error code configuration