# btcprice Bitcoin price tracker UI — Clojure Kit web application. Serves the HTML/Tailwind UI. Connects to btcdata for live price data via WebSocket. ## Build & Development Commands - `make run` — Start dev server on port 4000 - `make repl` — Start nREPL - `make test` — Run tests - `make tailwind` — Watch Tailwind CSS for changes - `make uberjar` — Build production JAR - `docker compose up -d` — Start btcprice + btcdata containers ## Docker Docker runs alongside local dev on different ports: | Service | Local dev | Docker | |----------|----------------|----------------| | btcprice | localhost:4000 | localhost:4041 | | btcdata | localhost:4100 | localhost:4101 | btcprice's docker-compose includes btcdata via `include: ../btcdata/docker-compose.yml`. ## REPL Commands ```clojure (dev-prep!) ;; Prepare dev system (go) ;; Start system (reset) ;; Reload code & restart (halt) ;; Stop system ``` ## Architecture - **Framework:** Kit (Integrant-based) - **Server:** Undertow - **Routing:** Reitit - **Templates:** Hiccup + HTMX (WebSocket extension) - **Styling:** Tailwind CSS v4 - **Data backend:** btcdata (separate service at BTCDATA_URL, default http://localhost:4100) - **No database** — all data comes from btcdata ## Source Layout ``` src/clj/pmagnus/btcprice/ ├── core.clj # App entry point ├── config.clj # System config loader └── web/ ├── handler.clj # Ring handler + routes ├── htmx.clj # page/fragment macros ├── controllers/ │ └── health.clj # Health check ├── middleware/ │ ├── core.clj # Base middleware │ ├── exception.clj # Exception handling │ └── formats.clj # Content negotiation └── routes/ ├── api.clj # /api routes (JSON) ├── ui.clj # UI routes (HTML + HTMX WebSocket) ├── ws_proxy.clj # WebSocket proxy to btcdata └── utils.clj # Route utilities ```