Fitofan
Sports platform: web, mobile apps and the backend behind them
One platform for athletes, coaches, clubs and fans: a web app in 11 languages, iOS and Android apps, and one backend that I own end to end.
- Role
- Senior Full-Stack & Mobile Engineer
- Period
- 2024 – 2026


Context
Fitofan serves athletes, coaches, parents, clubs and leagues with a Next.js web app, Flutter apps for iOS and Android and a NestJS backend. I own delivery across the whole stack: architecture, APIs, data, infrastructure and releases, and since 2026 I maintain the mobile app on my own.
The challenge
Keep one product coherent across three codebases and 11 languages while adding live sports data, payments, social publishing and AI features without slowing releases.
Built across the stack
- Next.js 16 web app on Feature-Sliced Design: 140+ pages, 11 locales, roughly 10,000 translation keys with parity checked in CI
- NestJS backend with 90+ modules, PostgreSQL and 290+ migrations, Swagger and health checks
- Event-driven sync over RabbitMQ with idempotent consumers, a dead-letter queue and correlation ids
- Redis caching with decorator-driven invalidation; Socket.IO gateways for comments and live sessions
- Live fixtures, results and odds from Sportmonks and API-Football; social publishing to Meta, TikTok, LinkedIn and YouTube
- Finix subscriptions plus payment verifiers for Stripe, Square, PayPal, LiqPay, Mercado Pago, GCash and Monopay
- OpenAI tool-calling assistant, Whisper transcription and Replicate image generation
- Flutter app: BLoC, Hive offline cache, Socket.IO, push notifications, AdMob, iOS Live Activities, 12 locales, 360+ tests
- CI/CD: lint and i18n gates, Jest, multi-stage Docker, container registry, SSH deploy; web on Vercel
- Shared registration and club-creation packages reused by GymTeam through an injectable host contract
- AI and vision R&D in the same ecosystem: a children's sport-assessment app with on-device pose estimation in Flutter and in-app subscriptions, and a browser-side taekwondo form analysis with MediaPipe and TensorFlow.js
Engineering highlights
- Idempotent event consumers: every message is recorded before it is acknowledged, so retries and replays never double-apply
- Architecture enforced by tooling: layer rules, a frozen lint baseline that can only shrink, dependency-cycle checks and i18n parity on every pull request
- Native iOS Live Activities driven from Flutter through a method-channel bridge
- One registration flow packaged behind a host contract and consumed by two products
What it enables
Features ship across web, mobile and backend in one change, and the platform exchanges club data with GymTeam in real time.