# Architecture ## Overview The project is a single-service web application that provides operational control and observability for a remote Bitcoin Core node. Core runtime components: - FastAPI server for UI and API delivery. - Session-based authentication middleware. - SQLite persistence for node settings and sampled metrics. - Bitcoin Core JSON-RPC client for node data and RPC execution. - SSH command runner for daemon start and restart operations. - Vanilla JavaScript frontend with Chart.js visualizations. Related references: - API contracts: `doc/api.md` - Persistence schema: `doc/data-models.md` - Deployment rules: `doc/build-and-deploy.md` ## Component Boundaries ### Backend Modules - `app/main.py` - Composes FastAPI app, middleware, startup/shutdown hooks, and all route handlers. - Validates payloads via Pydantic models. - Aggregates dashboard summary data and persists metric samples. - Starts a background sampler thread that periodically stores metrics. - `app/auth.py` - Verifies login credentials. - Enforces authenticated API access through `require_auth`. - `app/config.py` - Loads and validates environment-driven runtime configuration. - Creates the data directory when needed. - `app/db.py` - Initializes schema. - Persists and reads node settings. - Persists and reads metric history with retention trimming. - `app/bitcoin_rpc.py` - Encapsulates JSON-RPC request and batch request behavior. - Normalizes RPC errors through `BitcoinRPCError`. - Parses `help` output into command catalog entries. - `app/ssh_control.py` - Resolves SSH host and connection parameters. - Executes remote commands and returns execution result payloads. - Builds safe daemon start command strings. ### Frontend Assets - `app/templates/index.html` - Declares login, dashboard, settings modal, control actions, and RPC explorer regions. - `app/static/app.js` - Owns client state, auth transitions, API calls, chart hydration, and polling. - Caches metric history in browser local storage. - `app/static/styles.css` - Provides responsive layout and UI styling. ## Runtime Flow 1. Application startup calls `init_db()` and starts the metrics sampler thread. 2. Browser loads `/`, then frontend checks `/api/auth/me`. 3. After login, frontend loads settings, RPC command catalog, history, and summary. 4. Frontend refreshes summary every 15 seconds while page is open. 5. Backend stores sampled metrics: - on each summary API call. - in the background sampler at `METRICS_SAMPLER_INTERVAL_SECONDS` cadence. ## Data and Control Paths - Read-only node visibility: - `/api/dashboard/summary` uses batch RPC to fetch chain, network, mempool, mining, and uptime data. - `/api/dashboard/history` and `/api/dashboard/history/{window}` read persisted metric points. - Node management: - Stop uses Bitcoin RPC `stop`. - Start uses SSH execution of `bitcoind -daemon -conf=`. - Restart attempts RPC stop, waits briefly, then uses SSH start. - RPC explorer: - Command catalog derives from `help` output. - Arbitrary RPC call endpoint accepts method and JSON-array params. ## Error and Resilience Model - `BitcoinRPCError` and `SSHControlError` are mapped to HTTP `502`. - Missing required node settings are surfaced as HTTP `400`. - Validation issues return HTTP `422`. - Background sampler is best-effort and suppresses internal exceptions to avoid service interruption. ## Security Model - Authentication is session-cookie based using `SessionMiddleware`. - Access to operational endpoints requires `Depends(require_auth)`. - Credential verification supports: - plaintext password via `APP_PASSWORD` - bcrypt hash via `APP_PASSWORD_HASH` See `doc/environment.md` for security-relevant configuration fields.