Skip to content
View kutsibalci's full-sized avatar

Highlights

  • Pro

Block or report kutsibalci

Block user

Prevent this user from interacting with your repositories and sending you notifications. Learn more about blocking users.

You must be logged in to block users.

Maximum 250 characters. Please don’t include any personal information such as legal names or email addresses. Markdown is supported. This note will only be visible to you.
Report abuse

Contact GitHub support about this user’s behavior. Learn more about reporting abuse.

Report abuse
kutsibalci/README.md
Hüseyin Kutsi Balcı — Backend Development Student, Anadolu University

Backend development student at Anadolu University, based in İzmir, Türkiye. I build server-side systems end to end — schema first, then the API, then the container it ships in.

Most of what is here started as something I wanted to understand rather than something I was told to build: how an ORM actually maps a schema, what a request touches between the route and the database, what it takes to run a service on a server instead of a laptop.

Open to internships, junior backend roles and open-source collaboration.


Open Source

root-project/root#23002 — merged into ROOT, CERN's data analysis framework for particle physics.

tmva/tmva/inc/LinkDef5.h had been unreachable since 2015. The commit that split TMVA into libTMVA and libTMVAGui dropped that file's #include from the master LinkDef but left the file itself in the tree, and two later maintenance sweeps edited it without noticing it was already dead. I traced the commit that orphaned it, checked that every symbol it declared was already covered by the module that actually owns those classes, and confirmed against the generated build graph that nothing referenced it — then proposed the removal.

Still open: ROOT #23004, the same class of leftover in smatrix and genvector; a latent undefined-behaviour fix in Eclipse S-CORE, the BMW/Bosch/Mercedes automotive platform; and an issue in NASA's F´ flight software framework.

What I keep relearning here: the patch is the easy part. Proving the claim before making it is the actual work — several findings I was sure about turned out to be false positives, and never left my machine.


Featured — Concurrent Ticketing

concurrent-ticketing — a ticketing API built around one question: what stops the same seat from being sold twice?

Two customers open the same event page and click seat A12 in the same millisecond. The obvious implementation reads the seat, sees Available, and writes Held — and so does the other request, because both read before either wrote. Nothing is wrong with either line; the bug lives in the gap between them, and it only shows up under load.

The fix is to make the check and the write one statement. Seat maps PostgreSQL's xmin system column as an EF Core concurrency token, so the write carries the version the read saw:

UPDATE seats SET status = 1 WHERE id = @id AND xmin = @version;

The first transaction to commit changes xmin. The second matches zero rows and gets a 409 instead of overwriting a sale. No table locks, no SELECT FOR UPDATE, and two customers buying different seats never contend.

Measured rather than asserted — twenty concurrent requests, one seat, real PostgreSQL in a container:

20 concurrent requests → 1 × 201 Created, 19 × 409 Conflict
database: 1 held seat, 1 reservation

The second race is telling anyone about it. Confirming a reservation writes to PostgreSQL and publishes to RabbitMQ, and no transaction spans both — publish first and the broker may hold an event for a commit that fails; publish after and the process can die in between. So the event is written as a row in the same transaction as the reservation, and a dispatcher moves it to the broker afterwards. That is at-least-once rather than exactly-once, and the consumer absorbs the difference: a receipt row keyed on the message id, inserted alongside the work, so a duplicate delivery hits the primary key instead of sending a second e-mail.

FOR UPDATE SKIP LOCKED is what lets a second dispatcher be started at all — FOR UPDATE alone would make it queue behind the first.

The tests I value most here are the ones added last. With 84 passing, running the stack by hand showed POST /api/auth/register accepting a three-character password and the literal string bu-bir-email-degil as an e-mail address: the contracts carried [Required] and [MinLength], but nothing evaluated them, and no test crossed the HTTP boundary where they live. A green suite says the tested thing works. It says nothing about the untested one.

.NET 10 · PostgreSQL · RabbitMQ · Redis · JWT with refresh rotation · Clean Architecture · Testcontainers · 119 tests · Docker Compose · CI


What testing an old project taught me

Course Registration System architecture

Course Registration System — an ASP.NET Core MVC application that worked. Adding tests to it was supposed to be a formality: writing down behaviour that already held.

Several of the first tests failed.

Finding What it meant
AdminController had no [Authorize] The whole management area answered anonymous requests — POST /Admin/KursSil deleted a course with no session at all
Administrator credentials were string literals The working password shipped with the source
Passwords stored in clear text Reading the database was reading every password
Cancellation never checked ownership Any signed-in student could cancel anyone else's place by incrementing an id
Capacity was a read-then-write race Counted, compared, then inserted

The last one is the one worth measuring. Reproducing the original logic under 15 concurrent applications to a course with capacity 5:

old logic (count → compare → insert):   15 enrolled     ← 3× over capacity
current logic (conditional UPDATE):       5 enrolled

62 tests now, and CI that fails the build on any dependency with a known advisory.

The same read-then-write shape turned up in the coffee shop till, and I only found it because I was trying to make the ordering logic testable. Adding the first item to a table read the table's state, saw it free, then opened a tab — so two waiters on two terminals both read free and both opened one. The order screen only ever shows the newest tab, so everything written to the other was never billed. One conditional UPDATE closes it, the same way the course capacity was closed. Third time I have written that fix now; I have stopped thinking of it as a trick and started looking for the shape.


Also Building — File Analysis Service

File Analysis Service architecture

A pipeline that scans uploads with YARA rules, parses PE structure with pefile, and submits samples to a CAPE sandbox. Work is queued through Redis to a Celery worker rather than blocking the request — analysing an untrusted file is slow, and it has no business happening inside an HTTP handler.

The lesson that stuck came from a bug in my own code: YARA compile errors were caught by a bare except and skipped, so a rule file with a syntax error made every sample come back clean. For a scanner, no findings and the scan never ran look identical from the outside, and only one of them means the file is safe. A crash is a good outcome; a false negative is the bad one.


Focus

Area What I'm actually doing about it
Concurrency Optimistic concurrency against a real database, and tests that genuinely race rather than asserting they would
Messaging Transactional outbox, at-least-once delivery, idempotent consumers, dead-letter queues — RabbitMQ driven directly rather than through a framework, because the mechanics are the point
API design Paginated, validated REST endpoints — with ordering that makes pagination stable and ceilings on anything read into memory
Data modelling Normalised schemas, code-first migrations, and constraints in the database rather than only in application code
Deployment Docker Compose and AWS EC2, with credentials from the environment and nothing sensitive published on a port
Analysis tooling Static and dynamic file analysis with YARA and Celery — the area I find most interesting right now

Stack

Technology stack

Projects

Concurrent Ticketing — .NET 10, PostgreSQL, RabbitMQ, Redis Course Registration System — ASP.NET Core MVC, EF Core, SQLite
Business Directory API — FastAPI, SQLAlchemy, Alembic File Analysis Service — FastAPI, YARA, Celery, Docker
Redmine Deployment — Docker Compose, PostgreSQL, AWS EC2 Coffee Shop Management — C#, Windows Forms, MySQL
Pansuman Simulator — Unity, URP, C#

Some of this is team work — the Redmine deployment was built with Atakan MERGEN (@hzflora), whose repositories I also contribute to.


Currently Learning

  1. SQL query planning — reading execution plans instead of guessing at indexes
  2. What breaks when one service becomes several: distributed tracing, and knowing which failures a retry actually fixes
  3. Data structures and algorithms, properly rather than for exams


Get in touchbalcihkutsi@gmail.com

İzmir, Türkiye · open to remote and hybrid roles

Pinned Loading

  1. Course-Registration-System Course-Registration-System Public

    Course registration and management web app built with ASP.NET Core MVC, EF Core and SQLite - student applications, plus an admin panel for courses and instructors.

    C#

  2. Small-coffee-Shop-Management-App Small-coffee-Shop-Management-App Public

    Windows Forms point-of-sale app for a small coffee shop - order taking, table tracking and an admin panel, backed by MySQL.

    C#

  3. concurrent-ticketing concurrent-ticketing Public

    Ticketing API showing how a seat is sold exactly once under concurrent demand - PostgreSQL xmin optimistic concurrency, a transactional outbox to RabbitMQ, JWT with refresh rotation, and 119 tests …

    C#