Files
jdescopingtool/PLANS/ConnectionStringsEditor-Design.md
T
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

300 lines
12 KiB
Markdown

# 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<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:
```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