Skip to main content
Sérgio Gonçalves

Projects

TeamUP

TeamUP is for finding people to play with. You create an event for any sport, others join, everyone chats in real time and rates each other afterwards. Behind it sit five Laravel microservices, a React web app and a native Android client.

Context
A Master's project in Software Engineering at IPCA.

The problem

People who want to play football, do yoga, or train for anything else often can't, not because they lack interest, but because they lack the people. A five-a-side game needs ten players. A climbing session needs a partner. The activity isn't the barrier, finding others to do it with is.

What I built

TeamUP lets anyone create an event for any activity: pick the sport, the location, the time, and how many people you need, then let others join. Around that core there's real-time chat per event, notifications that surface events matching your interests, ratings, and gamification tracking how many events you've joined and what kinds.

Built as a Master's project by a team of three, on a microservices architecture: five Laravel services (users, event manager, chat, rating, achievements) in Docker containers communicating over RabbitMQ, with a separate WebSocket server for live chat. React on the web, Kotlin and Jetpack Compose on Android. We each worked across the whole stack rather than splitting by layer.

  • Five independent Laravel microservices (users, event manager, chat, rating and achievements), each with its own database and migrations.
  • Asynchronous messaging between services over RabbitMQ, with a dedicated WebSocket server for live chat.
  • The whole backend stack orchestrated with Docker Compose, and an SSL-enabled deployment variant.
  • Two first-class clients against the same API: a React web app and a native Android app in Kotlin with Jetpack Compose.

Decisions & trade-offs

  • A service per domain, wired with RabbitMQ

    Chat, ratings and achievements each got their own service, so they could change without touching the core event logic. RabbitMQ connects them: joining an event can unlock an achievement or fire a notification without the services knowing about each other.

  • WebSockets for chat, not the queue

    Chat runs on its own WebSocket server rather than through the message queue, because live chat needs a connection that stays open.

  • One command to bring the stack up

    Everything runs in Docker Compose, so all five services come up with one command. That mattered when three of us needed identical environments.

What I learned

This was my first project with a real microservices architecture, and the lesson was that the hard part isn't splitting the services up, it's everything that comes after. Keeping data consistent across service boundaries, debugging a request that crosses three services, and knowing when two things genuinely belong apart versus when you've just added complexity for its own sake.

It also taught me that infrastructure decisions are team decisions. Containerising everything wasn't the interesting technical problem, but it was the one that made three people able to work in parallel without stepping on each other.

Tech stack

  • Laravel
  • PHP
  • Docker
  • Docker Compose
  • Kubernetes
  • RabbitMQ
  • WebSockets
  • React
  • Kotlin
  • Jetpack Compose