• Switch to Warm
  • Switch to Cool
  • Switch to Ember
  • Switch to Dusk
  • Switch to Plum
  • Switch to Midnight
  • Switch to Harbor
  • Switch to Cobalt
  • Switch to Noir
  • Switch to Tropic
  • Workspace
  • Projects
  • Notes

SaglikCell: Turkcell CodeNight 2026

A personal health-tracking platform built in a 10-hour hackathon: modular-monolith Spring Boot backend, React frontend, and a demo that broke fifteen minutes before presentation.

Problem

Turkcell CodeNight 2026 gave three-person teams a single case, cold, at 18:00: build a personal health-tracking platform (daily metrics, goals with streaks, trend analytics, a mock premium subscription) with a mandatory backend, a mandatory relational database, and a working demo by 04:00. Ten hours, no pre-written business logic allowed, AI tools fully permitted.

Approach

We split by strength: Talha built the backend, Hatice Nur built the frontend, and I owned the project’s foundation: CI/CD, Docker orchestration, and the backend-frontend integration and migration layer holding both sides together. The result was a modular monolith: Spring Boot on the backend (auth, users, metrics, goals, analytics, notifications, subscriptions, and admin as separate bounded contexts within one deployable), a React/TypeScript frontend, PostgreSQL for persistent data, and Redis for sessions, caching, and token blacklisting. The whole stack ran containerized and orchestrated with Docker Compose behind Nginx.

Tradeoffs

Docker gave us a clean, reproducible environment and made the eventual demo trivially “just run make up”, a real advantage when three people are working in parallel against the same stack. What it cost us we didn’t fully feel until the very end: on modest hardware, under a hard ten-hour deadline, every rebuild-and-redeploy cycle was slow enough to matter. We chose the tooling that made the architecture right, not the tooling that made iteration fastest, and that trade paid off all night before it bit us in the last hour.

Architecture

Architecture diagram: a browser sends requests through an Nginx reverse proxy to a React/Vite frontend and a Spring Boot backend built as a modular monolith with separate bounded-context modules for auth, users, metrics, goals, analytics, notifications, subscriptions, and admin. The backend reads and writes PostgreSQL 16 and uses Redis 7 for sessions, caching, and token blacklisting.Architecture diagram: a browser sends requests through an Nginx reverse proxy to a React/Vite frontend and a Spring Boot backend built as a modular monolith with separate bounded-context modules for auth, users, metrics, goals, analytics, notifications, subscriptions, and admin. The backend reads and writes PostgreSQL 16 and uses Redis 7 for sessions, caching, and token blacklisting.Architecture diagram: a browser sends requests through an Nginx reverse proxy to a React/Vite frontend and a Spring Boot backend built as a modular monolith with separate bounded-context modules for auth, users, metrics, goals, analytics, notifications, subscriptions, and admin. The backend reads and writes PostgreSQL 16 and uses Redis 7 for sessions, caching, and token blacklisting.Architecture diagram: a browser sends requests through an Nginx reverse proxy to a React/Vite frontend and a Spring Boot backend built as a modular monolith with separate bounded-context modules for auth, users, metrics, goals, analytics, notifications, subscriptions, and admin. The backend reads and writes PostgreSQL 16 and uses Redis 7 for sessions, caching, and token blacklisting.Architecture diagram: a browser sends requests through an Nginx reverse proxy to a React/Vite frontend and a Spring Boot backend built as a modular monolith with separate bounded-context modules for auth, users, metrics, goals, analytics, notifications, subscriptions, and admin. The backend reads and writes PostgreSQL 16 and uses Redis 7 for sessions, caching, and token blacklisting.Architecture diagram: a browser sends requests through an Nginx reverse proxy to a React/Vite frontend and a Spring Boot backend built as a modular monolith with separate bounded-context modules for auth, users, metrics, goals, analytics, notifications, subscriptions, and admin. The backend reads and writes PostgreSQL 16 and uses Redis 7 for sessions, caching, and token blacklisting.Architecture diagram: a browser sends requests through an Nginx reverse proxy to a React/Vite frontend and a Spring Boot backend built as a modular monolith with separate bounded-context modules for auth, users, metrics, goals, analytics, notifications, subscriptions, and admin. The backend reads and writes PostgreSQL 16 and uses Redis 7 for sessions, caching, and token blacklisting.Architecture diagram: a browser sends requests through an Nginx reverse proxy to a React/Vite frontend and a Spring Boot backend built as a modular monolith with separate bounded-context modules for auth, users, metrics, goals, analytics, notifications, subscriptions, and admin. The backend reads and writes PostgreSQL 16 and uses Redis 7 for sessions, caching, and token blacklisting.Architecture diagram: a browser sends requests through an Nginx reverse proxy to a React/Vite frontend and a Spring Boot backend built as a modular monolith with separate bounded-context modules for auth, users, metrics, goals, analytics, notifications, subscriptions, and admin. The backend reads and writes PostgreSQL 16 and uses Redis 7 for sessions, caching, and token blacklisting.Architecture diagram: a browser sends requests through an Nginx reverse proxy to a React/Vite frontend and a Spring Boot backend built as a modular monolith with separate bounded-context modules for auth, users, metrics, goals, analytics, notifications, subscriptions, and admin. The backend reads and writes PostgreSQL 16 and uses Redis 7 for sessions, caching, and token blacklisting.

Lessons Learned

At around 03:00 the application was working end to end: seed data, live metric entry, trend charts, goal streaks, the mock Paycell upgrade flow, all of it. By 03:15, newly added metrics stopped reflecting in the dashboard. We suspected Redis, a caching or session-state issue, but every hotfix attempt meant a full rebuild, and our Docker build times were long enough that we couldn’t iterate our way to a fix before the deadline. We went into the live demo with the bug still there, and it cost us. The judges saw a broken flow, and that’s a fair reason to have placed the way we did.

What makes it stranger: months later, running the exact same code with no changes at all, the project works perfectly. Whatever broke that night either depended on some state specific to that session or that machine, or on something in the original Docker build that a fresh one doesn’t reproduce. Either way, we never found out what it was, and by the time I could reproduce the problem to actually debug it, it wasn’t reproducible anymore. The real lesson wasn’t about Redis specifically: under real time pressure, your tooling’s iteration cost is part of your architecture, not a detail you deal with later. A ten-minute rebuild loop meant a fixable bug went uninvestigated, and we’ll never know for certain what it was.

Outcome

A working modular-monolith health platform, built inside a single ten-hour window with a three-person team, meeting every mandatory requirement in the case, undone in the room by an unresolved bug we couldn’t iterate our way out of in time. The uncomfortable postscript is that the same code, unchanged, runs cleanly today. It’s a reminder that “it worked in the demo” and “it’s actually fixed” are different claims, and so is “it’s broken” when the failure never gets a real explanation.