# RFCP Native Backend Research ## Executive Summary **Finding:** The production Electron app already supports native Windows operation without WSL2. The production build uses PyInstaller to bundle the Python backend as a standalone Windows executable (`rfcp-server.exe`). WSL2 is only used during development. No migration is needed for end users. --- ## Current Architecture ### Development Mode ``` RFCP (Electron dev) └── Spawns: python -m uvicorn app.main:app --host 127.0.0.1 --port 8090 └── Uses system Python (Windows or WSL2) └── Requires venv with dependencies ``` ### Production Mode (Already Implemented) ``` RFCP.exe (Electron packaged) └── Spawns: rfcp-server.exe (bundled PyInstaller binary) └── Self-contained Python + all dependencies └── No WSL2 required └── No system Python required ``` --- ## Evidence from Codebase ### desktop/main.js (Lines 120-145) ```javascript function startBackend() { // Production: use bundled executable if (isProduction) { const serverPath = path.join(process.resourcesPath, 'rfcp-server.exe'); if (fs.existsSync(serverPath)) { backendProcess = spawn(serverPath, [], { ... }); return; } } // Development: use system Python backendProcess = spawn('python', ['-m', 'uvicorn', 'app.main:app', ...]); } ``` ### installer/rfcp-server.spec (PyInstaller Config) ```python # Key configuration a = Analysis( ['run_server.py'], pathex=[backend_path], binaries=[], datas=[ ('data/terrain', 'data/terrain'), # Terrain data bundled ], hiddenimports=[ 'uvicorn.logging', 'uvicorn.loops', 'uvicorn.protocols', 'motor', 'pymongo', 'numpy', 'scipy', 'shapely', # Full list of dependencies ], ) exe = EXE( pyz, a.scripts, name='rfcp-server', console=True, # Shows console for debugging icon='rfcp.ico', ) ``` --- ## GPU Acceleration in Production ### Current Status The PyInstaller bundle **does not include CuPy** by default because: 1. CuPy requires CUDA runtime (large, ~500MB) 2. Not all users have NVIDIA GPUs 3. Binary would be too large for distribution ### Solution Options **Option A: Ship CPU-only (Current)** - Production build uses NumPy (CPU) for calculations - GPU acceleration available only in dev mode or manual install - Smallest download size (~100MB) **Option B: Separate GPU Installer** - Main installer: CPU-only (~100MB) - Optional GPU addon: Downloads CuPy + CUDA runtime (~600MB) - Implemented via install_rfcp.py dependency installer **Option C: CUDA Toolkit Detection** - Detect if CUDA is already installed on user's system - If yes, attempt to load CuPy dynamically - Graceful fallback to NumPy if not available ### Recommendation Keep Option A (CPU-only production) with Option B available for power users: 1. Default production build works everywhere 2. Users with NVIDIA GPUs can run `install_rfcp.py` to enable GPU acceleration 3. No WSL2 required for either path --- ## Terrain Data Handling ### Current Implementation Terrain data (SRTM .hgt files) is bundled inside the PyInstaller executable: ```python datas=[ ('data/terrain', 'data/terrain'), ] ``` ### Considerations - Bundled terrain data increases exe size significantly - Alternative: Download terrain on first use (like current region download system) - For initial release, bundling common regions is acceptable --- ## Database (MongoDB) ### Production Architecture The Electron app embeds MongoDB or requires MongoDB to be installed separately. Options: 1. **Embedded MongoDB** - Ships mongod.exe with the app 2. **MongoDB Atlas** - Cloud database (requires internet) 3. **SQLite** - Switch to file-based database (significant refactor) 4. **In-memory + file persistence** - No MongoDB required (significant refactor) Current implementation uses Motor (async MongoDB driver). For true standalone operation, consider SQLite migration in future iteration. --- ## Build Process ### Current Build Commands ```bash # Build backend executable cd /mnt/d/root/rfcp/backend pyinstaller ../installer/rfcp-server.spec # Build Electron app with bundled backend cd /mnt/d/root/rfcp/installer ./build-win.sh ``` ### Output - `rfcp-server.exe` - Standalone backend (~80MB) - `RFCP-Setup-{version}.exe` - Full installer with Electron + backend (~150MB) --- ## Testing Native Build ### Test Procedure 1. Build `rfcp-server.exe` via PyInstaller 2. Run directly: `./rfcp-server.exe` 3. Verify API responds: `curl http://localhost:8090/api/health` 4. Verify coverage calculation works 5. Check GPU detection in logs ### Known Issues 1. **First launch slow**: PyInstaller extracts on first run (~5-10 seconds) 2. **Antivirus false positives**: Some AV flags PyInstaller executables 3. **Console window**: Shows black console (use `console=False` for windowless) --- ## Conclusions ### No Migration Needed The production Electron app already works without WSL2. The current architecture is: - ✅ Native Windows executable - ✅ No Python installation required - ✅ No WSL2 required - ✅ Self-contained dependencies ### Development vs Production | Aspect | Development | Production | |--------|-------------|------------| | Python | System Python / venv | Bundled via PyInstaller | | WSL2 | Optional (for testing) | Not required | | GPU | CuPy if installed | CPU-only (NumPy) | | MongoDB | Local instance | Embedded or Atlas | | Terrain | Local data/ folder | Bundled in exe | ### Remaining Work 1. **GPU for production**: Implement Optional GPU addon installer 2. **Smaller package**: On-demand terrain download instead of bundling 3. **Database portability**: Consider SQLite migration for offline-first 4. **Installer polish**: Signed executables, auto-update support --- ## Appendix: Full PyInstaller Hidden Imports From `installer/rfcp-server.spec`: ```python hiddenimports=[ 'uvicorn.logging', 'uvicorn.loops', 'uvicorn.loops.auto', 'uvicorn.protocols', 'uvicorn.protocols.http', 'uvicorn.protocols.http.auto', 'uvicorn.protocols.websockets', 'uvicorn.protocols.websockets.auto', 'uvicorn.lifespan', 'uvicorn.lifespan.on', 'motor', 'pymongo', 'numpy', 'scipy', 'shapely', 'shapely.geometry', 'shapely.ops', # ... additional imports ] ```