--- source_files: - Common/DTS.Common/Classes/TestMetaData/TestEngineerDetailsDbRecord.cs - Common/DTS.Common/Classes/TestMetaData/CustomerDetailsDbRecord.cs - Common/DTS.Common/Classes/TestMetaData/LabratoryDetailsDbRecord.cs generated_at: "2026-04-16T03:15:34.968260+00:00" model: "Qwen/Qwen3-Coder-Next-FP8" schema_version: 1 sha256: "b20907858a69ef9c" --- # Documentation: Test Metadata Database Record Classes ## 1. Purpose These three classes—`TestEngineerDetailsDbRecord`, `CustomerDetailsDbRecord`, and `LabratoryDetailsDbRecord`—represent immutable data transfer objects (DTOs) for loading and storing metadata about test engineers, customers, and laboratories from a database. They implement `INotifyPropertyChanged` via `BasePropertyChanged` to support UI binding, and provide constructors for instantiation from an `IDataReader` (database query results) or from another instance of the same interface type. Each class encapsulates domain-specific fields (e.g., contact info, reference numbers) alongside common metadata fields (e.g., `LastModified`, `Version`, `LocalOnly`) used for auditing and synchronization. They serve as the foundational data layer for test metadata management within the DTS system. ## 2. Public Interface ### `TestEngineerDetailsDbRecord` - **Namespace**: `DTS.Common.Classes.TestEngineerDetails` - **Implements**: `ITestEngineerDetailsDbRecord` - **Inherits**: `Base.BasePropertyChanged` | Member | Signature | Description | |--------|-----------|-------------| | Constructor | `TestEngineerDetailsDbRecord()` | Default parameterless constructor. | | Constructor | `TestEngineerDetailsDbRecord(ITestEngineerDetailsDbRecord)` | Copy constructor: initializes all properties from another instance of the interface. | | Constructor | `TestEngineerDetailsDbRecord(IDataReader reader)` | Constructor from database: reads values using `Utility.GetString`, `Utility.GetDateTime`, `Utility.GetInt`, and `Utility.GetBool`. | | Property | `int TestEngineerId { get; set; }` | Internal database ID; defaults to `-1`; read-only in UI (`[ReadOnly(true)]`, `[Browsable(false)]`). | | Property | `string Name { get; set; }` | Internal name (likely primary identifier); defaults to `""`; read-only in UI. | | Property | `string TestEngineerName { get; set; }` | Display name; defaults to `"NOVALUE"`; marked with `[DisplayResource("TestEngineerName")]`. | | Property | `string TestEngineerPhone { get; set; }` | Phone number; defaults to `"NOVALUE"`; marked with `[DisplayResource("TestEngineerPhone")]`. | | Property | `string TestEngineerFax { get; set; }` | Fax number; defaults to `"NOVALUE"`; marked with `[DisplayResource("TestEngineerFax")]`. | | Property | `string TestEngineerEmail { get; set; }` | Email address; defaults to `"NOVALUE"`; marked with `[DisplayResource("TestEngineerEmail")]`. | | Property | `bool LocalOnly { get; set; }` | Indicates if record is local-only (not synchronized); defaults to `false`; read-only in UI. | | Property | `DateTime LastModified { get; set; }` | Timestamp of last modification; defaults to `DateTime.MinValue`; read-only in UI. | | Property | `string LastModifiedBy { get; set; }` | User who last modified the record; defaults to `""`; read-only in UI. | | Property | `int Version { get; set; }` | Version number for concurrency control; defaults to `-1`; read-only in UI. | | Method | `bool IsInvalidBlank()` | Returns `true` if `Name` is `null`, empty, or whitespace. | ### `CustomerDetailsDbRecord` - **Namespace**: `DTS.Common.Classes.CustomerDetails` - **Implements**: `ICustomerDetailsDbRecord` - **Inherits**: `Base.BasePropertyChanged` | Member | Signature | Description | |--------|-----------|-------------| | Constructor | `CustomerDetailsDbRecord()` | Default parameterless constructor. | | Constructor | `CustomerDetailsDbRecord(ICustomerDetailsDbRecord)` | Copy constructor. | | Constructor | `CustomerDetailsDbRecord(IDataReader reader)` | Constructor from database. | | Property | `int CustomerId { get; set; }` | Internal database ID; defaults to `-1`; read-only in UI. | | Property | `string Name { get; set; }` | Internal name; defaults to `""`; read-only in UI. | | Property | `string CustomerName { get; set; }` | Display name; defaults to `""`; marked with `[DisplayResource("CustomerName")]`. | | Property | `string CustomerTestRefNumber { get; set; }` | Customer test reference number; defaults to `""`; marked with `[DisplayResource("CustomerTestRefNumber")]`. | | Property | `string ProjectRefNumber { get; set; }` | Project reference number; defaults to `"NOVALUE"`; marked with `[DisplayResource("ProjectRefNumber")]`. | | Property | `string CustomerOrderNumber { get; set; }` | Customer order number; defaults to `"NOVALUE"`; marked with `[DisplayResource("CustomerOrderNumber")]`. | | Property | `string CustomerCostUnit { get; set; }` | Cost center/unit; defaults to `"NOVALUE"`; marked with `[DisplayResource("CustomerCostUnit")]`. | | Property | `bool LocalOnly { get; set; }` | Local-only flag; defaults to `false`; read-only in UI. | | Property | `DateTime LastModified { get; set; }` | Modification timestamp; defaults to `DateTime.MinValue`; read-only in UI. | | Property | `string LastModifiedBy { get; set; }` | Modifier username; defaults to `""`; read-only in UI. | | Property | `int Version { get; set; }` | Version number; defaults to `-1`; read-only in UI. | | Method | `bool IsInvalidBlank()` | Returns `true` if `Name` is blank. | ### `LabratoryDetailsDbRecord` - **Namespace**: `DTS.Common.Classes.LabratoryDetails` *(Note: Typo in namespace and class name: "Labratory" instead of "Laboratory")* - **Implements**: `ILabratoryDetailsDbRecord` - **Inherits**: `Base.BasePropertyChanged` | Member | Signature | Description | |--------|-----------|-------------| | Constructor | `LabratoryDetailsDbRecord()` | Default parameterless constructor. | | Constructor | `LabratoryDetailsDbRecord(ILabratoryDetailsDbRecord)` | Copy constructor. | | Constructor | `LabratoryDetailsDbRecord(IDataReader reader)` | Constructor from database. | | Property | `int LabratoryId { get; set; }` | Internal database ID; defaults to `-1`; read-only in UI. | | Property | `string Name { get; set; }` | Internal name; defaults to `""`; read-only in UI. | | Property | `string LabratoryName { get; set; }` | Display name; defaults to `string.Empty`; marked with `[DisplayResource("LabratoryName")]`. | | Property | `string LabratoryContactName { get; set; }` | Contact person name; defaults to `string.Empty`; marked with `[DisplayResource("LabratoryContactName")]`. | | Property | `string LabratoryContactPhone { get; set; }` | Contact phone; defaults to `"NOVALUE"`; marked with `[DisplayResource("LabratoryContactPhone")]`. | | Property | `string LabratoryContactFax { get; set; }` | Contact fax; defaults to `"NOVALUE"`; marked with `[DisplayResource("LabratoryContactFax")]`. | | Property | `string LabratoryContactEmail { get; set; }` | Contact email; defaults to `"NOVALUE"`; marked with `[DisplayResource("LabratoryContactEmail")]`. | | Property | `string LabratoryTestRefNumber { get; set; }` | Lab test reference number; defaults to `string.Empty`; marked with `[DisplayResource("LabratoryTestRefNumber")]`. | | Property | `string LabratoryProjectRefNumber { get; set; }` | Lab project reference number; defaults to `string.Empty`; marked with `[DisplayResource("LabratoryProjectRefNumber")]`. | | Property | `bool LocalOnly { get; set; }` | Local-only flag; defaults to `false`; read-only in UI. | | Property | `DateTime LastModified { get; set; }` | Modification timestamp; defaults to `DateTime.MinValue`; read-only in UI. | | Property | `string LastModifiedBy { get; set; }` | Modifier username; defaults to `""`; read-only in UI. | | Property | `int Version { get; set; }` | Version number; defaults to `-1`; read-only in UI. | | Method | `bool IsInvalidBlank()` | Returns `true` if `Name` is blank. | ## 3. Invariants - **`Name` is required**: All three classes enforce that `Name` must not be `null`, empty, or whitespace for validity. This is checked via `IsInvalidBlank()`. - **Default values for display fields**: Non-essential contact/reference fields default to `"NOVALUE"` (e.g., `TestEngineerPhone`, `ProjectRefNumber`) or `string.Empty` (e.g., `LabratoryName`, `CustomerName`). - **Metadata fields initialized to sentinel values**: - `LastModified` → `DateTime.MinValue` - `Version` → `-1` - `LocalOnly` → `false` - **UI visibility**: Properties marked `[Browsable(false)]` and `[ReadOnly(true)]` are intended for internal/backend use only (e.g., `CustomerId`, `LastModified`). - **`[DisplayResource]` attribute usage**: Only user-facing fields (e.g., `CustomerName`, `TestEngineerEmail`) carry `[DisplayResource]`, indicating localization support via resource keys. - **Immutability in practice**: Though setters exist, the `[ReadOnly(true)]` attribute and internal naming (`_name`, `_version`) suggest these are *mostly* immutable after construction—especially when populated from a database. ## 4. Dependencies - **Core dependencies (all three classes)**: - `DTS.Common.Base.Classes.BasePropertyChanged` (base class for `INotifyPropertyChanged` implementation) - `DTS.Common.Interface.TestMetaData` (interfaces: `ITestEngineerDetailsDbRecord`, `ICustomerDetailsDbRecord`, `ILabratoryDetailsDbRecord`) - `DTS.Common.Utilities.Logging` (imported but *not used* in the provided code—likely legacy or for future use) - `System.Data` (`IDataReader` for database population) - `System.ComponentModel` (`[Browsable]`, `[ReadOnly]`, `[DisplayResource]` attributes) - **Internal utilities**: - `Utility.GetString`, `Utility.GetDateTime`, `Utility.GetInt`, `Utility.GetBool` (static methods for safe `IDataReader` access) - **Inferred consumers**: - Data access layers (DALs) that populate records from SQL queries. - UI components (e.g., WPF/WinForms) relying on `INotifyPropertyChanged` and `[DisplayResource]` for binding and localization. - Synchronization or caching services that use `LocalOnly`, `LastModified`, and `Version` for conflict resolution. ## 5. Gotchas - **Typo in namespace/class name**: The `LabratoryDetailsDbRecord` class and its namespace use "Labratory" (misspelled) instead of "Laboratory". This is likely historical and should be preserved for compatibility. - **`[DisplayResource]` attribute behavior is undefined**: The source does not show how `[DisplayResource]` is processed. Its runtime behavior (e.g., resource lookup mechanism) is not documented here. - **No validation on non-blank fields**: While `IsInvalidBlank()` checks `Name`, there is no validation for required contact fields (e.g., `TestEngineerEmail`). An instance may be "valid" yet missing critical data. - **`LocalOnly` semantics unclear**: The purpose of `LocalOnly` is not explained—e.g., whether it affects persistence, synchronization, or visibility. - **Default `"NOVALUE"` string**: This sentinel value is used inconsistently: - `TestEngineerDetailsDbRecord`: `"NOVALUE"` for phone/fax/email - `CustomerDetailsDbRecord`: `"NOVALUE"` for project/order/cost-unit - `LabratoryDetailsDbRecord`: `"NOVALUE"` for contact phone/fax/email Consumers must be aware of this convention to avoid misinterpreting `"NOVALUE"` as a literal value. - **No null-safety guarantees**: `Utility.GetString` and similar methods are used, but their behavior on `DBNull` or missing columns is not specified in the source. - **Copy constructor does not validate**: The copy constructor accepts `ITestEngineerDetailsDbRecord` (etc.) without checking for null or invalid state. A copy of an invalid record remains invalid. - **No explicit immutability enforcement**: Despite `[ReadOnly(true)]`, the properties remain settable programmatically—e.g., after construction from a database, callers can still mutate fields.