Skip to main content
Version: 3.0.1

Software Design Specification: Cross-Cutting Concerns

Document Type: System-Level (Tier 1) Status: Draft Last Updated: 2026-01-25


1. Purpose

This document describes infrastructure concerns that span all domains in the PCR Analysis System. Cross-cutting concerns are shared services and patterns used throughout the application but not owned by any single domain.

Scope:

  • Logging architecture
  • Error handling patterns
  • Configuration loading
  • Caching strategy
  • Job queue architecture
  • Database connectivity patterns

Constraint: This document does not satisfy requirements directly. It provides context for how domains implement their functionality.


2. Logging Architecture

2.1 Overview

The system uses Laravel's logging abstraction backed by Monolog. Logs are centralized through a configurable channel stack.

2.2 Log Channels

ChannelDriverPurposeDefault Level
stackstackPrimary channel; aggregates othersdebug
singlesingleSingle file outputdebug
dailydailyRotating daily logs (14-day retention)debug
slackslackCritical alerts to Slack webhookcritical
stderrmonologContainer/Lambda stderr outputdebug
syslogsyslogSystem logging integrationdebug
nullmonologDisabled logging (testing)-

Configuration: config/logging.php

2.3 Log Levels

Standard PSR-3 log levels apply:

LevelUsage
emergencySystem unusable
criticalCritical conditions (triggers Slack)
errorRuntime errors
warningExceptional occurrences that are not errors
infoInteresting events (login, file import)
debugDetailed debug information

2.4 What Gets Logged

CategoryLog LevelExamples
Authentication eventsinfoLogin success/failure, session termination
Job failureserrorQueue job exceptions
Database errorserrorConnection failures, query errors
API errorserror/warningValidation failures, authorization denials
Sentry integrationvariesAll errors forwarded to Sentry with breadcrumbs

2.5 External Error Tracking (Sentry)

Sentry captures exceptions with contextual breadcrumbs.

Breadcrumb Categories:

  • Laravel logs
  • SQL queries (with bindings)
  • Queue job information
  • Artisan command information

Configuration: config/sentry.php

Privacy: send_default_pii is disabled; no personally identifiable information is transmitted.


3. Error Handling

3.1 Exception Hierarchy

3.2 Application Exceptions

ExceptionPurposeUser-Facing
ApplicationDatabaseNotReadyExceptionAurora Serverless cold start; database wakingYes (retry prompt)
AuditDatabaseNotReadyExceptionAudit database unavailableYes (retry prompt)
DuplicateRunImportExceptionRun file already importedYes (error message)
ThermocyclerFieldMissingExceptionRequired thermocycler data missing from run fileYes (validation error)

3.3 Global Exception Handler

Location: app/Exceptions/Handler.php

Handling Rules:

Exception TypeWeb ResponseAPI Response
TokenMismatchExceptionRedirect to login with session timeout message-
AuthorizationExceptionRedirect to unauthorized page403 JSON {"message": "unauthorized"}
All othersLaravel default (error page or debug)Laravel default (JSON error)

3.4 Sensitive Input Protection

The following inputs are never flashed to session on validation errors:

  • password
  • password_confirmation

4. Configuration Loading

4.1 Configuration Hierarchy

4.2 Environment Variables

Primary configuration source. All sensitive values (credentials, API keys) are stored in environment variables.

Key Environment Variables:

VariablePurpose
APP_ENVEnvironment (production, staging, local)
APP_DEBUGDebug mode toggle
APP_KEYEncryption key
DB_*Database connection
DB_AUDIT_*Audit database connection
REDIS_*Redis/ElastiCache connection
AWS_*AWS credentials and region
SENTRY_DSNSentry error tracking

4.3 Laravel Configuration Files

Location: config/*.php

Key Files:

FilePurpose
app.phpApplication name, version, timezone, encryption
database.phpDatabase connections (application + audit)
cache.phpCache driver and store configuration
queue.phpQueue connections and failed job handling
logging.phpLog channels and levels
sentry.phpError tracking configuration

4.4 Database Configuration (client_configurations)

Runtime-configurable settings stored in client_configurations table as key-value pairs.

Pattern:

  • Name: Configuration key
  • Value: Configuration value

Usage: Domain-specific settings that vary per client/site without code deployment.

See SDS: Reference - Configuration for full configuration reference.


5. Caching Strategy

5.1 Cache Architecture

5.2 Cache Stores

StoreDriverUse Case
redisredisProduction caching (ElastiCache)
filefileLocal development
arrayarrayTesting (no persistence)
databasedatabaseAlternative persistent cache
dynamodbdynamodbAWS-native caching option

Default: file (overridden by CACHE_DRIVER environment variable)

Configuration: config/cache.php

5.3 Cache Key Prefix

All cache keys are prefixed with {APP_NAME}_cache to prevent collisions when sharing cache infrastructure.

5.4 What Gets Cached

Data TypeCache LocationTTL
Session dataDynamoDB (Vapor default)Session lifetime
Computation resultsRedisRequest-scoped
Configuration lookupsRedisVaries by domain

Note: Authoritative data lives in Aurora MySQL. Cache contains derived data that can be regenerated.


6. Job Queue Architecture

6.1 Overview

The system uses Laravel's queue abstraction for asynchronous processing. Jobs are dispatched to queues and processed by workers (Lambda in production, sync in development).

6.2 Queue Connections

ConnectionDriverUse Case
syncsyncDevelopment (immediate execution)
databasedatabaseLocal async with database backing
sqssqsProduction (Amazon SQS)
redisredisAlternative production option

Default: sync (overridden by QUEUE_CONNECTION environment variable)

Configuration: config/queue.php

6.3 Job Categories

6.4 Job Inventory

JobPurposeTimeoutRetry
RunAnalyseJobRun file analysis/reanalysisDefaultWithoutOverlapping
RunDataParseJobParse imported run fileDefaultDefault
RunStoreJobPersist run to databaseDefaultDefault
RunResultExportJobExport results to LIMSDefaultDefault
AuditExportJobGenerate audit export file900s1
RunDeleteJobDelete run fileDefaultDefault
ConfigDataImportJobImport configuration dataDefaultDefault

6.5 Job Patterns

WithoutOverlapping Middleware:

Jobs like RunAnalyseJob use WithoutOverlapping middleware to prevent concurrent processing of the same run.

public function middleware(): array
{
return [
(new WithoutOverlapping)->releaseAfter(3),
];
}

Transaction Wrapping:

Export jobs wrap operations in database transactions with rollback on failure.

Progress Broadcasting:

Long-running jobs broadcast progress via Pusher for real-time UI updates.

6.6 Failed Jobs

Failed jobs are logged to the failed_jobs table with:

  • Connection and queue name
  • Payload (serialized job data)
  • Exception message and stack trace
  • Failed timestamp

Configuration: config/queue.phpfailed


7. Database Connectivity

7.1 Dual Database Architecture

The system uses separate databases for application data and audit logs.

7.2 Connection Configuration

ConnectionPurposeDatabase
mysqlApplication data (runs, wells, config)DB_DATABASE
mysql_auditAudit trail dataDB_AUDIT_DATABASE
mysql_testTesting databaseDB_DATABASE_TEST

Configuration: config/database.php

7.3 Cold Start Handling

Aurora Serverless databases may be paused when idle. The application handles cold starts with:

  1. ApplicationDatabaseNotReadyException - Application database waking
  2. AuditDatabaseNotReadyException - Audit database waking

User Experience: Retry prompt displayed; database typically available within seconds.

Pooling Configuration: app.database_pooling_time = 5 seconds

7.4 Redis Configuration

Redis (ElastiCache in production) provides:

  • Default connection for general use
  • Cache connection for caching layer

Prefix: {APP_NAME}_database_ prevents key collisions


8. Common Utilities

8.1 Service Providers

ProviderPurpose
AppServiceProviderApplication bindings and boot logic
AuthServiceProviderAuthentication and authorization
BroadcastServiceProviderPusher/WebSocket channels
EventServiceProviderEvent-listener registration
RouteServiceProviderRoute loading and configuration
VaporUiServiceProviderLaravel Vapor dashboard
MicrosoftGraphServiceProviderSharePoint integration

8.2 Facade Aliases

Standard Laravel facades are aliased for convenience:

  • Cache, Config, DB, Log, Mail, Queue, Storage

8.3 Encryption

Algorithm: AES-256-CBC

Key: APP_KEY environment variable (32-character random string)

All sensitive data at rest uses Laravel's encryption service.


9. Non-Functional Requirements Coverage

This cross-cutting document provides implementation context for non-functional requirements that span all domains.

REQ IDTitleRelevant SectionImplementation Notes
REQ-NFR-001Page Load Time§2 Logging, §3 Error Handling, §5 CachingInfrastructure optimization via CDN, caching, and async job processing
REQ-NFR-002Reanalysis Operation Time§6 Job QueueRunAnalyseJob with progress broadcasting via Pusher
REQ-NFR-003Concurrent User Capacity§5 Caching, §6 Job Queue, §7 DatabaseAurora Serverless auto-scaling, ElastiCache, SQS queues
REQ-NFR-004Browser Resize HandlingN/AFrontend concern (Vue.js responsive CSS)
REQ-NFR-005Zoom Level UsabilityN/AFrontend concern (Vue.js responsive CSS)

Note: REQ-NFR-004 and REQ-NFR-005 are primarily frontend/CSS concerns with no backend implementation anchors. These requirements are satisfied through Vue.js component design and Tailwind CSS responsive utilities.


DocumentRelevance
SDS: Architecture OverviewSystem architecture context
SDS: Security ArchitectureAuthentication, authorization
SDS: Reference - ConfigurationFull configuration reference
SDD: ArchitectureLegacy architecture documentation
SDD: ConfigurationLegacy configuration documentation