sql-cli 1.73.1

SQL query tool for CSV/JSON with both interactive TUI and non-interactive CLI modes - perfect for exploration and automation
Documentation
# State Change Logging System Design

## Overview

This document describes the comprehensive state change logging system designed to support the gradual migration from `EnhancedTuiApp` to `AppStateContainer` with full visibility into all state mutations.

## Design Philosophy

**"Tiny Steps with Complete Visibility"** - Rather than doing large refactoring that leads to 8-hour regression fixes, we implement state migration in 30+ tiny iterations with comprehensive logging to track every change.

## Architecture Components

### 1. TUI Layer Macros (Call Site Logging)

**Location**: `src/enhanced_tui.rs` lines 67-92  
**Purpose**: Track all state mutations happening in the TUI layer with caller context

#### Available Macros:
```rust
// Log a state field change with old → new values
log_state_change!(self, "field_name", old_value, new_value, "caller_function");

// Log setting a state field to a new value
log_state_set!(self, "field_name", new_value, "caller_function"); 

// Log clearing/resetting a state field
log_state_clear!(self, "field_name", old_value, "caller_function");
```

#### Implementation:
```rust
macro_rules! log_state_change {
    ($self:expr, $field:expr, $old:expr, $new:expr, $caller:expr) => {
        if let Some(ref services) = $self.service_container {
            services.debug_service.info(
                "StateManager",
                format!("[{}] {} changed: {} -> {} (in {})",
                    chrono::Local::now().format("%H:%M:%S%.3f"),
                    $field, $old, $new, $caller
                ),
            );
        }
    };
}
```

### 2. Helper Methods Pattern (Migration Bridge)

**Location**: `src/enhanced_tui.rs` starting around line 250  
**Purpose**: Provide abstracted access to state during migration with logging

#### Design Pattern:
```rust
// Getter - abstracts whether data comes from local field or AppStateContainer
fn get_jump_to_row_input(&self) -> String {
    if let Some(ref container_arc) = self.state_container {
        container_arc.jump_to_row().input.clone()
    } else {
        self.jump_to_row_input.clone()
    }
}

// Setter - logs every mutation with caller tracking  
fn set_jump_to_row_input(&mut self, input: String) {
    let old_value = self.jump_to_row_input.clone();
    self.jump_to_row_input = input.clone();
    log_state_change!(self, "jump_to_row_input", old_value, input, "set_jump_to_row_input");
}
```

#### Benefits:
- **Gradual Migration**: Code can be updated to use helpers before moving data
- **Call Site Visibility**: Every mutation shows where it happened
- **Fallback Safety**: Works with both old and new state locations
- **Zero Regression Risk**: Changes are atomic and reversible

### 3. AppStateContainer Internal Logging

**Location**: `src/app_state_container.rs`  
**Purpose**: Log internal state container operations and transitions

#### Debug Service Integration:
- Uses `RefCell<Option<DebugService>>` for interior mutability through Arc
- Injected during initialization: `state_arc.set_debug_service(services.debug_service.clone_service())`
- Located at: `src/enhanced_tui.rs:525`

#### Active Logging Areas:
```rust
// Mode transitions
pub fn enter_mode(&mut self, mode: AppMode) -> Result<()> {
    let current = self.current_mode();
    if let Some(ref debug_service) = *self.debug_service.borrow() {
        debug_service.info("AppStateContainer", 
            format!("MODE TRANSITION: {:?} -> {:?}", current, mode));
    }
    // ... rest of implementation
}

// Help state changes
pub fn set_help_visible(&mut self, visible: bool) {
    let old_value = self.show_help;
    self.show_help = visible;
    if let Some(ref debug_service) = *self.debug_service.borrow() {
        debug_service.info("AppStateContainer", 
            format!("Help visibility changed: {} -> {} (in set_help_visible)", old_value, visible));
    }
}
```

### 4. Service Container Integration

**Location**: `src/enhanced_tui.rs:520-535`  
**Purpose**: Wire up the debug service dependency injection

```rust
// Initialize service container and help widget
let (service_container, help_widget) = if let Some(ref state_arc) = state_container {
    let services = ServiceContainer::new(state_arc.clone());

    // Inject debug service into AppStateContainer (now works with RefCell)
    state_arc.set_debug_service(services.debug_service.clone_service());

    // Create help widget and set services
    let mut widget = HelpWidget::new();
    widget.set_services(services.clone_for_widget());

    (Some(services), widget)
} else {
    (None, HelpWidget::new())
};
```

## Logging Output & Visibility

### F5 Debug View
All logging from both TUI layer and AppStateContainer appears in the F5 debug view with:
- **Timestamps**: `[HH:MM:SS.fff]` format
- **Component**: `StateManager` vs `AppStateContainer`  
- **Context**: Caller function names
- **State Changes**: `old_value -> new_value` format

### Example Log Output:
```
[14:23:45.123] jump_to_row_input changed: "" -> "42" (in set_jump_to_row_input)
[14:23:45.124] Help visibility changed: false -> true (in set_help_visible)
[14:23:45.125] MODE TRANSITION: Command -> Help
[14:23:45.126] Mode stack: [Command, Help]
```

## Migration Strategy

### Current Status (V12 Branch)
- ✅ Logging macros implemented
- ✅ Debug service integration complete  
- ✅ Helper methods for jump_to_row and help state
- ✅ AppStateContainer mode transition logging
- ✅ Service container dependency injection

### Next Steps
1. **Add more helper methods** for other state fields (input_text, table_state, etc.)
2. **Roll out macro usage** to all state mutations in EnhancedTuiApp
3. **Test migration** of individual fields using helper pattern
4. **Verify F5 logging** shows all state changes during operations

### Migration Pattern per Field:
1. **Add helper methods** (get_field/set_field) 
2. **Update all call sites** to use helpers
3. **Test thoroughly** with logging verification
4. **Move data** from EnhancedTuiApp to AppStateContainer
5. **Update helper** to use AppStateContainer
6. **Verify** no regressions with continued logging

## Technical Details

### Arc Mutability Solution
**Problem**: `Arc<AppStateContainer>` prevents mutable access for debug service injection  
**Solution**: Use `RefCell<Option<DebugService>>` in AppStateContainer for interior mutability

### Caller Tracking
All macros require explicit caller parameter to provide context about where state changes originate, enabling quick debugging of unexpected mutations.

### Performance Considerations  
- Logging is conditional on debug service availability
- Timestamps only generated when logging occurs
- String formatting only happens during actual log calls

## Files Modified

- `src/enhanced_tui.rs` - Logging macros, helper methods, service integration
- `src/app_state_container.rs` - Interior mutability, debug service integration, internal logging
- `src/service_container.rs` - Debug service dependency injection support

This logging system ensures complete visibility during the "tiny steps" migration approach, preventing regression issues and providing clear audit trails for all state mutations.