# ConnectionStrings Editor - Design Plan ## Overview Add a ConnectionStrings section under Settings in the ConfigManager tree view. This section provides a master-detail editor for managing database connection strings with provider-specific field editing. ## Design Decisions | Decision | Choice | Rationale | |----------|--------|-----------| | Storage location | appsettings.json | Consistent with existing settings pattern | | Field editing | Provider-specific parsed fields | Better UX than raw connection string editing | | Supported providers | Generic, Oracle, SqlServer | Covers existing JDE/CMS/MSSQL needs | | SQL Server auth | SQL Authentication only | Windows auth not needed for this use case | | Password display | Masked with reveal toggle | Security + usability balance | | Edit workflow | Inline panel editing | Matches existing form patterns | | Delete behavior | Confirmation dialog, immediate | Prevents accidents, clear feedback | ## Architecture ### Tree Structure ``` Settings/ ├── DataSync ├── DataAccess ├── Auth ├── Ldap ├── Search ├── ExcelExport └── ConnectionStrings <-- NEW ``` ### Data Model **ConnectionStringEntry** - represents a single connection string: ```csharp public class ConnectionStringEntry { public string Name { get; set; } = string.Empty; public ConnectionProvider Provider { get; set; } = ConnectionProvider.Generic; // SqlServer fields public string? Server { get; set; } public string? Database { get; set; } public string? UserId { get; set; } public string? Password { get; set; } public string Encrypt { get; set; } = "True"; public bool TrustServerCertificate { get; set; } public int ConnectionTimeout { get; set; } = 30; public string? ApplicationName { get; set; } // Oracle fields public string? Host { get; set; } public int Port { get; set; } = 1521; public string? ServiceName { get; set; } // Generic fields public string? RawConnectionString { get; set; } // Generates the final connection string based on Provider public string GenerateConnectionString() { ... } } public enum ConnectionProvider { Generic, SqlServer, Oracle } ``` **ConnectionStringsSection** - the config model section: ```csharp public class ConnectionStringsSection { public List Entries { get; set; } = new(); } ``` ### ViewModel Structure ``` ConnectionStringsFormViewModel ├── Connections : ObservableCollection ├── SelectedConnection : ConnectionStringEntryViewModel? ├── HasSelection : bool ├── AvailableProviders : IReadOnlyList ├── AddConnectionCommand ├── DeleteConnectionCommand ├── ValidateConnectionCommand ├── TestConnectionCommand ``` **ConnectionStringEntryViewModel** - wraps each entry for editing: ```csharp public class ConnectionStringEntryViewModel : ViewModelBase { // All fields from ConnectionStringEntry exposed as properties // Provider property triggers template switching // GeneratedConnectionString property for preview // IsPasswordVisible for password reveal toggle } ``` ### Connection String Formats **SqlServer:** ``` Server={server};Database={database};User Id={userId};Password={password};Encrypt={encrypt};TrustServerCertificate={trust};Connection Timeout={timeout};Application Name={appName}; ``` **Oracle (EZConnect):** ``` Data Source=//{host}:{port}/{serviceName};User Id={userId};Password={password};Connection Timeout={timeout}; ``` **Generic:** Raw connection string as entered by user. ## UI Design ### Layout Structure ``` ┌─────────────────────────────────────────────────────────┐ │ Connection Strings │ │ ──────────────────────────────────────────────────────── │ ├─────────────────────────────────────────────────────────┤ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Connections (3) │ │ │ │ ┌────────────┬──────────┬─────────────────────────┐ │ │ │ │ │ Name │ Provider │ Server │ │ │ │ │ ├────────────┼──────────┼─────────────────────────┤ │ │ │ │ │ jde │ Oracle │ jdeserver.company.com │ │ │ │ │ │ mssql │ SqlServer│ localhost\SQLEXPRESS │ │ │ │ │ │ cms │ Generic │ - │ │ │ │ │ └────────────┴──────────┴─────────────────────────┘ │ │ │ │ [+ Add] [Delete] │ │ │ └─────────────────────────────────────────────────────┘ │ ├─────────────────────────────────────────────────────────┤ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Edit Connection: mssql │ │ │ │ │ │ │ │ Name * Provider * │ │ │ │ [mssql ] [SqlServer ▼] │ │ │ │ ──────────────────────────────────────────────────── │ │ │ │ Server * Database * │ │ │ │ [localhost\SQLEXPRESS] [ScopingTool ] │ │ │ │ │ │ │ │ User Id Password │ │ │ │ [sa ] [•••••••• ] [👁] │ │ │ │ │ │ │ │ Encrypt ☐ Trust Server Certificate │ │ │ │ [True ▼] (Skip cert validation) │ │ │ │ │ │ │ │ Connection Timeout Application Name │ │ │ │ [30 ] [JdeScopingTool ] │ │ │ │ ──────────────────────────────────────────────────── │ │ │ │ CONNECTION STRING PREVIEW │ │ │ │ Server=localhost\SQLEXPRESS;Database=ScopingTool;... │ │ │ └─────────────────────────────────────────────────────┘ │ ├─────────────────────────────────────────────────────────┤ │ ┌─────────────────────────────────────────────────────┐ │ │ │ [Validate] [Test Connection] │ │ │ └─────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────┘ ``` ### Provider-Specific Forms **SqlServer fields:** - Server (text, required) - Database (text, required) - User Id (text) - Password (password with reveal toggle) - Encrypt (dropdown: True/False/Strict) - TrustServerCertificate (checkbox) - Connection Timeout (numeric, default 30) - Application Name (text) **Oracle fields:** - Host (text, required) - Port (numeric, default 1521) - Service Name (text, required) - User Id (text, required) - Password (password with reveal toggle, required) - Connection Timeout (numeric) **Generic fields:** - Connection String (multiline text, required) ### Button Behaviors | Button | Action | |--------|--------| | Add | Creates new entry with default values, selects it | | Delete | Shows confirmation dialog, removes entry on confirm | | Validate | Validates connection string syntax (no network call) | | Test | Attempts actual database connection, shows modal with result | ### State Transitions ``` No connections → Empty state with "Add First Connection" button Connections exist, none selected → Table visible, placeholder in edit area Connection selected → Edit form visible with provider-specific fields Field changed → Entry marked dirty, generates preview string Save (via main Save) → All changes persisted to appsettings.json ``` ## Integration Points ### ConfigModel Integration Add `ConnectionStrings` property to `ConfigModel`: ```csharp public class ConfigModel { // Existing properties... public ConnectionStringsSection ConnectionStrings { get; set; } = new(); } ``` ### MainWindowViewModel Integration - Add ConnectionStrings node to tree under Settings folder - Handle node selection to load `ConnectionStringsFormViewModel` - Mark node as modified when connection strings change ### Serialization Connection strings serialize to appsettings.json as: ```json { "ConnectionStrings": { "Entries": [ { "Name": "mssql", "Provider": "SqlServer", "Server": "localhost\\SQLEXPRESS", "Database": "ScopingTool", "UserId": "sa", "Password": "secretpassword", "Encrypt": "True", "TrustServerCertificate": true, "ConnectionTimeout": 30, "ApplicationName": "JdeScopingTool" }, { "Name": "jde", "Provider": "Oracle", "Host": "jdeserver.company.com", "Port": 1521, "ServiceName": "JDEPROD", "UserId": "jde_readonly", "Password": "oraclepassword", "ConnectionTimeout": 60 } ] } } ``` ## Testing Strategy ### Unit Tests 1. **ConnectionStringEntry tests:** - GenerateConnectionString produces correct format per provider - Default values are correct - Required field validation 2. **ConnectionStringEntryViewModel tests:** - Property changes raise PropertyChanged - Provider change clears irrelevant fields - Password visibility toggle works 3. **ConnectionStringsFormViewModel tests:** - Add creates new entry and selects it - Delete removes selected entry - Selection change updates form - HasSelection reflects state correctly ### Integration Tests 1. **Serialization round-trip:** - Save and reload preserves all fields - Provider enum serializes correctly 2. **Connection testing:** - SqlServer test connection works - Oracle test connection works - Error messages displayed correctly