Architecture: Session 179: How should the Vitto desktop app toggle between...
Documentation for Sessions
🏗️ Architecture: Session 179: How should the Vitto desktop app toggle between...
Date: 2026-03-06
Time: 15:57:39 UTC
Session: gspace1-179.5
Agent: angular
Confidence: 95%
Status: ✅ Documented
📋 Decision Context
Question:
Session 179: How should the Vitto desktop app toggle between production and development API environments at runtime?
Task: Implement dev/prod runtime toggle for Vitto desktop
🎯 Decision Made
Chosen:
Three-layer approach: (1) localStorage flag 'vitto-dev-mode' read at bootstrap by provideApiConfig() to override DI tokens (AI_API_URL, API_BASE_URL, etc.), (2) HTTP interceptor (devModeInterceptor) rewrites any remaining prod URLs to localhost, (3) passphrase-gated UI toggle in the header with inline input (not window.prompt). Default is production.
Options Considered:
- Build two separate binaries (dev + prod)
- HTTP interceptor only (insufficient — DI tokens not rewritten)
- DI token override at bootstrap + interceptor (chosen)
- Environment variable passed via Tauri CLI args
💭 Reasoning
Root cause of need: production Tauri builds hardcode environment.prod.ts URLs at compile time. Developers testing locally need localhost:300x endpoints without rebuilding the entire app (2+ min Rust compile). The Chrome extension solved this with a passphrase-gated toggle (Session 147) — same pattern adapted for desktop. Key architectural decision: DI tokens (InjectionToken) in Angular are resolved once at bootstrap and are immutable afterward. An HTTP interceptor alone wouldn't fix services like ApiConnectivityService that read AI_API_URL directly (not via HTTP). Solution: read localStorage BEFORE Angular DI resolves in app.config.ts, pass the correct URLs to provideApiConfig(). The interceptor acts as defense-in-depth for any URLs that bypass the DI system. window.prompt() was tried first but doesn't work in Tauri's WKWebView — replaced with signal-based inline input. What would make this wrong: if Angular changes DI resolution to be lazy/deferred, or if Tauri changes its webview origin scheme again.
📁 Files Involved
apps/gograb-ai/src/app/core/services/dev-mode.service.tsapps/gograb-ai/src/app/core/interceptors/dev-mode.interceptor.tsapps/gograb-ai/src/app/app.config.tsapps/gograb-ai/src/app/app.component.htmlapps/gograb-ai/src/app/app.component.ts
🔗 Related
- Decision ID:
dev_1772812659349_oxamtfr - Session: 179
- Workspace: gspace1
Auto-generated by MCP Smart Consolidation