Files
jdescopingtool/PLANS/ConnectionStringsEditor-Design.md
Joseph Doherty db663cc82d feat(configmanager): add ConnectionStrings editor with test connection support
Adds a new ConnectionStrings section to ConfigManager allowing users to manage
database connection strings with provider selection, connection testing, and
visual feedback for connection state.
2026-01-22 11:12:08 -05:00

12 KiB

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:

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:

public class ConnectionStringsSection
{
    public List<ConnectionStringEntry> Entries { get; set; } = new();
}

ViewModel Structure

ConnectionStringsFormViewModel
├── Connections : ObservableCollection<ConnectionStringEntryViewModel>
├── SelectedConnection : ConnectionStringEntryViewModel?
├── HasSelection : bool
├── AvailableProviders : IReadOnlyList<ConnectionProvider>
├── AddConnectionCommand
├── DeleteConnectionCommand
├── ValidateConnectionCommand
├── TestConnectionCommand

ConnectionStringEntryViewModel - wraps each entry for editing:

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:

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:

{
  "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