Cyber2Tech

Orders from three marketplaces,land on one panel.

Product
Kurjet
Type
Our own product
Duration
Aug 2025 – May 2026
Team
2 backend, 3 mobile, 3 web
Stack
C# / .NET · TypeScript
Briefly

An order can land on the restaurant panel, or arrive separately from Trendyol, Yemeksepeti or Getir; deciding which courier carries which package is still a call the restaurant or an admin makes by hand. We built Kurjet as a system that brings these orders onto one panel, starts a courier's shift by location, and tracks delivery step by step.

Problem
Orders arriving through three separate channels
Solution
One panel + manual assignment + live tracking
01Problem

Three marketplaces, one decision point.

Trendyol, Yemeksepeti and Getir orders reach the backend through separate queue consumers; orders entered on the restaurant panel join the same flow. The system doesn't pick a courier automatically — the restaurant or an admin assigns the package by hand from the panel. As order volume grows, seeing all three channels in one place and routing each to the right courier becomes the job itself.

02Constraints

Three constraints shaped the design.

K1

Both sides must see the same state at once

The restaurant panel and the courier app run on separate devices; order status has to reach both through SignalR at the same time, with neither finding out late.

K2

The courier is on the move, and connectivity drops

The courier app has to work while moving; on a weak signal, a location update can arrive late or get sent twice. The client filters out stale and duplicate locations to keep the display consistent.

K3

A shift only starts on site

When a courier wants to start a shift, they need to be near the restaurant; PostGIS calculates the distance, and outside the configured radius (500 meters by default) the shift won't start.

03 — Approach

Wherever an order comes from, it enters the same flow.

An order lands in the system from the restaurant panel or through the Trendyol, Yemeksepeti and Getir integrations via message queues; the kitchen marks it as being prepared, and the restaurant or an admin assigns the package to a courier by hand. The courier marks it picked up with one tap, then delivered; each step shows up on the restaurant panel instantly.

  1. 01Order createdfrom the panel or a marketplace
  2. 02Being preparedin the kitchen, no courier yet
  3. 03Courier assignedrestaurant/admin picks by hand
  4. 04En routecourier updates with one tap
  5. 05Delivereddaily counters update
packet-status.jsonrepresentative · PacketInformation status update
{
  "id": "6f2b1e2a-••••",
  "status": "OnTheWay",
  "requestFrom": "Trendyol",
  "pickedUpAt": "15:41"
}
What we tried and left behind

We put an 18-hour cap on shift length, then switched it off for now. Around the same time we took out a caching layer we had added.

04Screens

The restaurant should see where a courier is at a glance.

Courier locations update on the map in real time.
The restaurant plans courier shifts on a calendar and assigns them in bulk.
05What we learned

What we're carrying into the next project.

  1. 01Instead of a fixed 18-hour shift cap, we learned to make the rule flexible until we understood when a courier actually needed more time.
  2. 02Fixing location updates on weak connectivity came less from more infrastructure and more from filtering stale and duplicate data on the client.
  3. 03Before automating a decision as critical as courier assignment, we chose to get the manual version solid first.
Next case
Woonzero

Are your order channels
getting tangled?