GprFlow
ONLINECrypto trading platform
Live market data, a portfolio with profit and loss, statistics with charts, Stripe payments and a Gemini chatbot. JWT in an HttpOnly cookie and a gateway with rate limiting.
My role: Personal project, from architecture to deploy.
- React
- Redux
- Spring Cloud Gateway
- PostgreSQL
- Stripe
The problem
I wanted a personal project that dealt with what a real app has to handle: money, authentication, live external data and a real deployment. Stripe payments in the demo run in test mode, so no real money moves.
Architecture
It started as a Spring Boot monolith and is now split into services behind a Spring Cloud Gateway, with a React and Redux frontend.
- Services: coin, chatbot, ledger, auth and user, plus what is left of the monolith
- A single PostgreSQL instance, with a separate schema per service
- Hosted on my own Ubuntu server and exposed through a Cloudflare Tunnel, with no ports open on the router
- Automatic deploys with GitHub Actions: frontend and backend checks first, then release over Tailscale and SSH
Technical choices
- Phased migration: integration tests with Testcontainers first as a safety net, then one domain at a time (Coin and Chatbot, then Ledger, finally Auth and User)
- Security at the gateway: JWT in an HttpOnly cookie validated once, identity passed to services in headers, per-IP rate limiting, a 1 MB request cap and Cloudflare Turnstile on sign-in, sign-up and password reset
- Getting money right: closed access to other users’ data (IDOR), negative or zero amounts, OTP code reuse and wallet precision errors; the buy price is a weighted average when you buy the same asset again
What I learned
- How CI/CD pipelines work and how to use them, from automated checks to the production release
- How to deploy to a Linux server, including exposing the app with cloudflared
- How the containers of a Docker Compose stack talk to each other



