--- source_files: - DataPRO/DbAPI/TestMetaData/ICustomerDetails.cs - DataPRO/DbAPI/TestMetaData/ILabratoryDetails.cs - DataPRO/DbAPI/TestMetaData/ITestEngineerDetails.cs - DataPRO/DbAPI/TestMetaData/CustomerDetails.cs - DataPRO/DbAPI/TestMetaData/TestEngineerDetails.cs - DataPRO/DbAPI/TestMetaData/LabratoryDetails.cs generated_at: "2026-04-17T15:52:32.793882+00:00" model: "zai-org/GLM-5-FP8" schema_version: 1 sha256: "b095a05a967160c2" --- # TestMetaData Module Documentation ## 1. Purpose This module provides the database access layer for test metadata entities within the DataPRO system. It defines and implements CRUD operations for three core domain objects: `CustomerDetails`, `LabratoryDetails` (sic), and `TestEngineerDetails`. The module serves as an abstraction over SQL stored procedures, enforcing user authentication before any database operation and translating database results into strongly-typed record objects. Its role is to persist and retrieve test-related metadata that associates tests with customers, laboratories, and engineers. --- ## 2. Public Interface ### ICustomerDetails Interface **`ulong CustomerDetailsInsert(IUserDbRecord user, IConnectionDetails connection, CustomerDetailsDbRecord customerDetailsDbRecord, out int newId, out string errorString)`** - Inserts a new record into the CustomerDetails table via `sp_CustomerDetailsInsert` stored procedure. - Returns the new record's ID in `newId` on success. - Returns `0` (ERROR_SUCCESS) on success; non-zero error codes otherwise. **`ulong CustomerDetailsUpdate(IUserDbRecord user, IConnectionDetails connection, CustomerDetailsDbRecord customerDetailsDbRecord, out string errorString)`** - Updates an existing record in the CustomerDetails table via `sp_CustomerDetailsUpdate` stored procedure. - Returns `0` (ERROR_SUCCESS) on success; non-zero error codes otherwise. **`ulong CustomerDetailsGet(IUserDbRecord user, IConnectionDetails connection, string name, out ICustomerDetailsDbRecord[] customerDetailsDbRecords)`** - Retrieves all customer details matching the provided name via `sp_CustomerDetailsGet` stored procedure. - Returns matching records in `customerDetailsDbRecords` array (may be `null` if no matches or error). - Returns `0` (ERROR_SUCCESS) on success; non-zero error codes otherwise. **`ulong CustomerDetailsDelete(IUserDbRecord user, IConnectionDetails connection, string name, out string errorString)`** - Deletes an entry from the CustomerDetails table via `sp_CustomerDetailsDelete` stored procedure. - Returns `0` (ERROR_SUCCESS) on success; non-zero error codes otherwise. --- ### ILabratoryDetails Interface **`ulong LabratoryDetailsInsert(IUserDbRecord user, IConnectionDetails connection, LabratoryDetailsDbRecord labratoryDetailsDbRecord, out int newId, out string errorString)`** - Inserts a new record into the LabratoryDetails table via `sp_LabratoryDetailsInsert` stored procedure. - Returns the new record's ID in `newId` on success. - Returns `0` (ERROR_SUCCESS) on success; non-zero error codes otherwise. **`ulong LabratoryDetailsUpdate(IUserDbRecord user, IConnectionDetails connection, LabratoryDetailsDbRecord labratoryDetailsDbRecord, out string errorString)`** - Updates an existing record in the LabratoryDetails table via `sp_LabratoryDetailsUpdate` stored procedure. - Returns `0` (ERROR_SUCCESS) on success; non-zero error codes otherwise. **`ulong LabratoryDetailsUpdateInsert(IUserDbRecord user, IConnectionDetails connection, LabratoryDetailsDbRecord labratoryDetailsDbRecord, out string errorString)`** - Performs an upsert operation (update existing or insert new) via `sp_LabratoryDetailsUpdateInsert` stored procedure. - Returns `0` (ERROR_SUCCESS) on success; non-zero error codes otherwise. **`ulong LabratoryDetailsGet(IUserDbRecord user, IConnectionDetails connection, string name, out ILabratoryDetailsDbRecord[] labratoryDetailsDbRecords)`** - Retrieves all laboratory details matching the provided name via `sp_LabratoryDetailsGet` stored procedure. - Returns matching records in `labratoryDetailsDbRecords` array (may be `null` if no matches or error). - Returns `0` (ERROR_SUCCESS) on success; non-zero error codes otherwise. **`ulong LabratoryDetailsDelete(IUserDbRecord user, IConnectionDetails connection, string name, out string errorString)`** - Deletes an entry from the LabratoryDetails table via `sp_LabratoryDetailsDelete` stored procedure. - Returns `0` (ERROR_SUCCESS) on success; non-zero error codes otherwise. --- ### ITestEngineerDetails Interface **`ulong TestEngineerDetailsInsert(IUserDbRecord user, IConnectionDetails connection, TestEngineerDetailsDbRecord testEngineerDetailsDbRecord, out int newId, out string errorString)`** - Inserts a new record into the TestEngineerDetails table via `sp_TestEngineerDetailsInsert` stored procedure. - Returns the new record's ID in `newId` on success. - Returns `0` (ERROR_SUCCESS) on success; non-zero error codes otherwise. **`ulong TestEngineerDetailsUpdate(IUserDbRecord user, IConnectionDetails connection, TestEngineerDetailsDbRecord testEngineerDetailsDbRecord, out string errorString)`** - Updates an existing record in the TestEngineerDetails table via `sp_TestEngineerDetailsUpdate` stored procedure. - Returns `0` (ERROR_SUCCESS) on success; non-zero error codes otherwise. **`ulong TestEngineerDetailsUpdateInsert(IUserDbRecord user, IConnectionDetails connection, TestEngineerDetailsDbRecord testEngineerDetailsDbRecord, out string errorString)`** - Performs an upsert operation (update existing or insert new) via `sp_TestEngineerDetailsUpdateInsert` stored procedure. - Returns `0` (ERROR_SUCCESS) on success; non-zero error codes otherwise. **`ulong TestEngineerDetailsGet(IUserDbRecord user, IConnectionDetails connection, string name, out ITestEngineerDetailsDbRecord[] testEngineerDetailsDbRecords)`** - Retrieves all test engineer details matching the provided name via `sp_TestEngineerDetailsGet` stored procedure. - Returns matching records in `testEngineerDetailsDbRecords` array (may be `null` if no matches or error). - Returns `0` (ERROR_SUCCESS) on success; non-zero error codes otherwise. **`ulong TestEngineerDetailsDelete(IUserDbRecord user, IConnectionDetails connection, string name, out string errorString)`** - Deletes an entry from the TestEngineerDetails table via `sp_TestEngineerDetailsDelete` stored procedure. - Returns `0` (ERROR_SUCCESS) on success; non-zero error codes otherwise. --- ## 3. Invariants - **Authentication Required**: All public methods must call `DbAPI.Connections.IsUserLoggedIn(user, connection)` before executing any database operation. If this returns `false`, the method must immediately return `ErrorCodes.ERROR_ACCESS_DENIED`. - **Error Code Contract**: All methods return `ulong` error codes where `0` represents `ERROR_SUCCESS`. Any non-zero value indicates an error condition. - **Stored Procedure Usage**: All database operations must use stored procedures (never inline SQL). Stored procedures follow naming convention `sp_` (e.g., `sp_CustomerDetailsInsert`). - **Version Field**: The `@Version` parameter is always passed as `1` for all Insert and Update operations. The source does not indicate whether this is incremented elsewhere. - **Connection Disposal**: All implementations must dispose of `cmd.Connection` in a `finally` block to ensure cleanup even on exceptions. - **Output Parameter Pattern**: Stored procedures return error information via `@errorNumber` (int output) and `@errorMessage` (nvarchar(250) output) parameters. - **New ID on Insert**: Insert operations must declare an output parameter `@new_id` (int) to receive the newly created record's identifier. - **Record Filtering**: `Get` methods filter out records where `IsInvalidBlank()` returns `true` on the constructed record object. --- ## 4. Dependencies ### This Module Depends On: | Dependency | Usage | |------------|-------| | `DbAPI.Connections` | `ConnectionManager.GetSqlCommand()`, `IsUserLoggedIn()` | | `DbAPI.Errors` | `ErrorCodes` constants (e.g., `ERROR_SUCCESS`, `ERROR_ACCESS_DENIED`, `ERROR_UNKNOWN`) | | `DbAPI.Logging` | `LogManager.Log()` for error logging | | `DTS.Common.Interface.Database` | `IUserDbRecord` interface | | `DTS.Common.Interface.TestMetaData` | `ICustomerDetailsDbRecord`, `ILabratoryDetailsDbRecord`, `ITestEngineerDetailsDbRecord` interfaces | | `DTS.Common.Classes.CustomerDetails` | `CustomerDetailsDbRecord` class | | `DTS.Common.Classes.LabratoryDetails` | `LabratoryDetailsDbRecord` class | | `DTS.Common.Classes.TestEngineerDetails` | `TestEngineerDetailsDbRecord` class | | `System.Data.SqlClient` | `SqlParameter`, `SqlCommand`, `SqlDataReader` | | `System.Data` | `CommandType`, `ParameterDirection` | ### What Depends On This Module: Not determinable from the provided source files alone. The interfaces are public, while the implementing classes are `internal`, suggesting dependency injection or a factory pattern elsewhere in the codebase. --- ## 5. Gotchas ### Persistent Typo: "Labratory" The term "Laboratory" is consistently misspelled as "Labratory" throughout the codebase (namespace `DbAPI.LabratoryDetails`, interface `ILabratoryDetails`, class `LabratoryDetails`, stored procedures like `sp_LabratoryDetailsInsert`). This typo propagates to database object names and cannot be fixed without database migration. ### Double Connection Disposal in Delete Methods All three `Delete` methods (`CustomerDetailsDelete`, `LabratoryDetailsDelete`, `TestEngineerDetailsDelete`) contain nested `try/finally` blocks where `cmd.Connection.Dispose()` is called twice: ```csharp try { try { /* ... */ } finally { cmd.Connection.Dispose(); } // First disposal } catch (Exception ex) { /* ... */ } finally { cmd.Connection.Dispose(); } // Second disposal ``` While `Dispose()` is typically idempotent, this is redundant and indicates a refactoring artifact. ### Inconsistent Exception Handling - `CustomerDetailsInsert`, `LabratoryDetailsInsert`, `TestEngineerDetailsInsert` do not catch exceptions; they propagate to the caller. - `CustomerDetailsUpdate`, `LabratoryDetailsUpdate`, `TestEngineerDetailsUpdate` catch exceptions and populate `errorString`. - `CustomerDetailsGet`, `LabratoryDetailsGet`, `TestEngineerDetailsGet` catch exceptions, log them via `LogManager.Log()`, and return `ERROR_UNKNOWN`. ### Missing Parameter in TestEngineerDetailsUpdate In `TestEngineerDetailsUpdate`, the `@LocalOnly` parameter is commented out: ```csharp //cmd.Parameters.Add(new SqlParameter("@LocalOnly", SqlDbType.Bit) { Value = testEngineerDetailsDbRecord.LocalOnly }); ``` This means the `LocalOnly` field cannot be updated via this method, unlike in `TestEngineerDetailsInsert` and `TestEngineerDetailsUpdateInsert`. ### Unused Output Parameter in LabratoryDetailsUpdate `LabratoryDetailsUpdate` declares `@new_id` as an output parameter but never reads its value after execution. This parameter is not present in `CustomerDetailsUpdate` or `TestEngineerDetailsUpdate`. ### Delete Parameter Naming Inconsistency - `CustomerDetailsDelete` and `TestEngineerDetailsDelete` pass the `name` parameter to `@Name`. - `LabratoryDetailsDelete` passes the `name` parameter to `@LabratoryName`. ### Hardcoded Version Value All Insert and Update methods pass `@Version = 1` unconditionally. It is unclear from the source whether versioning is implemented elsewhere or if this represents tech debt. ### errorString Not Always Populated The `errorString` output parameter is only populated when the stored procedure returns a non-zero `@errorNumber` or when an exception is caught. On successful operations, it remains an empty string, which is correct but worth noting for callers expecting null checks.