# Playground Binary Implementation Plan | Item | Content | |------|---------| | Author | Warren | | Created | 2026-03-23 | | Document Version | V1.0 | --- ## Version History | Version | Date | Purpose | Operator | Tool/Model | |---------|------|---------|----------|------------| | V1.0 | 2026-03-23 | Create implementation plan | Warren | OpenCode | --- ## Overview Create separate `momentry_playground` binary with distinct configuration from `momentry` (production). | Aspect | Production (`momentry`) | Development (`momentry_playground`) | |--------|------------------------|-------------------------------------| | **Port** | 3002 | 3003 | | **Redis Prefix** | `momentry:` | `momentry_dev:` | | **Worker** | Enabled | Disabled | | **Purpose** | Production deployment | Testing/Development | --- ## Files to Modify ``` Files Changed: 6 files (+1 new) ├── src/core/config.rs ← Add server_port(), redis_key_prefix() ├── src/core/db/redis_client.rs ← Replace hardcoded prefixes ├── src/core/cache/redis_cache.rs ← Use configurable prefix ├── src/main.rs ← Update CLI defaults ├── src/playground.rs ← NEW: Development binary ├── Cargo.toml ← Add new binary └── .env.development ← NEW: Dev environment config ``` --- ## Implementation Steps ### Step 1: Update `src/core/config.rs` Add after line 51 (after `MEDIA_BASE_URL`): ```rust pub static SERVER_PORT: Lazy = Lazy::new(|| { env::var("MOMENTRY_SERVER_PORT") .unwrap_or_else(|_| "3002".to_string()) .parse() .unwrap_or(3002) }); pub static REDIS_KEY_PREFIX: Lazy = Lazy::new(|| { env::var("MOMENTRY_REDIS_PREFIX") .unwrap_or_else(|_| "momentry:".to_string()) }); ``` --- ### Step 2: Update `src/core/db/redis_client.rs` Replace all hardcoded `momentry:` prefixes with configurable prefix. **Import at top:** ```rust use crate::core::config::REDIS_KEY_PREFIX; ``` **Pattern for each method:** ```rust let prefix = REDIS_KEY_PREFIX.as_str(); let key = format!("{}job:{}", prefix, uuid); ``` **Affected lines:** | Line | Key Pattern | |------|-------------| | 47 | `job:{uuid}` | | 81, 109 | `job:{uuid}:processor:{processor}` | | 136, 146 | `progress:{uuid}` | | 172 | `jobs:active` | | 179 | `jobs:active` → `jobs:completed` | | 187 | `jobs:active` → `jobs:failed` | | 194 | `jobs:active` | | 201, 208 | `health:momentry_core` | | 214 | `monitor:job:{uuid}` | | 242, 300 | `errors:{uuid}` | | 258, 281 | `anomaly:alerts`, `anomaly:key:{key_id}` | | 317, 346, 364, 392, 397 | `worker:job:{uuid}...` | | 406, 410 | `worker:job:*` | --- ### Step 3: Update `src/core/cache/redis_cache.rs` **Import:** ```rust use crate::core::config::REDIS_KEY_PREFIX; ``` **Replace line 10:** ```rust // Remove: const KEY_PREFIX: &str = "momentry:cache:"; ``` **Update `prefixed_key` method (line 24):** ```rust fn prefixed_key(&self, key: &str) -> String { format!("{}cache:{}", REDIS_KEY_PREFIX.as_str(), key) } ``` **Update tests (lines 161-162):** ```rust #[test] fn test_prefixed_key() { // Note: This test will use the configured prefix let cache = RedisCache::new().unwrap(); // With default prefix "momentry:" assert_eq!(cache.prefixed_key("test"), "momentry:cache:test"); assert_eq!(cache.prefixed_key("video:abc"), "momentry:cache:video:abc"); } ``` --- ### Step 4: Update `src/main.rs` **Change CLI defaults (Lines 691-695):** ```rust // Before: #[arg(long, default_value = "3000")] port: u16, // After: #[arg(long)] port: Option, ``` **Update Server match arm (around line 2398):** ```rust Commands::Server { host, port } => { let port = port.unwrap_or_else(|| *crate::core::config::SERVER_PORT); momentry_core::api::start_server(&host, port).await?; Ok(()) } ``` **Update Redis key usage (Line 1098):** ```rust // Before: let key = format!("momentry:job:{}:processor:{}", uuid, processor); // After: let key = format!( "{}job:{}:processor:{}", crate::core::config::REDIS_KEY_PREFIX.as_str(), uuid, processor ); ``` --- ### Step 5: Create `src/playground.rs` ```rust use anyhow::{Context, Result}; use clap::{Parser, Subcommand}; // ... same imports as main.rs ... fn main() -> Result<()> { // Load development environment first dotenv::from_filename(".env.development").ok(); tracing_subscriber::fmt::init(); tracing::info!("Starting momentry_playground (development binary)"); tracing::info!("Port: {}", *momentry_core::core::config::SERVER_PORT); tracing::info!("Redis prefix: {}", *momentry_core::core::config::REDIS_KEY_PREFIX); let cli = Cli::parse(); // ... rest identical to main.rs ... } ``` --- ### Step 6: Update `Cargo.toml` **Add after line 90:** ```toml [[bin]] name = "momentry_playground" path = "src/playground.rs" ``` **Add dependency (if not present):** ```toml dotenv = "0.15" ``` --- ### Step 7: Create `.env.development` ```bash # Development Environment Configuration # Used by: momentry_playground binary # Server Configuration MOMENTRY_SERVER_PORT=3003 MOMENTRY_REDIS_PREFIX=momentry_dev: # Worker Configuration (disabled for development) MOMENTRY_WORKER_ENABLED=false MOMENTRY_MAX_CONCURRENT=1 MOMENTRY_POLL_INTERVAL=10 # Database (can use separate dev database) DATABASE_URL=postgres://accusys@localhost:5432/momentry MONGODB_URL=mongodb://accusys:Test3200Test3200@localhost:27017/admin # Redis REDIS_URL=redis://:accusys@localhost:6379 ``` --- ### Step 8: Update `.env` (Production) Add these lines: ```bash # Production Environment Configuration # Used by: momentry binary # Server Configuration MOMENTRY_SERVER_PORT=3002 MOMENTRY_REDIS_PREFIX=momentry: # Worker Configuration MOMENTRY_WORKER_ENABLED=true MOMENTRY_MAX_CONCURRENT=2 MOMENTRY_POLL_INTERVAL=5 ``` --- ## Testing Checklist ### 1. Build and Run Production Binary ```bash cargo build --release --bin momentry cargo run --bin momentry -- server # Expected: Listening on http://127.0.0.1:3002 cargo run --bin momentry -- worker # Expected: Worker started with momentry: prefix ``` ### 2. Build and Run Development Binary ```bash cargo build --bin momentry_playground cargo run --bin momentry_playground -- server # Expected: Listening on http://127.0.0.1:3003 ``` ### 3. Verify Redis Key Isolation ```bash # Production data redis-cli KEYS "momentry:*" # Development data redis-cli KEYS "momentry_dev:*" # Should be separate ``` ### 4. Run Both Simultaneously ```bash # Terminal 1: Production cargo run --bin momentry -- server # Terminal 2: Development cargo run --bin momentry_playground -- server # Both should run without port conflicts ``` ### 5. Unit Tests ```bash cargo test --lib # All tests should pass ``` --- ## Redis Key Structure ### Production (`momentry:`) ``` momentry:job:{uuid} # Job status momentry:job:{uuid}:processor:{name} # Processor progress momentry:progress:{uuid} # Progress pub/sub momentry:jobs:active # Active job set momentry:jobs:completed # Completed job set momentry:jobs:failed # Failed job set momentry:health:momentry_core # Health status momentry:cache:{key} # Cache entries momentry:worker:job:{uuid} # Worker job momentry:worker:job:{uuid}:processor:{name} ``` ### Development (`momentry_dev:`) ``` momentry_dev:job:{uuid} momentry_dev:job:{uuid}:processor:{name} momentry_dev:progress:{uuid} momentry_dev:jobs:active momentry_dev:jobs:completed momentry_dev:jobs:failed momentry_dev:health:momentry_core momentry_dev:cache:{key} momentry_dev:worker:job:{uuid} momentry_dev:worker:job:{uuid}:processor:{name} ``` --- ## Potential Issues & Solutions | Issue | Solution | |-------|----------| | `dotenv` crate not in dependencies | Add to Cargo.toml | | Tests use hardcoded prefix | Update tests to use config, or use `#[cfg(test)]` defaults | | Worker starts in playground | Check `MOMENTRY_WORKER_ENABLED=false` in `.env.development` | | Port already in use | Graceful error message with suggestion to use `--port` flag | | Mixed data in Redis | Ensure prefix is loaded before any Redis operations | --- ## Files Summary | File | Lines Changed | Purpose | |------|---------------|---------| | `src/core/config.rs` | +15 | Add SERVER_PORT and REDIS_KEY_PREFIX | | `src/core/db/redis_client.rs` | ~50 | Replace hardcoded prefixes | | `src/core/cache/redis_cache.rs` | ~10 | Use configurable prefix | | `src/main.rs` | ~15 | Update CLI defaults, Redis key usage | | `src/playground.rs` | NEW (~2800) | Development binary | | `Cargo.toml` | +4 | Add binary definition | | `.env.development` | NEW (~20) | Development environment | **Total**: ~60 lines modified + ~2800 lines new file --- ## Reference Documents | Document | Purpose | |----------|---------| | `docs/SERVICES.md` | Port allocations | | `docs/MOMENTRY_CORE_REDIS_KEYS.md` | Redis key design | | `AGENTS.md` | Code style and conventions | --- ## Version History | Version | Date | Author | Changes | |---------|------|--------|---------| | 1.0 | 2025-03-25 | OpenCode | Initial implementation plan |