# btcdata Bitcoin data backend — Clojure Kit application. Fetches BTC prices from Binance WebSocket and Kraken HTTP, stores in PostgreSQL, exposes a JSON API with WebSocket price stream. ## Build & Development Commands - `make run` — Start dev server on port 4100 - `make repl` — Start nREPL - `make test` — Run tests - `make uberjar` — Build production JAR - `docker compose up -d` — Start btcdata container ## Docker Docker runs alongside local dev on different ports and databases: | | Local dev | Docker | |--|----------------|----------------| | **Port** | localhost:4100 | localhost:4101 | | **Database** | btcprice | btcprod | ## REPL Commands ```clojure (dev-prep!) ;; Prepare dev system (go) ;; Start system (reset) ;; Reload code & restart (halt) ;; Stop system (reset-db) ;; Drop & re-migrate database (migrate) ;; Run pending migrations (rollback) ;; Rollback last migration (query-fn) ;; Get database query function ``` ## Architecture - **Framework:** Kit (Integrant-based) - **Server:** Undertow - **Routing:** Reitit - **Database:** PostgreSQL + conman + Migratus - **Port:** 4100 (env: BTCDATA_PORT) - **CORS:** Configured via CORS_ORIGIN env var ## API Endpoints - `GET /api/health` — Health check - `GET /api/price/ws` — WebSocket endpoint for live HTML price fragments (HTMX-compatible) - `GET /api/price/latest` — Latest price as JSON ## Source Layout ``` src/clj/pmagnus/btcdata/ ├── core.clj # App entry point ├── config.clj # System config loader ├── ws/ │ └── binance.clj # Binance WebSocket client ├── kraken/ │ ├── ohlc.clj # Hourly OHLC poller │ └── ohlc_daily.clj # Daily OHLC poller └── web/ ├── handler.clj # Ring handler + routes ├── controllers/ │ └── health.clj # Health check ├── middleware/ │ ├── core.clj # Base middleware + CORS │ ├── exception.clj # Exception handling │ └── formats.clj # Content negotiation └── routes/ ├── api.clj # /api routes (JSON + WebSocket) └── utils.clj # Route utilities ```