# embedded-backend Specification ## Purpose TBD - created by archiving change add-embedded-backend-packaging. Update Purpose after archive. ## Requirements ### Requirement: Embedded Backend Packaging The FastAPI backend SHALL be packaged as a standalone executable using PyInstaller for all-in-one deployment. #### Scenario: Backend executable creation - **WHEN** build script runs with embedded backend flag - **THEN** PyInstaller SHALL create `backend/dist/backend/backend.exe` containing FastAPI, uvicorn, and all dependencies #### Scenario: Backend executable startup - **WHEN** backend executable is launched - **THEN** it SHALL read configuration from `config.json` in the same directory - **AND** start uvicorn server on configured host and port ### Requirement: Electron Backend Sidecar Management The Electron main process SHALL manage the embedded backend as a sidecar process. #### Scenario: Start backend on app launch - **WHEN** Electron app launches with `backend.embedded: true` in config - **THEN** main process SHALL spawn backend executable as child process - **AND** pass configuration via environment variables #### Scenario: Skip backend when disabled - **WHEN** Electron app launches with `backend.embedded: false` in config - **THEN** main process SHALL NOT spawn backend executable - **AND** frontend SHALL connect to remote backend via `apiBaseUrl` #### Scenario: Terminate backend on app close - **WHEN** user closes Electron app - **THEN** main process SHALL send SIGTERM to backend process - **AND** force kill after 5 seconds if still running ### Requirement: Backend Health Check The Electron main process SHALL verify backend readiness before showing the main window. #### Scenario: Health check success - **WHEN** backend `/api/health` returns HTTP 200 - **THEN** main process SHALL proceed to create main window - **AND** set `backendReady` state to true #### Scenario: Health check timeout - **WHEN** backend does not respond within 30 seconds (30 attempts, 1s interval) - **THEN** main process SHALL display error dialog - **AND** log detailed error for debugging #### Scenario: Health check polling - **WHEN** health check attempt fails - **THEN** main process SHALL retry after 1 second - **AND** log attempt number for debugging ### Requirement: Unified Configuration Schema All configuration for frontend, backend, and whisper SHALL be in a single `config.json` file. #### Scenario: Backend configuration loading - **WHEN** backend sidecar starts - **THEN** it SHALL read database type from `config.json` backend.database.type section - **AND** read SQLite path from `config.json` backend.database.sqlitePath section (if SQLite mode) - **AND** read database credentials from `config.json` backend.database section (if MySQL mode) - **AND** read API keys from `config.json` backend.externalApis section - **AND** read auth settings from `config.json` backend.auth section #### Scenario: Configuration priority - **WHEN** both environment variable and config.json value exist - **THEN** environment variable SHALL take precedence #### Scenario: Default values - **WHEN** configuration value is not specified - **THEN** system SHALL use sensible defaults (host: 127.0.0.1, port: 8000, database.type: mysql) ### Requirement: Backend Status API The Electron app SHALL expose backend status to the renderer process. #### Scenario: Get backend status - **WHEN** renderer calls `window.electronAPI.getBackendStatus()` - **THEN** it SHALL return object with `ready` boolean and `url` string #### Scenario: Backend status in UI - **WHEN** backend is starting - **THEN** UI MAY display loading indicator ### Requirement: Backward Compatibility The embedded backend feature SHALL NOT break existing separate-deployment mode. #### Scenario: Separate deployment unchanged - **WHEN** `backend.embedded` is false or undefined - **THEN** system SHALL behave exactly as before this change - **AND** frontend connects to `apiBaseUrl` without spawning local backend #### Scenario: Existing scripts work - **WHEN** user runs `./start.sh start` or `./scripts/setup-backend.sh` - **THEN** backend SHALL start normally as standalone server ### Requirement: SQLite Database Support The backend SHALL support SQLite as an alternative to MySQL for offline/standalone deployments. #### Scenario: SQLite mode initialization - **WHEN** `database.type` is set to `"sqlite"` in config.json - **THEN** backend SHALL create SQLite database at `database.sqlitePath` - **AND** initialize all required tables using SQLite-compatible syntax #### Scenario: MySQL mode initialization - **WHEN** `database.type` is set to `"mysql"` or not specified in config.json - **THEN** backend SHALL connect to MySQL using credentials from `database` section - **AND** behave exactly as before this change #### Scenario: SQLite thread safety - **WHEN** multiple concurrent requests access SQLite database - **THEN** backend SHALL use thread lock to serialize database operations - **AND** use `check_same_thread=False` for SQLite connection #### Scenario: SQLite data persistence - **WHEN** app is closed and reopened - **THEN** all meeting data SHALL persist in SQLite file - **AND** be accessible on next launch ### Requirement: Portable Extraction Path Configuration The portable Windows build SHALL extract to a predictable folder name. #### Scenario: Fixed extraction folder - **WHEN** portable executable starts - **THEN** it SHALL extract to `%TEMP%\Meeting-Assistant` instead of random UUID folder #### Scenario: Windows Defender consistency - **WHEN** user launches portable executable multiple times - **THEN** Windows Defender SHALL NOT prompt for permission each time - **BECAUSE** extraction path is consistent across launches