Gix is a distributed currency exchange rate monitor designed specifically for the Polish cantor market. It leverages a fast vector-based UI (Gio) and a robust cloud-native backend to track, aggregate, and stream exchange rates in real-time.
- Problem Statement
- Architecture & Tech Stack
- FinOps & Cost-Awareness (FOCUS Framework) - WORK IN PROGRESS
- Quick Start
- Known Limitations
- Roadmap
- Security & Contributing
- Demo
The currency exchange market (specifically physical cantors in Poland) is highly fragmented. Rates change dynamically, spreads vary dramatically, and finding the best real-time deal requires scraping dozens of disjointed, poorly-optimized websites.
Gix solves this by providing:
- Centralized Intelligence: Aggregates physical exchange office rates via smart, heuristic-based web scraping.
- Zero-Lag Updates: Uses NATS JetStream and dRPC for instant rate streaming directly to a native desktop/mobile client without polling.
- Cost Transparency: Scraping external providers isn't free (compute, bandwidth, LLM tokens). Gix includes a built-in.
- Go: Provides great performance, simple concurrency (goroutines), and static typing, perfect for both scraping engines and lightweight microservices.
- Gio UI: Immediate-mode vector graphics allow 60 FPS rendering on native platforms without embedding an entire Chromium browser (like Electron).
- TimescaleDB: Native PostgreSQL extension highly optimized for time-series data, perfect for analyzing historical currency trends.
- NATS JetStream: Lightweight, high-performance event streaming that supports replayability and exactly-once delivery.
It's designed with strict FinOps principles:
- Visibility: Real-time cost estimation per scraper run, saved directly to TimescaleDB (
provider_unit_coststable). - Governance: A built-in Circuit Breaker cuts off cantors if the cost-to-serve ratio exceeds
$0.05per day. - Optimization: Kubernetes resources are strictly bounded, TimescaleDB chunks are aggressively dropped after 30 days, and Redis handles traffic spikes to shield the DB.
- Go 1.26.2+
- Docker & Docker Compose
- Task (
go install github.com/go-task/task/v3/cmd/task@latest) - Gemini API Key: Required for the Heuristic LLM fallback scraper. Set it as an environment variable:
export GEMINI_API_KEY="your_api_key_here"
To start the entire environment (TimescaleDB, Redis, NATS) and run the Backend + UI natively:
task devTo run the native UI connected to the production cloud API:
task start:gui:remoteBelow is a list of all commands configured in the Taskfile.yml:
| Command | Description |
|---|---|
task proto |
Generates Go code from Protobuf files |
task lint |
Runs golangci-lint |
task test |
Runs unit tests |
task vuln |
Runs govulncheck on Go code |
task run:backend |
Runs the backend locally |
task run:estimator |
Runs the cost estimator locally |
task start:gui:local |
Starts GUI pointing to the local API |
task start:gui:remote |
Starts GUI pointing to the remote DigitalOcean API |
task deploy:do |
Builds, pushes, and deploys backend to DigitalOcean K8s |
task docker:build |
Builds the docker image |
task k8s:deploy |
Deploys backend to Kubernetes |
task clean |
Cleans temporary and build files |
task build:macos |
Builds a valid .app package for macOS |
task helm:lint |
Lints Helm chart |
task trivy:scan |
Scans the project for vulnerabilities using Trivy |
- Scraper Brittleness: Scraping physical cantors relies on their HTML structure. If a cantor updates their site, the static scraper might break. The Heuristic LLM fallback mitigates this but consumes API tokens.
- Geolocation API: The fallback to OSM Nominatim for city search is rate-limited by OpenStreetMap's fair usage policy.
- Heuristic LLM-based Cantor Discovery (WIP)
- NATS JetStream Event Streaming
- FinOps Cost-Estimator & Governance Circuit Breaker
- Predictive ML Anomaly Detection (DataDog ML)
- ...more???
Please read our SECURITY.md for reporting vulnerabilities. If you want to contribute, check CONTRIBUTING.md.
MIT License