stt-cli 0.2.1

Speech to text Cli using Groq API and OpenAI API
# Migration Plan: Hexagonal Architecture for TTS-Groq

## 1. Overview
This document outlines a step-by-step plan to migrate TTS-Groq to a robust hexagonal (ports & adapters) architecture, leveraging Rust's trait system for maximum modularity, testability, and extensibility.

---

## 2. Hexagonal Architecture Principles (Rust Context)
- **Domain/Core:** Pure business logic, no dependencies on external systems. All dependencies are expressed as traits (ports).
- **Ports:** Traits defining interfaces for inbound (driven by) and outbound (driving) adapters.
- **Adapters:** Implementations of ports (e.g., for providers, audio devices, platform insertion, hotkey handling).
- **Dependency Direction:** Domain depends only on traits/ports; adapters depend on domain traits, not vice versa.
- **Testability:** Core logic can be tested with mock adapters.

---

## 3. Mapping TTS-Groq to Hexagonal Layers
- **Domain Layer:** Core transcription logic, state, and use cases (traits and structs).
- **Application Layer:** Orchestrates domain logic, manages tasks, coordinates adapters.
- **Ports:**
  - Inbound: Hotkey events, CLI/config, user commands.
  - Outbound: Audio capture, transcription provider, text insertion, logging, shutdown.
- **Adapters:**
  - Inbound: Hotkey service, CLI parser.
  - Outbound: Audio device manager, provider implementations, platform text inserter, logging, shutdown handler.

---

## 4. Step-by-Step Migration Plan

### A. Inventory and Refine Traits (Ports)
- List all traits: `TranscriptionProvider`, `TextInserter`, `TranscriptionResultHandler`, etc.
- Add/Refine traits for:
  - Audio capture
  - Hotkey event source
  - Shutdown signaling

### B. Create `domain/` Module
- Move all core business logic and trait definitions here.
- Ensure domain logic depends only on traits, not concrete implementations.

### C. Create `adapters/` Module
- Move all platform, provider, audio, hotkey, and shutdown implementations here, grouped by concern.
- Each adapter implements the corresponding port (trait).

### D. Refactor Application Layer
- `app.rs` becomes the application service, orchestrating domain and adapters.
- Application layer wires together domain logic and adapters via trait objects.

### E. Implement Dependency Injection
- Use constructor injection for adapters (pass trait objects to domain/application structs).
- Use `Arc<dyn Trait + Send + Sync>` for async/multithreaded contexts as needed.

### F. Testing
- Provide mock implementations for all ports for unit/integration testing.
- Ensure all domain logic is testable without real adapters.

### G. Proposed Directory Structure

```
src/
  domain/
    mod.rs
    transcription.rs
    audio.rs
    hotkey.rs
    provider.rs
    platform.rs
    shutdown.rs
  application/
    app.rs
    orchestrator.rs
  adapters/
    audio/
      cpal_audio.rs
    provider/
      groq.rs
      openai.rs
      mock.rs
    platform/
      windows.rs
      linux.rs
      macos.rs
      stub.rs
    hotkey/
      hotkey_service.rs
    shutdown/
      shutdown_handler.rs
  main.rs
```

### H. Example Trait (Port) Definition
```rust
// domain/provider.rs
pub trait TranscriptionProvider: Send + Sync {
    fn transcribe(&self, audio_chunk: AudioChunk) -> Result<TranscriptionResult, ProviderError>;
}
```

### I. Example Adapter Implementation
```rust
// adapters/provider/groq.rs
use crate::domain::provider::{TranscriptionProvider, AudioChunk, TranscriptionResult, ProviderError};

pub struct GroqProvider { /* fields */ }

impl TranscriptionProvider for GroqProvider {
    fn transcribe(&self, audio_chunk: AudioChunk) -> Result<TranscriptionResult, ProviderError> {
        // Implementation
    }
}
```

### J. Application Layer Wiring
```rust
// application/app.rs
use crate::domain::provider::TranscriptionProvider;

pub struct App {
    provider: Box<dyn TranscriptionProvider>,
    // other fields
}

impl App {
    pub fn new(provider: Box<dyn TranscriptionProvider>, /* ... */) -> Self {
        // ...
    }
}
```

---

## 5. Migration Steps
1. **Inventory Existing Traits:** List all traits and identify missing ports.
2. **Create `domain` Module:** Move/refactor all domain logic and trait definitions here.
3. **Create `adapters` Module:** Move all concrete implementations here, grouped by concern.
4. **Refactor Application Layer:** Ensure orchestration is via trait objects only.
5. **Update Dependency Injection:** Refactor constructors to accept trait objects.
6. **Write/Update Tests:** Use mocks for all ports; ensure coverage of edge cases.
7. **Iterate and Validate:** Refactor incrementally, running tests after each step.
8. **Document Migration:** Update documentation to reflect new architecture.

---

## 6. Boundary Cases and Robustness
- Ensure all async boundaries are handled with trait bounds (`Send + Sync`).
- Graceful shutdown: propagate cancellation through trait-based signals.
- Hotkey and audio device errors: handle and propagate via Result types.
- Platform-specific adapters: ensure fallback/stub implementations for unsupported platforms.
- Test with multiple providers and platforms, including failure scenarios.

---

## 7. Testing and Validation
- Write integration tests that use mock adapters to simulate all edge cases.
- Test shutdown and error propagation paths thoroughly.
- Validate that new providers and platforms can be added with minimal changes.

---

## 8. References
- See `docs/README.md`, `docs/modules.md`, and `docs/architecture.md` for current design and module details.

---

**Follow this plan incrementally and rigorously test after each step to ensure a robust migration to hexagonal architecture.**