Settings Domain Design
Document Type: Domain Design (Tier 2) Domain: SETTINGS (SITE, CLIENTCFG, USERSET) Domain Character: Configuration-heavy SRS References: site.md, client-config.md, user-settings.md Status: Draft Last Updated: 2026-01-25
1. Overview
1.1 Purpose
The Settings domain provides centralized management of organizational, client-level, and user-level configuration across the PCR Analysis System. It implements a three-tier settings hierarchy with distinct ownership, precedence, and scoping rules:
| Tier | Entity | Scope | Managed By |
|---|---|---|---|
| Site | Organizational unit | Storage paths, multi-site mode | Admin, Super Admin |
| Client Configuration | System behavior | Feature toggles, data handling | Super User |
| User Settings | Display preferences | Timezone, date/time format, display name | Authenticated user |
This domain is characterized by:
- CRUD-heavy operations with validation at each tier
- Precedence hierarchy: Site → Client → User (higher tiers constrain lower)
- Multi-site data isolation via site-scoped queries
- Import/export functionality for client configuration bulk transfer
- Immediate application of settings upon save (no restart required)
1.2 Requirements Covered
| REQ ID | Title | Tier |
|---|---|---|
| REQ-SITE-001 | Provision Storage on Site Creation | Site |
| REQ-SITE-002 | Configure S3 Structure Preservation | Site |
| REQ-SITE-003 | Specify Custom S3 Folder Name | Site |
| REQ-SITE-004 | Modify Custom S3 Folder Name | Site |
| REQ-SITE-005 | Enforce Multi-site Mode Restrictions | Site |
| REQ-CLIENTCFG-001 | View and Edit Client Configuration Settings | Client |
| REQ-CLIENTCFG-002 | Export Client Configuration | Client |
| REQ-CLIENTCFG-003 | Import Client Configuration | Client |
| REQ-USERSET-001 | Manage User Display Preferences | User |
| REQ-USERSET-002 | Validate Display Name Uniqueness | User |
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 validation rules documented in the SRS acceptance criteria.
1.4 Dependencies
| Direction | Domain/Component | Purpose |
|---|---|---|
| Provides to | FILEIMPORT | Site-scoped storage paths |
| LIMS Export | S3 folder structure for exports | |
| ANALYTICS | Feature toggles, analysis options | |
| REPORTS | Display options, export preferences | |
| Global UI | User timezone, date/time format, feature visibility | |
| Consumes | Amazon S3 | Storage folder creation |
| AWS Cognito | User identity for preferences |
2. Component Architecture
2.1 Component Diagram
2.2 Component Responsibilities
| Component | Type | Responsibility | REQ Trace |
|---|---|---|---|
SitesController | Controller | Site CRUD operations | REQ-SITE-001, 003, 004 |
SitesEnableController | Controller | Enable site | REQ-SITE-005 |
SitesDisableController | Controller | Disable site | REQ-SITE-005 |
PreserveS3StructureForFirstSiteController | Controller | Toggle S3 preservation | REQ-SITE-002 |
UseMultipleSitesFeatureController | Controller | Toggle multi-site mode | REQ-SITE-005 |
StoreSiteAction | Action | Create site with storage | REQ-SITE-001, 003 |
UpdateSiteAction | Action | Update site properties | REQ-SITE-004 |
CreateStorageForSiteAction | Action | Provision S3 folders | REQ-SITE-001, 003, 004 |
ClientConfigurationsController | Controller | Configuration CRUD | REQ-CLIENTCFG-001 |
ConfigDataController | Controller | Import/export orchestration | REQ-CLIENTCFG-002, 003 |
GetClientConfigurationsAction | Action | Retrieve with computed disabled state | REQ-CLIENTCFG-001 |
UpdateClientConfigurationAction | Action | Update with cascade handling | REQ-CLIENTCFG-001 |
ClientConfigurationEnableStateChecker | Action | Runtime dependency evaluation | REQ-CLIENTCFG-001 |
AuthUserController | Controller | User profile and settings | REQ-USERSET-001 |
UpdateAuthUserAction | Action | Persist user preferences | REQ-USERSET-001, 002 |
2.3 Architectural Patterns
Pattern: Three-Tier Settings Hierarchy
Settings cascade from site to client to user level with clear precedence:
Site Settings (organizational boundaries)
├── Multi-site mode enabled/disabled
├── S3 storage paths
└── Site enable/disable state
│
▼
Client Configuration (system behavior)
├── Feature toggles (affect all users)
├── Data handling rules
└── Export preferences
│
▼
User Settings (personal preferences)
├── Timezone
├── Date/time format
└── Display name
Pattern: Site-Scoped Queries
All configuration queries are scoped by site for multi-site clients:
// Client configurations are site-scoped
ClientConfiguration::where('site_id', $currentSite->id)->get();
// Features are site-scoped
Feature::where('site_id', $currentSite->id)->get();
Pattern: Configuration Dependency Cascade
Client configurations have dependencies that disable related settings:
Inherit Run Date = ENABLED
└── Westgard Second Priority Ordering = DISABLED (greyed out)
Prevent Drag/Drop Import = ENABLED
└── Upload Button Import = DISABLED
Pattern: Immediate Application
All settings take effect immediately upon save without requiring application restart.
3. Data Design
3.1 Entity Ownership
This domain owns the following entities:
| Entity | Table | Purpose | Key Relationships |
|---|---|---|---|
Site | sites | Organizational unit | → client_configurations, features, users |
ClientConfiguration | client_configurations | System settings | → site |
Feature | features | Feature toggles | → site |
User.settings | users (JSON column) | User preferences | → user |
User.display_name | users | User identifier | → user |
See Database Reference for full schema.
3.2 Entity Relationship Overview
3.3 Configuration Types
Client Configuration Types:
| Type | Value | Description | Example |
|---|---|---|---|
| BOOLEAN | 1 | Toggle switch | fallback_shared_controls_enabled |
| TEXT | 2 | Text input | N/A (not currently used) |
| OPTIONS | 3 | Dropdown select | lims_export_location |
| MULTISELECT | 4 | Multi-select | allowed_characters_in_accessions |
Configuration Groups:
| Group | Order | Examples |
|---|---|---|
| Login/User Management Options | 1 | User type restrictions |
| Import/Data Options | 2 | Drag/drop, unknown mix handling |
| Export Options | 3 | LIMS location, CSV settings |
| Display Options | 4 | Comment count, hyperlinks |
| Edit/Manage Results Options | 5 | Role priority resolution |
| Westgard Options | 6 | Priority ordering |
3.4 Setting Precedence
When multi-site mode is disabled, certain settings are constrained:
| Condition | Constrained Settings |
|---|---|
| Multi-site mode disabled | Site creation, site editing, S3 preservation toggle |
| Inherit Run Date enabled | Westgard second priority ordering |
| Prevent drag/drop enabled | Upload button import |
4. Interface Design
4.1 APIs Provided
Site Management:
| Endpoint | Method | Purpose | REQ Trace |
|---|---|---|---|
/api/sites | GET/POST | List/create sites | REQ-SITE-001, 003 |
/api/sites/{id} | PUT | Update site | REQ-SITE-004 |
/api/sites/{id}/enable | POST | Enable site | REQ-SITE-005 |
/api/sites/{id}/disable | POST | Disable site | REQ-SITE-005 |
/api/preserve-s3-structure-for-first-site | PUT | Toggle S3 preservation | REQ-SITE-002 |
/api/use-multiple-sites | PUT | Toggle multi-site mode | REQ-SITE-005 |
/api/auth-user/change-logged-in-site | PUT | Switch active site | REQ-SITE-005 |
/api/auth-user/visible-sites | GET | List user's visible sites | REQ-SITE-005 |
Client Configuration:
| Endpoint | Method | Purpose | REQ Trace |
|---|---|---|---|
/api/client-configurations | GET | List all configurations | REQ-CLIENTCFG-001 |
/api/client-configurations/{id} | PUT | Update configuration | REQ-CLIENTCFG-001 |
/api/client-configuration-settings/{name} | GET | Get setting by name | REQ-CLIENTCFG-001 |
/api/config-data/export | GET | Export all configuration | REQ-CLIENTCFG-002 |
/api/config-data/import | POST | Import configuration | REQ-CLIENTCFG-003 |
User Settings:
| Endpoint | Method | Purpose | REQ Trace |
|---|---|---|---|
/api/auth-user | GET | Get current user with settings | REQ-USERSET-001 |
/api/auth-user | PUT | Update user settings | REQ-USERSET-001, 002 |
4.2 Events Published
| Event | Payload | Purpose | Listener |
|---|---|---|---|
SiteCreated | site_id, user_id | Audit trail | LogIntoDatabase |
SiteEnabled | site_id, user_id | Audit trail | LogIntoDatabase |
SiteDisabled | site_id, user_id | Audit trail | LogIntoDatabase |
ClientConfigurationUpdated | config_name, old_value, new_value | Audit trail | LogIntoDatabase |
5. Behavioral Design
5.1 Site Creation Flow
Algorithm: Create Site with Storage
Inputs:
- name: Site name
- custom_s3_folder_name: Optional custom folder name
- authUser: Authenticated user
Outputs:
- site: Created Site entity
Assumptions:
- Multi-site mode is enabled
- User has Admin role or higher
- S3 is accessible
Steps:
1. Begin database transaction
2. Create Site record:
a. Set name
b. Set custom_s3_folder_name (nullable)
3. Attach site to system user (for system operations)
4. Create storage for site (via CreateStorageForSiteAction):
a. Determine storage directory based on site settings
b. Create LIMS_Reports folder
c. Create Runs/Completed_files folder
5. Copy default client configurations from current site
6. Copy default features from current site
7. Commit transaction
8. Return created site
Notes:
- Transaction ensures atomicity
- Storage creation failure rolls back entire operation
- Default configurations inherited from user's current site
5.2 S3 Storage Path Resolution
Algorithm: Resolve Site Storage Directory
Inputs:
- site: Site entity
- config: Configuration repository
Outputs:
- path: Storage directory path (may be empty for root-level)
Steps:
1. If site is NOT the default (first) site:
a. Return custom_s3_folder_name if set, else site name
2. If site IS the default site:
a. If multi-site feature disabled: Return "" (root-level)
b. If preserve_s3_structure enabled: Return "" (root-level)
c. Else: Return custom_s3_folder_name if set, else site name
Notes:
- Empty string means use root-level folders: <env>/LIMS_Export, <env>/Runs
- Non-empty means use site-specific: <env>/<path>/LIMS_Export, <env>/<path>/Runs
- Changing toggle does NOT migrate existing files
5.3 Client Configuration Update with Dependencies
Algorithm: Update Client Configuration
Inputs:
- configuration: ClientConfiguration entity
- value: New value
Outputs:
- void (side effects on configuration)
Assumptions:
- User has Super User role
- Value is valid for configuration type
Steps:
1. Cast value based on configuration type:
a. BOOLEAN: Convert to 'TRUE'/'FALSE' string
b. MULTISELECT: JSON encode array
c. OPTIONS/TEXT: Use as-is
2. Persist new value
3. Get affected configurations (if any):
a. Look up dependency chain from AffectedClientConfigurations
b. If parent config affects this one, mark as disabled in response
4. For cascade effects:
a. Inherit Run Date → disables Westgard second priority
b. Prevent drag/drop → disables upload button
Notes:
- Dependencies are enforced at UI level (disabled state)
- No automatic value changes on cascade
- All configurations site-scoped
5.4 User Settings Update
Algorithm: Update User Display Preferences
Inputs:
- user: Authenticated User entity
- details: Collection with settings, display_name
Outputs:
- user: Updated User entity
Assumptions:
- User is authenticated
- Display name (if provided) meets length constraint
Steps:
1. Extract settings array (timezone, date_format, time_format)
2. Extract display_name (optional)
3. Validate display_name:
a. Check max length (40 characters)
b. Check uniqueness (if implementing REQ-USERSET-002)
4. Force-fill user record:
a. settings = JSON of preferences
b. display_name = provided value
5. Save user
6. Return updated user
Notes:
- Settings are stored as JSON in user record
- Display name uniqueness validation gap in current implementation
- Timezone applied at frontend display time
6. Error Handling
| Condition | Detection | Response | User Impact |
|---|---|---|---|
| S3 folder creation fails | Storage API exception | Roll back site creation | Site not created, error message |
| Configuration validation fails | Type/options mismatch | Reject update | Setting not saved, error shown |
| Display name too long | Validation rule | Reject update | Preference not saved, error shown |
| Display name duplicate | Uniqueness check | Reject update | Preference not saved, error shown |
| Multi-site mode disabled | Feature check | Disable site management UI | Actions blocked, tooltip explains |
| S3 folder name conflict | Path collision | Allow (uses existing folder) | No error, uses existing |
7. Configuration
This domain manages configuration for other domains. Meta-configuration for its own behavior:
| Setting | Location | Default | Effect | REQ Trace |
|---|---|---|---|---|
use_multiple_sites | Feature toggle | false | Enables multi-site mode | REQ-SITE-005 |
preserve_s3_structure_first_site | Client configuration | true | Root-level folders for first site | REQ-SITE-002 |
User Settings Defaults:
| Setting | Default | Source |
|---|---|---|
timezone | America/Chicago | User::defaultSettings() |
date_format | MM/DD/YYYY | User::defaultSettings() |
time_format | 12-hour | User::defaultSettings() |
See Configuration Reference for full list.
8. Implementation Mapping
8.1 Code Locations
Site Management:
| Component | Type | Path |
|---|---|---|
| Site | Model | app/Site.php |
| SitesController | Controller | app/Http/Controllers/SitesController.php |
| SitesEnableController | Controller | app/Http/Controllers/SitesEnableController.php |
| SitesDisableController | Controller | app/Http/Controllers/SitesDisableController.php |
| PreserveS3StructureForFirstSiteController | Controller | app/Http/Controllers/PreserveS3StructureForFirstSiteController.php |
| UseMultipleSitesFeatureController | Controller | app/Http/Controllers/UseMultipleSitesFeatureController.php |
| StoreSiteAction | Action | app/Actions/Sites/StoreSiteAction.php |
| UpdateSiteAction | Action | app/Actions/Sites/UpdateSiteAction.php |
| CreateStorageForSiteAction | Action | app/Actions/Sites/CreateStorageForSiteAction.php |
| EnableSiteAction | Action | app/Actions/Sites/EnableSiteAction.php |
| DisableSiteAction | Action | app/Actions/Sites/DisableSiteAction.php |
| ToggleUseMultipleSitesFeatureAction | Action | app/Actions/Sites/ToggleUseMultipleSitesFeatureAction.php |
| UpdatePreserveS3StructureForFirstSiteAction | Action | app/Actions/Sites/UpdatePreserveS3StructureForFirstSiteAction.php |
Client Configuration:
| Component | Type | Path |
|---|---|---|
| ClientConfiguration | Model | app/ClientConfiguration.php |
| ClientConfigurationsController | Controller | app/Http/Controllers/ClientConfigurationsController.php |
| ClientConfigurationSettingsController | Controller | app/Http/Controllers/ClientConfigurationSettingsController.php |
| ConfigDataController | Controller | app/Http/Controllers/ConfigDataController.php |
| UpdateClientConfigurationAction | Action | app/Actions/UpdateClientConfigurationAction.php |
| GetClientConfigurationsAction | Action | app/Actions/ClientConfigurations/GetClientConfigurationsAction.php |
| ClientConfigurationEnableStateChecker | Action | app/Actions/ClientConfigurations/ClientConfigurationEnableStateChecker.php |
| AffectedClientConfigurations | Service | app/ClientConfigurations/AffectedClientConfigurations.php |
| ClientConfigurationParentService | Service | app/ClientConfigurations/ClientConfigurationParentService.php |
| ClientConfigurationsExport | Export | app/Exports/Config/ClientConfigurationsExport.php |
| ClientConfigurationsImportSheet | Import | app/Imports/Sheets/ClientConfigurationsImportSheet.php |
| ClientConfigurationValidator | Validator | app/Imports/Sheets/Support/Validators/ClientConfigurations/ClientConfigurationValidator.php |
User Settings:
| Component | Type | Path |
|---|---|---|
| AuthUserController | Controller | app/Http/Controllers/AuthUserController.php |
| UpdateAuthUserAction | Action | app/Actions/Users/UpdateAuthUserAction.php |
| UpdateAuthUserRequest | Request | app/Http/Requests/UpdateAuthUserRequest.php |
| ChangeLoggedInSiteController | Controller | app/Http/Controllers/AuthUser/ChangeLoggedInSiteController.php |
| VisibleSitesController | Controller | app/Http/Controllers/AuthUser/VisibleSitesController.php |
| UpdateAuthUserLoggedInSiteAction | Action | app/Actions/AuthUser/UpdateAuthUserLoggedInSiteAction.php |
8.2 Requirement Traceability
| REQ ID | Design Section | Primary Code |
|---|---|---|
| REQ-SITE-001 | §5.1, §5.2 | StoreSiteAction, CreateStorageForSiteAction |
| REQ-SITE-002 | §5.2 | Site::getStorageDirectory(), UpdatePreserveS3StructureForFirstSiteAction |
| REQ-SITE-003 | §5.1 | StoreSiteAction, CreateStorageForSiteAction |
| REQ-SITE-004 | §5.2 | UpdateSiteAction, CreateStorageForSiteAction |
| REQ-SITE-005 | §5.2 | ToggleUseMultipleSitesFeatureAction, EnableSiteAction, DisableSiteAction |
| REQ-CLIENTCFG-001 | §5.3 | ClientConfigurationsController, UpdateClientConfigurationAction |
| REQ-CLIENTCFG-002 | §4.1 | ConfigDataController, ClientConfigurationsExport |
| REQ-CLIENTCFG-003 | §4.1 | ConfigDataController, ClientConfigurationsImportSheet |
| REQ-USERSET-001 | §5.4 | AuthUserController, UpdateAuthUserAction |
| REQ-USERSET-002 | §5.4 | UpdateAuthUserRequest (gap: uniqueness not enforced) |
9. Design Decisions
| Decision | Rationale | Alternatives Considered |
|---|---|---|
| Three-tier settings hierarchy | Clear ownership, precedence matches organizational structure | Flat settings (rejected: no scoping), inheritance hierarchy (rejected: complexity) |
| Site-scoped configurations | Multi-tenant isolation without separate databases | Separate databases (rejected: operational complexity) |
| Immediate application | User expects settings to take effect without restart | Queued application (rejected: confusing UX) |
| JSON storage for user settings | Flexible schema, easy to extend | Separate columns (rejected: schema migration burden) |
| Excel import/export for client config | Customer familiarity, offline editing | JSON/YAML (rejected: less accessible to lab staff) |
| S3 preservation toggle for first site | Backward compatibility for existing deployments | Force migration (rejected: disruptive) |
| Configuration dependency cascade at UI level | Clear feedback, no hidden value changes | Automatic value clearing (rejected: surprising) |
10. Implementation Gaps
| Gap | SRS Requirement | Current State | Recommendation |
|---|---|---|---|
| Display name uniqueness | REQ-USERSET-002 | Validation rule validates max:40 only | Add unique:users,display_name rule |
11. Related Documents
| Document | Relevant Sections |
|---|---|
| SRS: site.md | Site management requirements |
| SRS: client-config.md | Client configuration requirements |
| SRS: user-settings.md | User settings requirements |
| SDS: Architecture | Multi-site architecture |
| SDS: Data Architecture | Entity model |
| SDS: Security | Site-based access control |
| SDS: CONFIGIO Domain | Import/export patterns |
| Database Reference | Full schema |
| Configuration Reference | Setting details |