Skip to content
All projects

MailC: CSEE x Check24

Apr 2026 – Jul 2026DevOps lead, then full-stack developer10 students across three teams (Frontend, Backend, DevOps)

MailC is a mail observability platform built to analyze and debug mail infrastructure issues.

Screenshot of MailC: CSEE x Check24

At a glance

  • 10 students in three teams (Frontend, Backend, DevOps)
  • Led the DevOps team
  • Set up coding guidelines and CI/CD pipelines for the project
  • Replicated Check24's mail infrastructure on Hetzner servers using Terraform and Ansible
  • Transitioned to full-stack developer after infrastructure work was done

Stack

  • React
  • TypeScript
  • Python
  • FastAPI
  • PostgreSQL
  • Keycloak (OIDC)
  • Terraform
  • Ansible
  • Docker
  • Caddy
  • Hetzner Cloud
  • GitHub Actions

The problem

SMTP is old, and it was never designed for the scale or the threat model it now carries. Every individual problem email has — spam, spoofing, delivery failure — already has a solution, but those solutions live inside different hops of the mail infrastructure and none of them share a view.

A mail path at a company like CHECK24 is not one server. An inbound message can pass a gateway doing early spam checks, then a filter, then an encryption/decryption engine, before it ever reaches a mailbox. When a message is rejected or silently never delivered, the evidence is scattered across those hops, and answering “what happened to this email?” means reading several logs on several machines.

MailC set out to build the missing integrated view: one platform that collects activity from every hop and makes both aggregate traffic and individual delivery failures visible to the internal departments that actually send the mail.

What we built

A single Docker Compose stack fronted:

  • A FastAPI collector exposing both the ingestion endpoint and the query API.
  • A React dashboard for aggregate traffic plus per-partner and per-vertical drill-downs as well as per message delivery graph.
  • PostgreSQL as the backing store for the collector and for Keycloak.
  • Keycloak as the OIDC identity provider.
  • Two periodic agents: spf_checker, which validates configured domains’ SPF records, and dmarc_fetcher, which reads a DMARC Maildir and posts aggregate reports back to the collector.

Logs are shipped from the mail hops with Grafana Alloy, which is what lets a single message be reconstructed across the hops it passed through.

My part

I led the DevOps team. This added aligning with the other teams, managing tasks and reporting to the project lead ontop of the “normal” development work. The hardest constraint was that we could not test against CHECK24’s real mail infrastructure — so we rebuilt a representative version of it. Using Terraform and Ansible, we stood up a Hetzner environment running a multi-hop Postfix path with the same shape as production: a gateway, routing between hops, SPF/DKIM/DMARC records in DNS, and Alloy shipping logs from each one. That simulation environment became the reference implementation the whole team developed against, and it is what made the ingestion work testable at all.

Alongside the infrastructure, the DevOps twam set up the project’s coding guidelines and the CI/CD pipelines — GitHub Actions building and pushing backend and frontend images to GHCR, then deploying over SSH.

Once the infrastructure work was done and stable, I moved onto feature work as a full-stack developer for the rest of the project.

What I took from it

Most of what I learned was about handing work over. The infrastructure I built was only useful if eight other people could run it, so I wrote it to be read: the setup guide walks through standing the whole stack up on a fresh environment, and it is deliberately paired with the simulation docs so every Postfix, Alloy and DNS claim has a working example behind it. Writing that document changed how I build infrastructure — the parts that were hard to explain turned out to be the parts that were badly designed. This collaborative approach was especially convenient for the usage of AI to develop. Instead of explaining our whole problem and simulation environment in each session, we could reference the documentation that already served the devs.