# {{TOOL_NAME}} Architecture

Complete system design and component documentation.

## High-Level Overview

{{TOOL_NAME}} is a production-grade tool implementing a **3-tier architecture**:

```
┌─────────────────────────────────────────────┐
│  Tier 3: CLI / User Interface                │
│  crates/{{tool_name_kebab}}-cli/             │
│  - clap command parsing                     │
│  - Configuration discovery                  │
│  - User-friendly output                     │
└─────────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────────┐
│  Tier 2: REST API (optional)                │
│  crates/{{tool_name_kebab}}-api/            │
│  - axum HTTP server                        │
│  - JSON request/response                   │
│  - RESTful endpoints                       │
└─────────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────────┐
│  Tier 1: Core Library                       │
│  crates/{{tool_name_kebab}}-core/           │
│  - Business logic                          │
│  - Domain types                            │
│  - Service layer                           │
│  - Error handling                          │
│  - Data persistence                        │
└─────────────────────────────────────────────┘
```

## Tier 1: Core Library

**Location**: `crates/{{tool_name_kebab}}-core/`

**Purpose**: Reusable, interface-agnostic business logic

### Components

#### Error Handling

**File**: `src/error.rs`

Canonical error struct pattern:

```rust
pub struct {{ToolName}}Error {
    pub kind: {{ToolName}}ErrorKind,
    pub context: String,
    pub source: Option<Box<dyn Error>>,
    pub backtrace: Backtrace,
}
```

**Error Types** (customize for your domain):
- `ConfigError` - Configuration issues
- `ValidationError` - Input validation
- `IoError` - File I/O failures
- `DatabaseError` - Database operations
- Custom domain errors as needed

**Usage**:
```rust
fn operation() -> Result<T> {
    if condition {
        return Err({{ToolName}}Error::new(
            {{ToolName}}ErrorKind::ValidationError("message".into()),
            "context about what failed",
        ));
    }
    Ok(value)
}
```

#### Domain Types

**File**: `src/types.rs`

Primary domain type and related structures:

```rust
pub struct {{MainType}} {
    pub id: String,                    // UUID v4
    pub name: String,                  // Human-readable name
    pub description: String,           // Details
    pub metadata: serde_json::Value,   // Extensibility
    pub created_at: DateTime<Utc>,     // Creation timestamp
    pub updated_at: DateTime<Utc>,     // Last modification
}
```

**Additional Types**:
- Enums for status, priority, categories
- Configuration structures (serde + validation)
- Query filters and responses
- Transfer objects for APIs

#### Service Layer

**File**: `src/handlers/service.rs`

Business logic implementation:

```rust
pub struct {{MainType}}Service {
    items: Arc<Mutex<HashMap<String, {{MainType}}>>>,
}

impl {{MainType}}Service {
    pub async fn create(...) -> Result<{{MainType}}>
    pub async fn get(&self, id: &str) -> Result<{{MainType}}>
    pub async fn list(&self) -> Result<Vec<{{MainType}}>>
    pub async fn update(...) -> Result<{{MainType}}>
    pub async fn delete(&self, id: &str) -> Result<()>
}
```

**Storage Options**:
- **In-memory** (template default) - Dev/testing only
- **SQLite** - Single-user, embedded
- **PostgreSQL** - Production, concurrent access
- **Custom** - Implement `Storage` trait

**Pattern**: Async/await with tokio for all I/O operations

#### Module Organization

```
src/
├── lib.rs           # Exports and documentation
├── error.rs         # {{ToolName}}Error, {{ToolName}}ErrorKind
├── types.rs         # {{MainType}} and related types
└── handlers/
    ├── mod.rs       # Module organization
    └── service.rs   # {{MainType}}Service, business logic
```

### Testing

**Unit Tests** (in each module file):
```rust
#[cfg(test)]
mod tests {
    #[tokio::test]
    async fn test_create() { ... }
}
```

**Integration Tests** (`tests/` directory):
```
tests/
├── common/
│   └── mod.rs       # Shared test utilities
└── integration_test.rs
```

**Requirements**:
- Minimum 15 tests per module
- Test success paths
- Test error paths
- Test edge cases
- All tests must pass before commit

## Tier 2: REST API (Optional)

**Location**: `crates/{{tool_name_kebab}}-api/`

**Purpose**: HTTP interface to core library

### Components

#### Web Server

**Framework**: axum (Rust async web framework)

```rust
#[tokio::main]
async fn main() -> Result<()> {
    let app = Router::new()
        .route("/health", get(health_check))
        .route("/{{main_type_plural}}", get(list).post(create))
        .route("/{{main_type_plural}}/:id", get(get_one).put(update).delete(delete))
        .with_state(Arc::new(state));

    axum::serve(listener, app).await?;
    Ok(())
}
```

#### Request/Response Types

**Request** (input from client):
```rust
#[derive(Deserialize)]
struct CreateRequest {
    name: String,
    description: String,
}
```

**Response** (output to client):
```rust
#[derive(Serialize)]
struct {{MainType}}Response {
    id: String,
    name: String,
    created_at: DateTime<Utc>,
}
```

#### Endpoints

Standard CRUD with HTTP semantics:

| Method | Path | Description | Status |
|--------|------|-------------|--------|
| GET | `/health` | Health check | 200 OK |
| GET | `/{{main_type_plural}}` | List all | 200 OK |
| GET | `/{{main_type_plural}}/:id` | Get one | 200 OK or 404 |
| POST | `/{{main_type_plural}}` | Create | 201 Created |
| PUT | `/{{main_type_plural}}/:id` | Update | 200 OK or 404 |
| DELETE | `/{{main_type_plural}}/:id` | Delete | 204 No Content or 404 |

#### Error Handling

Structured error responses:

```json
{
  "error": "Validation error",
  "details": "Name is required",
  "code": "VALIDATION_ERROR"
}
```

### Deployment

**Local Development**:
```bash
cargo run -p {{tool_name_kebab}}-api
# Server on http://127.0.0.1:3000
```

**Production**:
```bash
cargo build -p {{tool_name_kebab}}-api --release
./target/release/{{tool_name_kebab}}-api
```

**Docker**:
```dockerfile
FROM rust:latest as builder
WORKDIR /app
COPY . .
RUN cargo build --release

FROM debian:bookworm-slim
COPY --from=builder /app/target/release/{{tool_name_kebab}}-api /usr/bin/
ENTRYPOINT ["{{tool_name_kebab}}-api"]
```

## Tier 3: CLI

**Location**: `crates/{{tool_name_kebab}}-cli/`

**Purpose**: User-friendly command-line interface

### Components

#### Command Parser

**Framework**: clap (derive macros for CLI parsing)

```rust
#[derive(Parser)]
#[command(name = "{{tool_name_kebab}}")]
#[command(about = "{{TOOL_NAME}} - {{SHORT_DESCRIPTION}}")]
struct Cli {
    #[arg(short, long)]
    config: Option<PathBuf>,

    #[arg(short, long, global = true)]
    verbose: bool,

    #[command(subcommand)]
    command: Commands,
}
```

#### Configuration Discovery

**Implementation**: tools-shared library

```rust
use tools_shared::find_config_path;

let config_path = find_config_path("{{tool_name_kebab}}.toml")
    .unwrap_or_else(|| PathBuf::from(".project/{{tool_name_kebab}}.toml"));
```

**Search Order**:
1. `.project/{{tool_name_kebab}}.toml` - Tools ecosystem
2. `.vapora/{{tool_name_kebab}}.toml` - VAPORA projects
3. `.coder/{{tool_name_kebab}}.toml` - Doc tracking
4. `./{{tool_name_kebab}}.toml` - Current directory

**Help Text**:
```
CONFIGURATION SEARCH:
  Looks for config in order (uses first found):

  1. .project/{{tool_name_kebab}}.toml
  2. .vapora/{{tool_name_kebab}}.toml
  3. .coder/{{tool_name_kebab}}.toml
  4. ./{{tool_name_kebab}}.toml
```

#### Commands

Organized into subcommands:

```rust
#[derive(Subcommand)]
enum Commands {
    /// List items
    List {
        #[arg(short, long)]
        filter: Option<String>,

        #[arg(short, long, default_value = "20")]
        limit: usize,
    },

    /// Show summary
    Summary {
        #[arg(short, long)]
        group_by: Option<String>,
    },

    /// Create new item
    Create {
        name: String,

        #[arg(short, long)]
        description: Option<String>,
    },

    /// Show version
    Version,
}
```

#### Logging

Structured logging with tracing:

```rust
// Initialize
let log_level = if cli.verbose { "debug" } else { "info" };
tracing_subscriber::fmt()
    .with_env_filter(log_level)
    .init();

// Usage
tracing::info!("Starting operation");
tracing::debug!("Debug info");
tracing::warn!("Warning message");
tracing::error!("Error occurred");
```

### Data Flow

```
User runs command
    ↓
clap parses arguments
    ↓
Config discovery (tools-shared)
    ↓
Load configuration (serde + TOML)
    ↓
Validate configuration
    ↓
Initialize service from core library
    ↓
Execute command (call service method)
    ↓
Format output (JSON, table, text)
    ↓
Display to user
```

## Configuration System

### Configuration File (TOML)

**Structure**:
```toml
[{{tool_name_kebab}}]
# Main settings
setting1 = "value1"
setting2 = 42
enable_feature = true

[{{tool_name_kebab}}.advanced]
# Advanced options
max_items = 1000
timeout_seconds = 30

[database]
# If using database
type = "sqlite"
path = ".project/{{tool_name_kebab}}.db"
```

### Configuration Validation

In CLI before execution:

```rust
fn validate_config(config: &Config) -> Result<()> {
    if config.name.is_empty() {
        return Err(ConfigError::EmptyName);
    }
    if config.timeout < 0 {
        return Err(ConfigError::InvalidTimeout);
    }
    Ok(())
}
```

### Environment Variable Overrides

Support ENV vars for key settings:

```bash
export {{TOOL_NAME}}_SETTING1=value1
export {{TOOL_NAME}}_TIMEOUT=60

{{tool_name_kebab}} list
# Uses ENV values if set, otherwise config file
```

## Data Persistence

### Storage Interface

```rust
pub trait Storage {
    async fn create(&mut self, item: {{MainType}}) -> Result<()>;
    async fn get(&self, id: &str) -> Result<{{MainType}}>;
    async fn list(&self) -> Result<Vec<{{MainType}}>
    async fn update(&mut self, item: {{MainType}}) -> Result<()>;
    async fn delete(&mut self, id: &str) -> Result<()>;
}
```

### Storage Implementations

**In-Memory** (template default):
- Fast for development
- Data lost on restart
- Thread-safe with Arc<Mutex<>>

**SQLite**:
- File-based, embedded
- Good for single-user tools
- Use sqlx with async

**PostgreSQL**:
- Server-based
- Multiple concurrent users
- Use sqlx with connection pooling

## Error Propagation

```
Tier 3 (CLI)
    ↓ catches
Tier 2 (API)
    ↓ catches
Tier 1 (Core)
    ↓ propagates
Result<T, Error>
    ↓ back up
Format for user/response
```

## Testing Strategy

### Unit Tests (Tier 1)
- Test each service method
- Mock storage
- Test error conditions
- Minimum 15 tests

### Integration Tests
- Test with real storage
- Test full workflows
- Test configuration loading
- Test CLI argument parsing

### End-to-End Tests
- Test complete user workflows
- Test all commands
- Test error scenarios
- Test configuration discovery

## Performance Considerations

### Optimization Points
- Configuration caching
- Lazy loading of items
- Database connection pooling
- Async/await for all I/O

### Bottlenecks to Avoid
- Synchronous blocking I/O
- Loading all items in memory
- Repeated configuration parsing
- Unnecessary cloning

### Monitoring
- Structured logging (tracing)
- Performance metrics
- Error tracking
- Resource usage

## Security Considerations

### Input Validation
- Validate all user input
- Sanitize configuration values
- Validate file paths
- Check for path traversal

### Error Handling
- Don't expose internal paths
- Don't leak sensitive data
- Provide helpful error messages
- Log with appropriate levels

### Dependencies
- Audit external crates (cargo audit)
- Keep dependencies updated
- Minimize external unsafe code
- Pin versions in production

## Extension Points

### Adding New Commands
1. Add variant to Commands enum
2. Implement handler
3. Add tests
4. Update help text
5. Update documentation

### Adding New Service Methods
1. Implement in {{MainType}}Service
2. Add error handling
3. Add tests (success and error paths)
4. Update documentation
5. Expose in CLI or API

### Adding New Storage Backend
1. Implement Storage trait
2. Add configuration option
3. Add feature flag
4. Add tests
5. Update documentation

## Deployment Checklist

- ✅ All tests pass (cargo test --workspace)
- ✅ No clippy warnings (cargo clippy)
- ✅ Code formatted (cargo fmt)
- ✅ No vulnerabilities (cargo audit)
- ✅ Documentation complete
- ✅ Help text clear and accurate
- ✅ Configuration discoverable
- ✅ Error messages helpful

## References

- **Complete README**: [README.md](README.md)
- **Quick Start**: [QUICKSTART.md](QUICKSTART.md)
- **Configuration Guide**: [configuration.md](configuration.md)
- **Code**: `crates/{{tool_name_kebab}}-*/src/`

