Configuration Import/Export Design
Document Type: Domain Design (Tier 2) Domain: CONFIGIO Domain Character: Integration SRS Reference: configio.md Status: Draft Last Updated: 2026-01-25
1. Overview
1.1 Purpose
The Configuration Import/Export (CONFIGIO) subsystem provides bulk configuration management via XLSX spreadsheet files. It enables administrators to:
- Import configuration data from Excel files for bulk setup and migration
- Export configuration data for backup, environment migration, and customer documentation
- Generate status reports showing which rows were imported or ignored with reasons
This is an integration-heavy domain characterized by:
- File format parsing and generation (XLSX)
- Extensive per-row validation across 25+ sheet types
- Asynchronous job processing for large imports
- Notification delivery with downloadable status reports
1.2 Requirements Covered
| REQ ID | Title | Priority |
|---|---|---|
| REQ-CONFIGIO-001 | Generate Import Status Reports | Must |
| REQ-CONFIGIO-002 | Export Customer-Friendly Configuration | Must |
| REQ-CONFIGIO-003 | Import and Export Mixes and Targets Configuration | Must |
| REQ-CONFIGIO-004 | Import and Export Combined Outcomes Configuration | Must |
| REQ-CONFIGIO-005 | Import and Export Control Labels Configuration | Must |
| REQ-CONFIGIO-006 | Import and Export Error Codes Configuration | Must |
| REQ-CONFIGIO-007 | Import and Export Error Resolutions Configuration | Must |
| REQ-CONFIGIO-008 | Import and Export Help Items Tags | Should |
| REQ-CONFIGIO-009 | Import and Export Rules Configuration | Must |
| REQ-CONFIGIO-010 | Import and Export QIR Quantification Settings | Must |
| REQ-CONFIGIO-011 | Validate Westgard Limits on Import | Must |
| REQ-CONFIGIO-012 | Import Quantitative/Qualitative Reporting Cut-offs | Must |
| REQ-CONFIGIO-013 | Import and Export LIMS Export Configuration | Must |
| REQ-CONFIGIO-014 | Apply Extraction Instruments Toggle on Import | Must |
1.3 Constraints
Tier 2 Constraint: This document describes ownership, patterns, and design rationale. It links to reference docs for full schemas and validation rules documented in the SRS acceptance criteria.
1.4 Dependencies
| Direction | Domain/Component | Purpose |
|---|---|---|
| Consumes | XLSX Files | Configuration data input |
| Config Template | Customer-friendly export template | |
| Provides to | KITCFG | Imported configuration entities |
| Queue System | Asynchronous job processing | |
| Notification System | Import status delivery | |
| Uses | Cloud Storage | Status report file storage |
2. Component Architecture
2.1 Component Diagram
2.2 Component Responsibilities
| Component | Type | Responsibility | REQ Trace |
|---|---|---|---|
ConfigDataController | Controller | Upload endpoint, file validation, job dispatch | REQ-CONFIGIO-001, 003-014 |
ConfigDataImportJob | Job | Async import orchestration, notification trigger | REQ-CONFIGIO-001 |
ConfigDataImport | Orchestrator | Multi-sheet import routing (25 sheet types) | REQ-CONFIGIO-003-014 |
*ImportSheet | Sheet Handler | Sheet-specific parsing and validation | Various |
*ImportRowValidator | Validator | Per-row field validation | Various |
KitConfigurationImportResultExportAction | Action | Generate status report, send notification | REQ-CONFIGIO-001 |
KitConfigurationsExport | Export | Full configuration export to XLSX | REQ-CONFIGIO-003-014 |
CustomerFriendlyKitConfigurationsExport | Export | Customer-readable export | REQ-CONFIGIO-002 |
PrecedenceNormalizer | Algorithm | Rule precedence normalization | REQ-CONFIGIO-009 |
2.3 Architectural Patterns
Pattern: Sheet Registry
Import sheets are registered by name in ConfigDataImport. Unknown sheets are skipped with logging.
// Sheet name → Handler mapping
'Mix and Targets' => new MixAndTargetsImportSheet($user),
'Combined Outcomes' => new CombinedOutcomesImportSheet($user),
// ... 23 more sheets
Pattern: Row Status Collection
Each import sheet maintains a collection of rows with status:
$this->rowsWithStatuses = $importAction($user, $rows);
// Each row has 'status' = 'Imported' | 'Ignored: {reason}'
Pattern: Chunked Processing
Large sheets use chunked reading to manage memory:
// CombinedOutcomesImportSheet
public function chunkSize(): int { return 1000; }
Pattern: Post-Import Cascade
Mix/Target imports trigger global mapping:
public function afterSheet() {
(new GlobalMixMapper($this->authUser))->map();
}
3. Data Design
3.1 Entities
This domain does not own persistent entities. It orchestrates import/export operations that affect entities owned by KITCFG, ERRORCODES, and other configuration domains.
| Entity | Owner | Usage in CONFIGIO |
|---|---|---|
mixes | KITCFG | Import/export target |
targets | KITCFG | Import/export target |
control_labels | KITCFG | Import/export target |
combined_outcomes | KITCFG | Import/export target |
error_codes | ERRORCODES | Import/export target |
error_resolutions | ERRORCODES | Import/export target |
westgard_settings | KITCFG | Import/export target |
rules | RULES | Import/export target |
lims_statuses | KITCFG | Import/export target |
See Database Reference for full schema.
3.2 Data Structures
Import Row with Status
interface ImportRow {
// Original row data from XLSX (varies by sheet type)
[column: string]: string | number | boolean | null;
// Appended by import process
status: 'Imported' | `Ignored: ${string}`;
}
Import Result Counts
interface ImportResultCounts {
imported: number;
ignored: number;
}
Sheet Configuration
// 25 supported sheet names
type SheetName =
| 'Client Configurations'
| 'Dyes'
| 'Roles'
| 'Rules'
| 'Mix and Targets'
| 'Control Labels'
| 'Combined Outcomes'
| 'Error Codes'
| 'Error Resolutions'
| 'Westgard Limits'
| 'QIR - Quantification settings'
| 'Help Items'
// ... 13 more
;
3.3 State Transitions
This domain is stateless. All operations are request-scoped, though import jobs execute asynchronously.
4. Interface Design
4.1 APIs Provided
| Endpoint | Method | Purpose | REQ Trace |
|---|---|---|---|
/api/config-data | POST | Upload configuration file, dispatch import job | REQ-CONFIGIO-001, 003-014 |
/api/config-data | DELETE | Delete all client configurations for site | N/A (admin utility) |
/api/kit-configurations/export | GET | Export full configuration XLSX | REQ-CONFIGIO-003-014 |
/api/customer-friendly-kit-configurations/export | GET | Export customer-friendly XLSX | REQ-CONFIGIO-002 |
4.2 APIs Consumed
This domain does not consume external APIs. It interacts with the filesystem and queue system.
4.3 File Formats
Import File Requirements:
- Format: XLSX or XLS
- Structure: Multiple sheets, each with header row
- Sheet names must match expected names (case-sensitive)
- Unknown sheets are skipped
Export File Format:
- Format: XLSX
- Naming:
kit-configurations-{site_name}-{timestamp}.xlsx - Customer-friendly naming:
customer-friendly-kit-configurations-{site_name}.xlsx
Status Report Format:
- Format: XLSX
- Content: Original import data with appended "Status" column
- Naming:
kit-configuration-import-results-{timestamp}.xlsx
4.4 Events
| Event | Direction | Payload | Purpose |
|---|---|---|---|
ConfigDataImportJob | Dispatched | filePath, fileName | Trigger async import |
KitConfigurationsImportedWithIgnoredRows | Notification | fileName, message, downloadUrl | Notify user of import with errors |
KitConfigurationsImportedWithoutIgnoredRows | Notification | fileName | Notify user of successful import |
5. Behavioral Design
5.1 Import Processing Flow
Algorithm: Process Configuration Import
Inputs:
- file: XLSX file with multiple sheets
- user: Authenticated user
Outputs:
- notification: Import status notification with optional report download
Assumptions:
- File is valid XLSX format
- User has Administrator or Super Administrator role
- Queue system is operational
Steps:
1. Controller receives file upload
2. Validate file extension (xlsx, xls only)
3. Store file temporarily
4. Dispatch ConfigDataImportJob to queue
5. Job executes asynchronously:
a. Create ConfigDataImport with sheet registry
b. For each recognized sheet:
- Instantiate appropriate ImportSheet handler
- Parse rows with heading row mapping
- For each row:
* Validate required fields
* Validate field formats (type, range, precision)
* Check business rules (references, duplicates)
* If valid: create/update entity, status = "Imported"
* If invalid: skip entity, status = "Ignored: {reason}"
- Collect rows with statuses
- Execute post-sheet hooks (e.g., GlobalMixMapper)
c. Unknown sheets logged and skipped
6. Calculate import/ignored counts
7. If any ignored rows:
a. Generate status report XLSX
b. Store to cloud storage
c. Send notification with download link
8. Else:
Send success notification
9. Delete temporary upload file
Notes:
- Sheet processing order matters for dependencies
- Large sheets processed in chunks (1000 rows)
- Partial failures allowed: valid rows imported, invalid skipped
Import Sheet Processing Order:
| Order | Sheet | Dependencies |
|---|---|---|
| 1 | Client Configurations | None |
| 2 | Dyes | None |
| 3 | Roles | None |
| 4 | Rules | None |
| 5 | Westgard Events | None |
| 6 | Specimens | None |
| 7 | Extractions | None |
| 8 | Mix and Targets | None |
| 9 | Thermocyclers | None |
| 10 | Control Labels | Mixes, Roles |
| 11 | Rules Mapping | Mixes, Targets, Roles |
| 12 | Lims Exports | None |
| 13 | Error Codes | None |
| 14 | Curve Control Limits | Mixes, Targets, Roles |
| 15 | Westgard Limits | Mixes, Targets, Roles |
| 16 | Cross Contamination Limits | Mixes, Targets |
| 17 | Test Codes | Mixes |
| 18 | Qualitative Reportings | Mixes, Targets |
| 19 | Error Resolutions | Error Codes |
| 20 | QIR - Quantification settings | Targets |
| 21 | Help Items | None |
| 22 | Combined Outcomes | Mixes, Targets, LIMS Statuses |
| 23 | Features | None |
| 24 | Alerts | None |
| 25 | Known Quantities | Mixes, Targets, Roles |
5.2 Status Report Generation
5.3 Rule Precedence Normalization
Algorithm: Normalize Rule Precedence on Import
Inputs:
- rules: Collection of imported rule rows
- existing_rules: Current rules in database
Outputs:
- rules: Collection with normalized global precedence values
Assumptions:
- Rules have rule_type and relative_precedence fields
- Rule types have fixed type precedence order
Steps:
1. Group imported rules by rule_type
2. For each rule type (in type precedence order):
a. Observation (type_precedence = 1)
b. Control Check (type_precedence = 2)
c. Sample Result (type_precedence = 3)
d. Apply Controls (type_precedence = 4)
e. Sample Check (type_precedence = 5)
f. Parse/Import/Reanalysis/General/Reporting (type_precedence = 6)
3. Within each type:
a. Sort by relative_precedence
b. Remove gaps (renumber sequentially)
c. Resolve duplicates (later rows get higher precedence)
d. New imported rules take priority over existing at same precedence
4. Calculate global_precedence = (type_precedence * 1000) + relative
5. Return rules with assigned global_precedence
Notes:
- Existing rules may shift to accommodate imports
- Precedence affects rule execution order in analysis
5.4 Validation Flow (Per-Row)
Algorithm: Validate Import Row
Inputs:
- row: Single row from import sheet
- validator: Sheet-specific row validator
- context: Site, user, related entities
Outputs:
- result: { valid: boolean, reason?: string }
Steps:
1. Check required fields present
2. For each field:
a. Validate data type (string, number, boolean)
b. Validate format (precision, range, enum values)
c. Validate business rules:
- Foreign key references exist
- No duplicates where uniqueness required
- Conditional rules (e.g., sample type toggle)
3. If all valid: return { valid: true }
4. If any invalid: return { valid: false, reason: first_failure }
Notes:
- First validation failure stops further checks
- Reason is human-readable for status report
6. Error Handling
| Condition | Detection | Response | User Impact |
|---|---|---|---|
| Invalid file extension | Controller validation | 422 Unprocessable | Upload rejected with error |
| Corrupt XLSX file | Excel library exception | Job failure logged | No notification (silent fail) |
| Unknown sheet name | Sheet registry lookup | Skip with log | Sheet ignored, others processed |
| Required field missing | Row validator | Status = "Ignored: field required" | Row skipped |
| Invalid field format | Row validator | Status = "Ignored: invalid format" | Row skipped |
| Foreign key not found | Row validator | Status = "Ignored: reference not found" | Row skipped |
| Duplicate entity | Unique constraint | Upsert or skip (varies by sheet) | Depends on sheet policy |
| Memory exhaustion | PHP limit | Job failure | Partial import, no notification |
| Queue timeout | Job timeout | Retry or fail | May result in duplicate processing |
Malformed File Handling:
- Files that cannot be parsed by PHPSpreadsheet result in job failure
- No notification is sent in this case (limitation acknowledged)
- Job logs capture the exception for debugging
7. Configuration
| Setting | Location | Default | Effect | REQ Trace |
|---|---|---|---|---|
use_extraction_instruments | client_configurations | false | Toggle Westgard import based on extraction instruments | REQ-CONFIGIO-014 |
use_role_priority_for_resolution | client_configurations | false | Enable resolution priority import for control labels | REQ-CONFIGIO-005 |
use_sample_type | client_configurations | false | Enable specimen type validation for reporting cut-offs | REQ-CONFIGIO-012 |
memory_limit | PHP ini | 5G | Set during import for large files | REQ-CONFIGIO-003-014 |
queue.default | Laravel config | redis | Queue driver for async processing | REQ-CONFIGIO-001 |
See Configuration Reference for details.
8. Implementation Mapping
8.1 Code Locations
| Component | Type | Path |
|---|---|---|
| ConfigDataController | Controller | app/Http/Controllers/ConfigDataController.php |
| KitConfigurationsExportController | Controller | app/Http/Controllers/KitConfigurationsExportController.php |
| CustomerFriendlyKitConfigurationsExportController | Controller | app/Http/Controllers/CustomerFriendlyKitConfigurationsExportController.php |
| ConfigDataImportJob | Job | app/Jobs/ConfigDataImportJob.php |
| ConfigDataImport | Orchestrator | app/Imports/ConfigDataImport.php |
| MixAndTargetsImportSheet | Import Sheet | app/Imports/Sheets/MixAndTargetsImportSheet.php |
| CombinedOutcomesImportSheet | Import Sheet | app/Imports/Sheets/CombinedOutcomesImportSheet.php |
| ControlLabelsImportSheet | Import Sheet | app/Imports/Sheets/ControlLabelsImportSheet.php |
| ErrorCodesImportSheet | Import Sheet | app/Imports/Sheets/ErrorCodesImportSheet.php |
| ErrorResolutionsImportSheet | Import Sheet | app/Imports/Sheets/ErrorResolutionsImportSheet.php |
| RulesImportSheet | Import Sheet | app/Imports/Sheets/RulesImportSheet.php |
| WestgardLimitsImportSheet | Import Sheet | app/Imports/Sheets/WestgardLimitsImportSheet.php |
| CalculatedQuantificationSettingsImportSheet | Import Sheet | app/Imports/Sheets/CalculatedQuantificationSettingsImportSheet.php |
| QuantitativeReportingsImportSheet | Import Sheet | app/Imports/Sheets/QuantitativeReportingsImportSheet.php |
| LimsStatusImportSheet | Import Sheet | app/Imports/Sheets/LimsStatusImportSheet.php |
| HelpItemsImportSheet | Import Sheet | app/Imports/Sheets/HelpItemsImportSheet.php |
| KitConfigurationImportResultExportAction | Action | app/Actions/Notifications/KitConfigurationImportResultExportAction.php |
| KitConfigurationsExportAction | Action | app/Actions/KitConfigurationsExportAction.php |
| CustomerFriendlyKitConfigurationsExportAction | Action | app/Actions/CustomerFriendlyKitConfigurationsExportAction.php |
| KitConfigurationsExport | Export | app/Exports/Config/KitConfigurationsExport.php |
| KitConfigurationsImportResultsExport | Export | app/Exports/Config/KitConfigurationsImportResultsExport.php |
| MixImportRowValidator | Validator | app/Actions/Mixes/ImportSupport/Validate/MixImportRowValidator.php |
| TargetImportRowValidator | Validator | app/Actions/Mixes/ImportSupport/Validate/TargetImportRowValidator.php |
| CombinedOutcomeImportRowValidator | Validator | app/Actions/OutcomeToLimsStatus/ImportSupport/Validate/CombinedOutcomeImportRowValidator.php |
| ControlLabelImportRowValidator | Validator | app/Actions/ControlLabels/ImportSupport/Validate/ControlLabelImportRowValidator.php |
| WestgardLimitImportRowValidator | Validator | app/Actions/WestgardLimits/ImportSupport/Validate/WestgardLimitImportRowValidator.php |
| PrecedenceNormalizer | Algorithm | app/Imports/Sheets/Support/PrecedenceNormalizer/PrecedenceNormalizer.php |
8.2 Requirement Traceability
| REQ ID | Design Section | Primary Code |
|---|---|---|
| REQ-CONFIGIO-001 | §5.2 Status Report | KitConfigurationImportResultExportAction, KitConfigurationsImportResultsExport |
| REQ-CONFIGIO-002 | §5.1 (export path) | CustomerFriendlyKitConfigurationsExportAction, CustomerFriendlyKitConfigurationsExport |
| REQ-CONFIGIO-003 | §5.1, §5.4 | MixAndTargetsImportSheet, MixImportRowValidator, TargetImportRowValidator |
| REQ-CONFIGIO-004 | §5.1, §5.4 | CombinedOutcomesImportSheet, CombinedOutcomeImportRowValidator |
| REQ-CONFIGIO-005 | §5.4 | ControlLabelsImportSheet, ControlLabelImportRowValidator |
| REQ-CONFIGIO-006 | §5.4 | ErrorCodesImportSheet |
| REQ-CONFIGIO-007 | §5.4 | ErrorResolutionsImportSheet, ResolutionCodeImportRowValidator |
| REQ-CONFIGIO-008 | §5.4 | HelpItemsImportSheet |
| REQ-CONFIGIO-009 | §5.3 Precedence | RulesImportSheet, PrecedenceNormalizer |
| REQ-CONFIGIO-010 | §5.4 | CalculatedQuantificationSettingsImportSheet |
| REQ-CONFIGIO-011 | §5.4 | WestgardLimitsImportSheet, WestgardLimitImportRowValidator |
| REQ-CONFIGIO-012 | §5.4 | QuantitativeReportingsImportSheet, QuantitativeReportingImportRowValidator |
| REQ-CONFIGIO-013 | §5.4 | LimsStatusImportSheet |
| REQ-CONFIGIO-014 | §7 Configuration | WestgardLimitsImportSheet (uses use_extraction_instruments toggle) |
9. Design Decisions
| Decision | Rationale | Alternatives Considered |
|---|---|---|
| Asynchronous import via queue | Large files (1000+ rows) would timeout synchronous requests | Synchronous (rejected: timeout risk) |
| XLSX format for import/export | Customer familiarity, Excel editing, round-trip compatibility | JSON (rejected: less accessible), CSV (rejected: no multi-sheet) |
| Per-row validation with status | Partial imports useful; users can fix specific rows | All-or-nothing (rejected: frustrating UX) |
| Cloud storage for status reports | Temporary URLs, no server filesystem management | Local storage (rejected: multi-server issues) |
| Sheet name registry pattern | Explicit mapping, unknown sheets safely skipped | Reflection (rejected: fragile), strict (rejected: breaks on new sheets) |
| Chunked processing for large sheets | Memory management for 1000+ row sheets | Load all (rejected: OOM risk) |
| Status in notification, not response | Async job cannot return response | Polling (rejected: complexity) |
| Memory limit override (5G) | Large imports require significant memory | Streaming (rejected: library limitations) |
10. Performance Considerations
| Scenario | Concern | Mitigation |
|---|---|---|
| Large import (5000+ rows) | Memory exhaustion | Chunked processing, 5G memory limit |
| Many concurrent imports | Queue congestion | Queue worker scaling |
| Status report generation | File size, storage cost | Cloud storage with temporary URLs (24h expiry) |
| Export with many entities | Query performance, memory | Chunked export, lazy loading |
| File upload | Network timeout | Client-side chunking (frontend), size limits |
11. Related Documents
| Document | Relevant Sections |
|---|---|
| SRS: configio.md | Requirements source |
| SDS: Architecture | Queue system integration |
| SDS: KITCFG Domain | Target entities for import/export |
| SDS: Cross-Cutting | Error handling patterns |
| SDS: Configuration Reference | Client configuration toggles |