mrapids 0.1.31

Your OpenAPI, but executable
Documentation
# Validation Performance Analysis

## Latency Impact

### Validation Timing Benchmarks
```
Small spec (10 operations):    ~50-100ms
Medium spec (50 operations):   ~200-300ms  
Large spec (200 operations):   ~500-800ms
Huge spec (1000+ operations):  ~1-2s
```

### Command-by-Command Analysis

## ✅ Commands WHERE Validation Makes Sense

### 1. `init` Command - **YES**
```rust
// ONE-TIME validation when setting up project
mrapids init my-api --from-url https://api.example.com/spec.yaml
// Add 200-500ms is acceptable for project initialization
```
**Why**: This is a one-time setup operation where 500ms is negligible.

### 2. `validate` Command - **YES**
```rust
// DEDICATED validation command
mrapids validate spec api.yaml --level all
```
**Why**: This is the primary purpose of the command.

### 3. `analyze` Command - **YES**
```rust
// Validate BEFORE generating test data
mrapids analyze api.yaml
```
**Why**: Already does heavy processing; validation adds value with minimal relative impact.

### 4. `generate` Command - **YES**
```rust
// Validate BEFORE code generation
mrapids generate sdk --spec api.yaml
```
**Why**: Code generation takes seconds; validation prevents generating invalid code.

### 5. `flatten` Command - **YES**
```rust
// Validate AFTER flattening
mrapids flatten api.yaml --output flat.yaml
```
**Why**: Ensures flattened spec is still valid.

## ❌ Commands WHERE Validation Should NOT Run

### 1. `run` Command - **NO**
```rust
// DO NOT validate on every API call
mrapids run get-user --id 123
// Would add 200-500ms to EVERY request!
```
**Why**: Would destroy the performance advantage of a fast CLI.

### 2. `test` Command - **NO**
```rust
// DO NOT validate during test execution
mrapids test --all
```
**Why**: Tests should run fast; spec already validated during init/analyze.

### 3. `show` Command - **NO**
```rust
// DO NOT validate for simple lookups
mrapids show get-user
```
**Why**: This is a quick lookup operation.

### 4. `list` Command - **NO**
```rust
// DO NOT validate for listing operations
mrapids list operations
```
**Why**: Simple read operation should be instant.

## 🤖 Agent CLI Considerations

### Agent Real-Time Operations - **NO**
```rust
// Agent handling MCP requests
// DO NOT validate on each tool invocation
agent.handle_tool_call("run", params)
```
**Why**: Would add unacceptable latency to real-time AI interactions.

### Agent Startup - **MAYBE** ⚠️
```rust
// Validate specs during agent initialization
mrapids-agent start --spec api.yaml
// One-time 500ms delay is acceptable
```
**Why**: Ensures agent works with valid specs, but only validates once.

## 🚀 Performance Optimization Strategies

### 1. Validation Caching
```rust
pub struct ValidationCache {
    // Cache validation results by file hash
    cache: HashMap<String, (DateTime<Utc>, ValidationResult)>,
    ttl: Duration,
}

impl ValidationCache {
    pub fn get_or_validate(&mut self, spec_path: &Path) -> Result<&ValidationResult> {
        let hash = calculate_file_hash(spec_path)?;
        
        if let Some((timestamp, result)) = self.cache.get(&hash) {
            if Utc::now() - *timestamp < self.ttl {
                return Ok(result); // Cache hit!
            }
        }
        
        // Cache miss - validate
        let result = validate_spec(spec_path)?;
        self.cache.insert(hash, (Utc::now(), result));
        Ok(&self.cache.get(&hash).unwrap().1)
    }
}
```

### 2. Lazy Validation
```rust
// Only validate if spec changed since last validation
pub fn needs_validation(spec_path: &Path) -> bool {
    let validation_marker = spec_path.with_extension("validated");
    
    if !validation_marker.exists() {
        return true;
    }
    
    let spec_modified = fs::metadata(spec_path)?.modified()?;
    let validation_time = fs::metadata(&validation_marker)?.modified()?;
    
    spec_modified > validation_time
}
```

### 3. Background Validation
```rust
// Validate in background thread during init
pub async fn init_with_background_validation(cmd: InitCommand) -> Result<()> {
    // Start validation in background
    let spec_content = load_spec(&cmd)?;
    let validation_handle = tokio::spawn(async move {
        validate_spec_content(&spec_content).await
    });
    
    // Continue with project setup
    create_project_structure(&cmd)?;
    
    // Check validation result
    match validation_handle.await? {
        Ok(report) => {
            if report.has_errors() {
                println!("⚠️  Spec has validation errors. Run 'mrapids validate' for details.");
            }
        }
        Err(e) => {
            println!("⚠️  Could not validate spec: {}", e);
        }
    }
    
    Ok(())
}
```

### 4. Validation Levels for Performance
```rust
pub enum ValidationLevel {
    Quick,    // ~50ms - Basic structure only
    Standard, // ~200ms - OAS compliance
    Full,     // ~500ms - All rules including security
}

// Quick validation for time-sensitive operations
pub fn quick_validate(spec: &Value) -> Result<()> {
    // Just check critical fields exist
    spec.get("openapi").or(spec.get("swagger"))
        .ok_or_else(|| anyhow!("Not a valid OpenAPI spec"))?;
    
    spec.get("info").ok_or_else(|| anyhow!("Missing info section"))?;
    spec.get("paths").ok_or_else(|| anyhow!("Missing paths section"))?;
    
    Ok(())
}
```

## 📊 Recommended Validation Strategy

### Design-Time Validation (Full)
- `init` - Validate external specs before importing
- `validate` - Dedicated validation command
- `analyze` - Ensure spec is valid before analysis
- `generate` - Prevent generating code from invalid specs
- `flatten` - Validate output is still correct

### Runtime Skip (No Validation)
- `run` - Trust pre-validated specs
- `test` - Trust pre-validated specs  
- `show` - Simple read operation
- `list` - Simple read operation
- Agent runtime calls - Maximum performance

### Hybrid Approach
```rust
// Global flag to control validation
pub struct RuntimeConfig {
    pub skip_validation: bool,        // Default: true for run/test
    pub validation_cache_ttl: Duration, // Default: 1 hour
    pub validation_level: ValidationLevel, // Default: Quick for runtime
}

// Commands can override based on their needs
impl RunCommand {
    pub fn execute(&self, config: &RuntimeConfig) -> Result<()> {
        if !config.skip_validation && self.validate {
            // Only validate if explicitly requested
            quick_validate(&self.spec)?;
        }
        
        // Proceed with normal execution
        run_operation(self)?;
        Ok(())
    }
}
```

## Summary

**Validation should be applied at design-time, not runtime:**

✅ **Design-Time Commands** (init, validate, analyze, generate): Full validation
❌ **Runtime Commands** (run, test, agent calls): Skip validation
⚠️ **Optional**: Cache validation results for 1 hour to balance safety and speed

This approach ensures specs are validated when it matters without impacting the performance that makes MicroRapid fast!