Skip to content

Beep Call

Real-time call-record processing that turns failed low-balance calls into call-me-back SMS and flash calls

Operator dashboard fed by the query API, with simulated traffic from the mock network gateway1 / 5

When a prepaid subscriber with no balance places a call, the call fails and the person they tried to reach never finds out. Beep Call reads the network's call detail records as they happen, spots those failures and tells the other person to call back.

The problem

Failed calls from zero-balance subscribers are lost revenue and a missed connection. The operator needed to detect them from a high-volume stream of call detail records, without notifying the same person twice or overwhelming the SMS gateway.

What I built

Call records land in Kafka. A Kafka Streams filter keeps only low-balance failures and removes duplicates inside a time window. A bridge hands each event to RabbitMQ, where SMS and flash-call workers send notifications with retries and a dead-letter queue. Redis idempotency keys stop duplicate sends, and every record is also written to ClickHouse for search and reporting.

Results

  • The whole pipeline runs locally with one Docker Compose command, including a mock network gateway that stands in for the operator's SMSC and SIP endpoints.
  • Prometheus metrics and Grafana dashboards show ingestion and dispatch rates per stage.
  • Maven build runs in GitHub Actions on every push.

Features

  • Low-balance failure detection from raw call detail records
  • Deduplication windows so a callee is not messaged repeatedly
  • SMS and flash-call dispatch with retry and dead-letter queues
  • Subscriber guard and blacklist
  • Call record search and analytics in ClickHouse
  • Operator dashboard for configuration, blacklist and dispatch detail

How it's put together

Multi-module Maven project on Java 21 and Spring Boot: common, subscriber-guard, cdr-filter, notification-dispatch, cdr-sink, query-api and app, plus a mock gateway service.

  • Kafka for ingestion and Kafka Streams for stateful filtering
  • RabbitMQ for dispatch, where per-message retry and dead-lettering matter more than throughput
  • ClickHouse as the analytics store behind the query API
  • Next.js operator dashboard reading from the query API
  • Soko admin dashboard Products page listing eight demo coffee products such as Yirgacheffe Grade 1 Washed, Sidamo Natural and Guji Honey Process with slug, enabled status and row actions, beside the Platform and Administration sidebar
    Backends & APIs2025

    Soko Commerce

    Headless commerce on .NET 9 with CQRS, its own identity server, search and durable workflows

    Contributor.NETC#EF Core+15
  • MediOne catalogue screen in French with a medicine search box, category chips and a grid of products showing stock status and prices in Djibouti francs
    Mobile apps2026

    MediOne

    MediOne, Djibouti

    Online pharmacy and delivery for Djibouti, with a NestJS API and an Expo app that tracks orders on a map

    Solo buildNestJSMikroORMPostgreSQL+13
  • Dube home screen showing ETB 3,125.50 total outstanding and a list of customers with their balances and call buttons
    Mobile apps2026

    Dube

    Offline-first debt book for shopkeepers: an Android app, a sync API and an admin panel

    Solo buildExpoReact Nativeexpo-sqlite+15