239 lines
6.6 KiB
Markdown
239 lines
6.6 KiB
Markdown
|
|
# Library Migration & Code Reduction Guide
|
||
|
|
|
||
|
|
This document describes the library migrations performed to reduce custom code and leverage battle-tested Rust crates.
|
||
|
|
|
||
|
|
## Summary of Changes
|
||
|
|
|
||
|
|
| Area | Before | After | Lines Reduced |
|
||
|
|
|------|--------|-------|---------------|
|
||
|
|
| Secrets Management | Custom Vault HTTP client | `vaultrs` library | ~210 lines |
|
||
|
|
| Calendar | Custom CalendarEngine | `icalendar` (RFC 5545) | +iCal support |
|
||
|
|
| Rate Limiting | None | `governor` library | +320 lines (new feature) |
|
||
|
|
| Config | Custom parsing | `figment` available | Ready for migration |
|
||
|
|
|
||
|
|
## Security Audit Results
|
||
|
|
|
||
|
|
All new dependencies passed `cargo audit` with no vulnerabilities:
|
||
|
|
|
||
|
|
```
|
||
|
|
✅ vaultrs = "0.7" - HashiCorp Vault client
|
||
|
|
✅ icalendar = "0.17" - RFC 5545 calendar support
|
||
|
|
✅ figment = "0.10" - Layered configuration
|
||
|
|
✅ governor = "0.10" - Rate limiting
|
||
|
|
```
|
||
|
|
|
||
|
|
### Packages NOT Added (Security Issues)
|
||
|
|
|
||
|
|
| Package | Issue | Alternative |
|
||
|
|
|---------|-------|-------------|
|
||
|
|
| `openidconnect` | RSA vulnerability (RUSTSEC-2023-0071) | Keep custom Zitadel client |
|
||
|
|
| `tower-sessions-redis-store` | Unmaintained `paste` dependency | Keep custom session manager |
|
||
|
|
|
||
|
|
## Module Changes
|
||
|
|
|
||
|
|
### 1. Secrets Management (`core/secrets/mod.rs`)
|
||
|
|
|
||
|
|
**Before:** ~640 lines of custom Vault HTTP client implementation
|
||
|
|
**After:** ~490 lines using `vaultrs` library
|
||
|
|
|
||
|
|
#### Key Changes:
|
||
|
|
- Replaced custom HTTP calls with `vaultrs::kv2` operations
|
||
|
|
- Simplified caching logic
|
||
|
|
- Maintained full API compatibility
|
||
|
|
- Environment variable fallback preserved
|
||
|
|
|
||
|
|
#### Usage (unchanged):
|
||
|
|
```rust
|
||
|
|
use botserver::core::secrets::{SecretsManager, SecretPaths};
|
||
|
|
|
||
|
|
let manager = SecretsManager::from_env()?;
|
||
|
|
let db_config = manager.get_database_config().await?;
|
||
|
|
let llm_key = manager.get_llm_api_key("openai").await?;
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2. Calendar Module (`calendar/mod.rs`)
|
||
|
|
|
||
|
|
**Before:** Custom event storage with no standard format support
|
||
|
|
**After:** Full iCal (RFC 5545) import/export support
|
||
|
|
|
||
|
|
#### New Features:
|
||
|
|
- `export_to_ical()` - Export events to .ics format
|
||
|
|
- `import_from_ical()` - Import events from .ics files
|
||
|
|
- Standard recurrence rule support (RRULE)
|
||
|
|
- Attendee and organizer handling
|
||
|
|
|
||
|
|
#### Usage:
|
||
|
|
```rust
|
||
|
|
use botserver::calendar::{CalendarEngine, CalendarEventInput, export_to_ical};
|
||
|
|
|
||
|
|
let mut engine = CalendarEngine::new();
|
||
|
|
let event = engine.create_event(CalendarEventInput {
|
||
|
|
title: "Team Meeting".to_string(),
|
||
|
|
start_time: Utc::now(),
|
||
|
|
end_time: Utc::now() + Duration::hours(1),
|
||
|
|
organizer: "user@example.com".to_string(),
|
||
|
|
// ...
|
||
|
|
});
|
||
|
|
|
||
|
|
// Export to iCal format
|
||
|
|
let ical_string = engine.export_ical("My Calendar");
|
||
|
|
|
||
|
|
// Import from iCal
|
||
|
|
let count = engine.import_ical(&ical_content, "organizer@example.com");
|
||
|
|
```
|
||
|
|
|
||
|
|
#### New API Endpoints:
|
||
|
|
- `GET /api/calendar/export.ics` - Download calendar as iCal
|
||
|
|
- `POST /api/calendar/import` - Import iCal file
|
||
|
|
|
||
|
|
### 3. Rate Limiting (`core/rate_limit.rs`)
|
||
|
|
|
||
|
|
**New module** providing API rate limiting using `governor`.
|
||
|
|
|
||
|
|
#### Features:
|
||
|
|
- Per-IP rate limiting
|
||
|
|
- Tiered limits for different endpoint types:
|
||
|
|
- **API endpoints:** 100 req/s (burst: 200)
|
||
|
|
- **Auth endpoints:** 10 req/s (burst: 20)
|
||
|
|
- **LLM endpoints:** 5 req/s (burst: 10)
|
||
|
|
- Automatic cleanup of stale limiters
|
||
|
|
- Configurable via environment variables
|
||
|
|
|
||
|
|
#### Configuration:
|
||
|
|
```bash
|
||
|
|
RATE_LIMIT_ENABLED=true
|
||
|
|
RATE_LIMIT_API_RPS=100
|
||
|
|
RATE_LIMIT_API_BURST=200
|
||
|
|
RATE_LIMIT_AUTH_RPS=10
|
||
|
|
RATE_LIMIT_AUTH_BURST=20
|
||
|
|
RATE_LIMIT_LLM_RPS=5
|
||
|
|
RATE_LIMIT_LLM_BURST=10
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Usage in Router:
|
||
|
|
```rust
|
||
|
|
use botserver::core::rate_limit::{RateLimitConfig, RateLimitState, rate_limit_middleware};
|
||
|
|
use std::sync::Arc;
|
||
|
|
|
||
|
|
let rate_limit_state = Arc::new(RateLimitState::from_env());
|
||
|
|
|
||
|
|
let app = Router::new()
|
||
|
|
.merge(api_routes)
|
||
|
|
.layer(axum::middleware::from_fn_with_state(
|
||
|
|
rate_limit_state,
|
||
|
|
rate_limit_middleware
|
||
|
|
));
|
||
|
|
```
|
||
|
|
|
||
|
|
## Dependencies Added to Cargo.toml
|
||
|
|
|
||
|
|
```toml
|
||
|
|
# Vault secrets management
|
||
|
|
vaultrs = "0.7"
|
||
|
|
|
||
|
|
# Calendar standards (RFC 5545)
|
||
|
|
icalendar = "0.17"
|
||
|
|
|
||
|
|
# Layered configuration
|
||
|
|
figment = { version = "0.10", features = ["toml", "env", "json"] }
|
||
|
|
|
||
|
|
# Rate limiting
|
||
|
|
governor = "0.10"
|
||
|
|
```
|
||
|
|
|
||
|
|
## Future Migration Opportunities
|
||
|
|
|
||
|
|
These libraries are available and audited, ready for future use:
|
||
|
|
|
||
|
|
### 1. Configuration with Figment
|
||
|
|
|
||
|
|
Replace custom `ConfigManager` with layered configuration:
|
||
|
|
|
||
|
|
```rust
|
||
|
|
use figment::{Figment, providers::{Env, Toml, Format}};
|
||
|
|
|
||
|
|
let config: AppConfig = Figment::new()
|
||
|
|
.merge(Toml::file("config.toml"))
|
||
|
|
.merge(Env::prefixed("GB_"))
|
||
|
|
.extract()?;
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2. Observability with OpenTelemetry
|
||
|
|
|
||
|
|
```toml
|
||
|
|
opentelemetry = "0.31"
|
||
|
|
tracing-opentelemetry = "0.32"
|
||
|
|
```
|
||
|
|
|
||
|
|
## Packages Kept (Good Choices)
|
||
|
|
|
||
|
|
These existing dependencies are optimal and should be kept:
|
||
|
|
|
||
|
|
| Package | Purpose | Notes |
|
||
|
|
|---------|---------|-------|
|
||
|
|
| `axum` | Web framework | Excellent async support |
|
||
|
|
| `diesel` | Database ORM | Type-safe queries |
|
||
|
|
| `rhai` | Scripting | Perfect for BASIC dialect |
|
||
|
|
| `qdrant-client` | Vector DB | Native Rust client |
|
||
|
|
| `rcgen` + `rustls` | TLS/Certs | Good for internal CA |
|
||
|
|
| `lettre` + `imap` | Email | Standard choices |
|
||
|
|
| `tauri` | Desktop UI | Cross-platform |
|
||
|
|
| `livekit` | Video meetings | Native SDK |
|
||
|
|
|
||
|
|
## Testing
|
||
|
|
|
||
|
|
All new code includes unit tests:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Run tests for specific modules
|
||
|
|
cargo test --lib secrets
|
||
|
|
cargo test --lib calendar
|
||
|
|
cargo test --lib rate_limit
|
||
|
|
```
|
||
|
|
|
||
|
|
## HTTP Client Consolidation
|
||
|
|
|
||
|
|
The HTTP client is already properly consolidated:
|
||
|
|
|
||
|
|
- **botlib:** Contains the canonical `BotServerClient` implementation
|
||
|
|
- **botui:** Re-exports from botlib (no duplication)
|
||
|
|
- **botserver:** Uses `reqwest` directly for external API calls
|
||
|
|
|
||
|
|
This architecture ensures:
|
||
|
|
- Single source of truth for HTTP client logic
|
||
|
|
- Consistent timeout and retry behavior
|
||
|
|
- Unified error handling across all projects
|
||
|
|
|
||
|
|
## Backward Compatibility
|
||
|
|
|
||
|
|
All changes maintain backward compatibility:
|
||
|
|
- Existing API signatures preserved
|
||
|
|
- Environment variable names unchanged
|
||
|
|
- Database schemas unaffected
|
||
|
|
- Configuration file formats unchanged
|
||
|
|
|
||
|
|
## Code Metrics
|
||
|
|
|
||
|
|
| Project | Before | After | Reduction |
|
||
|
|
|---------|--------|-------|-----------|
|
||
|
|
| `botserver/src/core/secrets/mod.rs` | 747 lines | 493 lines | **254 lines (-34%)** |
|
||
|
|
| `botserver/src/calendar/mod.rs` | 227 lines | 360 lines | +133 lines (new features) |
|
||
|
|
| `botserver/src/core/rate_limit.rs` | 0 lines | 319 lines | +319 lines (new feature) |
|
||
|
|
|
||
|
|
**Net effect:** Reduced custom code while adding RFC 5545 calendar support and rate limiting.
|
||
|
|
|
||
|
|
## Dependencies Summary
|
||
|
|
|
||
|
|
### Added (Cargo.toml)
|
||
|
|
```toml
|
||
|
|
vaultrs = "0.7"
|
||
|
|
icalendar = "0.17"
|
||
|
|
figment = { version = "0.10", features = ["toml", "env", "json"] }
|
||
|
|
governor = "0.10"
|
||
|
|
```
|
||
|
|
|
||
|
|
### Existing (No Changes Needed)
|
||
|
|
- `reqwest` - HTTP client (already in use)
|
||
|
|
- `redis` - Caching (already in use)
|
||
|
|
- `diesel` - Database ORM (already in use)
|
||
|
|
- `tokio` - Async runtime (already in use)
|