Files
DP44/enriched-qwen3-coder-next/DataPRO/Modules/PreviousDBVersions/Version57/DatabaseExport/Classes/TestMetaData.md

124 lines
9.2 KiB
Markdown
Raw Normal View History

2026-04-17 14:55:32 -04:00
---
source_files:
- DataPRO/Modules/PreviousDBVersions/Version57/DatabaseExport/Classes/TestMetaData/CustomerDetails.cs
- DataPRO/Modules/PreviousDBVersions/Version57/DatabaseExport/Classes/TestMetaData/LabratoryDetails.cs
- DataPRO/Modules/PreviousDBVersions/Version57/DatabaseExport/Classes/TestMetaData/TestEngineerDetails.cs
generated_at: "2026-04-16T04:59:22.874172+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "283afdf9f6a03436"
---
# Documentation: Test Metadata Wrappers (Version 57)
## 1. Purpose
This module provides managed wrapper classes for low-level `ISO.*Details` types (`CustomerDetails`, `LabratoryDetails`, `TestEngineerDetails`) used in database export operations for Version 57 of the database schema. Its primary role is to encapsulate and standardize access to these domain entities—offering lazy-loaded, sorted, and deduplicated collections via singleton list managers (`CustomerDetailsList`, `LabratoryDetailsList`, `TestEngineerDetailsList`). It ensures consistent handling of a special "(none)" placeholder entry and provides thread-safe access to metadata used in test reporting and export workflows.
## 2. Public Interface
### `CustomerDetails`
- **`CustomerDetails()`**
Default constructor. Initializes internal `_customerDetails` with a new `ISO.CustomerDetails`, setting its `Name` to `"(none)"`.
- **`CustomerDetails(ISO.CustomerDetails customerDetails)`**
Copy constructor. Creates a new `ISO.CustomerDetails` instance from the provided `customerDetails`.
- **`string Name { get; set; }`**
Gets or sets the `Name` property of the underlying `ISO.CustomerDetails`.
- **`ISO.CustomerDetails GetISOCustomer()`**
Returns the internal `ISO.CustomerDetails` instance.
- **`override string ToString()`**
Returns the `Name` property.
### `CustomerDetailsList`
- **`static CustomerDetailsList CustomerList { get; }`**
Singleton accessor.
- **`CustomerDetails[] Customers { get; }`**
Returns a sorted (by `Name`, ordinal) array of all `CustomerDetails`, including the "(none)" entry. Thread-safe via `lock` and lazy initialization.
- **`CustomerDetails[] GetAllCustomers()`**
Returns a fresh array containing a new "(none)" `CustomerDetails` followed by all `CustomerDetails` created from `ISO.CustomerDetails.GetAllCustomerDetails()`.
- **`CustomerDetails GetCustomerDetail(string name)`**
Returns the first `CustomerDetails` in `Customers` (parallel query) matching `name`, or `null` if none found.
---
### `LabratoryDetails`
- **`LabratoryDetails()`**
Default constructor. Initializes `_lab` with a new `ISO.LabratoryDetails`, setting `Name` to `"(none)"`.
- **`LabratoryDetails(ISO.LabratoryDetails lab)`**
Copy constructor. Creates a new `ISO.LabratoryDetails` instance from `lab`.
- **`string Name { get; set; }`**
Gets or sets the `Name` property of `_lab`.
- **`ISO.LabratoryDetails GetIsoLab()`**
Returns the internal `_lab` instance.
- **`override string ToString()`**
Returns the `Name` property.
### `LabratoryDetailsList`
- **`protected LabratoryDetailsList()`**
Protected constructor (enforces singleton via private instantiation).
- **`static LabratoryDetailsList LabratoryList { get; }`**
Singleton accessor.
- **`LabratoryDetails[] Labs { get; }`**
Returns a sorted (by `Name`, ordinal) array of all `LabratoryDetails`, including "(none)". Thread-safe via `lock` and lazy initialization.
- **`LabratoryDetails GetLab(string name)`**
Returns the `LabratoryDetails` for `name` from the internal `_labs` dictionary (if populated), or `null`. Includes exception handling (logs via `APILogger` on failure).
- **`private LabratoryDetails[] GetAllLabs()`**
Returns a fresh array containing a new "(none)" `LabratoryDetails` followed by all `LabratoryDetails` created from `ISO.LabratoryDetails.GetAllLabratoryDetails()`. Includes exception handling.
---
### `TestEngineerDetails`
- **`TestEngineerDetails()`**
Default constructor. Initializes `_testEngineerDetails` with a new `ISO.TestEngineerDetails`, setting `Name` to `"(none)"`.
- **`TestEngineerDetails(ISO.TestEngineerDetails testEngineerDetails)`**
Copy constructor. Creates a new `ISO.TestEngineerDetails` instance from `testEngineerDetails`.
- **`string Name { get; set; }`**
Gets or sets the `Name` property of `_testEngineerDetails`.
- **`ISO.TestEngineerDetails GetISOTestEngineer()`**
Returns the internal `_testEngineerDetails` instance.
- **`override string ToString()`**
Returns the `Name` property.
### `TestEngineerDetailsList`
- **`static TestEngineerDetailsList TestEngineerList { get; }`**
Singleton accessor.
- **`TestEngineerDetails[] TestEngineers { get; }`**
Returns a sorted (by `Name`, using `CompareTo`) array of all `TestEngineerDetails`, including "(none)". Thread-safe via `lock` and lazy initialization.
- **`TestEngineerDetails[] GetAllTestEngineers()`**
Returns a fresh array containing a new "(none)" `TestEngineerDetails` followed by all `TestEngineerDetails` created from `ISO.TestEngineerDetails.GetAllTestEngineerDetails()`.
- **`TestEngineerDetails GetTestEngineerDetail(string name)`**
Returns the first `TestEngineerDetails` in `TestEngineers` (parallel LINQ query) matching `name`, or `null`.
## 3. Invariants
- **"(none)" Placeholder**: Each list (`CustomerDetails`, `LabratoryDetails`, `TestEngineerDetails`) *always* includes a special entry with `Name == "(none)"` as the first element returned by `GetAll*()` methods.
- **Deduplication**: The internal `_customers`, `_labs`, and `_testEngineers` dictionaries use `Name` as the key, ensuring only one entry per unique name (last one wins in case of duplicates in `GetAll*()`).
- **Sorted Output**: The `Customers`, `Labs`, and `TestEngineers` properties return arrays sorted by `Name` using ordinal string comparison (`String.Compare(..., StringComparison.Ordinal)` or `CompareTo`).
- **Thread Safety**: All list properties (`Customers`, `Labs`, `TestEngineers`) and their underlying population methods (`PopulateCustomers`, `PopulateList`, `PopulateEngineers`) are guarded by dedicated static `lock` objects. However, `GetCustomerDetail` and `GetTestEngineerDetail` use `AsParallel()` on the *already-computed* `Customers`/`TestEngineers` array, which is safe but not optimized.
- **Null Handling**: `Compare*` methods explicitly handle `null` inputs (returning `-1`, `0`, or `1` as appropriate). `Get*Detail` methods return `null` if no match is found.
## 4. Dependencies
- **Internal Dependencies**:
- `ISO.CustomerDetails`, `ISO.LabratoryDetails`, `ISO.TestEngineerDetails` (from the `ISO` namespace) — core data types being wrapped.
- `ISO.CustomerDetails.GetAllCustomerDetails()`, `ISO.LabratoryDetails.GetAllLabratoryDetails()`, `ISO.TestEngineerDetails.GetAllTestEngineerDetails()` — static methods to fetch raw data.
- **External Dependencies**:
- `DTS.Utilities.Logging.APILogger` (used in `LabratoryDetailsList` only) — for logging exceptions during lab retrieval.
- Standard .NET: `System`, `System.Collections.Generic`, `System.Linq`.
- **Depended Upon**: This module is part of `DatabaseExport` namespace and is likely consumed by higher-level export/reporting logic in the `DataPRO` system (not visible in source).
## 5. Gotchas
- **Inconsistent Naming**: Class is named `LabratoryDetails` (misspelled) instead of `LaboratoryDetails`. This typo is propagated in both class and list names.
- **Exception Swallowing**: `LabratoryDetailsList` silently swallows exceptions in `GetLab` and `GetAllLabs` (logs only via `APILogger`), which may hide failures during lab data loading.
- **Race Condition in `Populate*`**: While `Populate*` methods are called under lock, they are not idempotent-safe in all cases:
- `CustomerDetailsList.PopulateCustomers()` checks `if (null != _customers) return;` — safe.
- `TestEngineerDetailsList.PopulateEngineers()` does *not* check `_testEngineers != null` before reassigning — safe only because its called under lock *and* only once.
- `LabratoryDetailsList.PopulateList()` has the same safe guard (`if (null != _labs) return;`).
→ All are safe *in practice* due to locking, but the pattern is fragile.
- **Redundant Copying**: Both constructors (`CustomerDetails(ISO.CustomerDetails)`, etc.) create a *new* instance of the underlying `ISO.*Details` (via copy constructor), not a reference wrapper. This is intentional but may be surprising if mutation of the returned `ISO.*Details` is expected to affect the wrappers internal state.
- **Inconsistent `Get*Detail` Implementations**:
- `CustomerDetailsList.GetCustomerDetail` and `TestEngineerDetailsList.GetTestEngineerDetail` use `AsParallel()` on the *already-computed* array — unnecessary overhead for small lists.
- `LabratoryDetailsList.GetLab` uses direct dictionary lookup (`_labs.ContainsKey`) — more efficient, but only works *after* `Labs` property has been accessed (since `_labs` is populated in `Labs` getter, not eagerly).
- **No Validation**: No validation on `Name` values (e.g., empty strings, duplicates in raw data) — relies on underlying `ISO.*` types or data source to prevent invalid names.
- **Hardcoded Placeholder**: The `"(none)"` string is hardcoded in constructors. No constant or resource reference (despite commented-out `Strings.StringResources.TestTemplate_EmptyListName` in `TestEngineerDetails`).