HesAPP

Gerçek bir kafede her gün kullanılan, internetsiz çalışan dokunmatik adisyon (POS) sistemi.

Rol
Tek geliştirici
Ekip
Bireysel · gerçek bir kafe için
Yıl
2026
Durum
Canlıda · her gün kullanılıyor
ASP.NET Core.NET 10React 19TypeScriptSignalRSQLiteESC/POSPWA

Kaynak kod gizli: sistem bir işletmede canlıda çalışıyor. GitHub’daki repo, ekran görüntüleri ve teknik açıklamaların yer aldığı bir tanıtım reposu.

208backend testiCanlıda · her gün kullanılıyor

İnternetsiz, dokunmatik, gerçek zamanlı.

Platform
Yerel ağ · PWA + kiosk
Kullanıcılar
Garson, kasiyer, yönetici
Veri
SQLite (WAL) · otomatik yedek
Arayüz dili
Türkçe

HesAPP, gerçek bir kafe için geliştirdiğim ve personelin her gün kullandığı dokunmatik bir adisyon sistemi. Tamamen yerel ağda çalışıyor; internet bağlantısı gerektirmiyor.

Garsonlar siparişleri tabletlerden alıyor; dokunmatik kasa bilgisayarı hem kasa hem sunucu görevi görüyor ve tüm cihazlar gerçek zamanlı senkron kalıyor. Kasiyer bölünmüş veya kısmi ödeme alıyor, termal yazıcılardan fiş ve mutfak fişi basıyor, müşteri carilerini tutuyor ve günü Z raporuyla kapatıyor. Müşteriler canlı menüyü ayrı bir dokunmatik kiosk ekranında inceliyor.

Projedeki rolüm

Projeyi baştan sona tek başıma geliştirdim: veri modeli ve ASP.NET Core API, React + TypeScript arayüzü, gerçek zamanlı senkronizasyon, ESC/POS yazdırma, yedekleme, testler ve müşteri kiosk menüsü.

Sistem gerçek bir kafe için yapıldı ve orada her gün kullanılıyor; bu yüzden güvenilirlik, para hesaplarının doğruluğu ve veri güvenliği tasarımın merkezinde.

Neler yapabiliyor?

Masalar & siparişler

Bölgelere ayrılmış masa düzeni, masa başına tek adisyon, ürün notları, masa taşıma / birleştirme ve servis takibi.

Ödemeler

Nakit (para üstü hesaplı), kart, yemek kartı ve veresiye; tutara veya ürüne göre bölünmüş ve kısmi ödemeler, indirim ve ikram.

Müşteri carileri

Borç, tahsilat ve ön ödemeli bakiye; borçlu müşteride hatırlatma ve eski borcu aynı fişte tahsil etme.

Raporlar & Z raporu

Günlük ve tarih aralığı raporları, ödeme yöntemi dağılımı, en çok satanlar; sıra numaralı Z raporu ve geçmişi.

Personel & güvenlik

Üç rol (garson, kasiyer, yönetici), PIN ile giriş, her uç noktada rol bazlı yetki, JWT oturumları ve giriş hız sınırı.

Yazdırma

80 mm termal yazıcılara TCP (9100) veya Windows USB üzerinden ESC/POS fiş; yalnızca mutfak ürünlerini içeren mutfak fişi.

Gerçek zamanlı yerel ağ

SignalR ile tüm cihazlara anlık sipariş, masa ve menü güncellemesi; kurulabilir PWA, kasada tam ekran kiosk modu.

Müşteri kiosk menüsü

Boştayken ürün tanıtan ekran ve fotoğraflı menü; canlı menüyü 60 saniyede bir çekip çevrimdışı için önbelleğe alır.

Veri güvenliği

WAL modunda SQLite, açılışta ve 24 saatte bir otomatik yedek (son 14 saklanır), arayüzden yedek indirme.

Nasıl kurulu?

Backend

ASP.NET Core Web API.NET 10EF Core 10SQLiteSignalR

Kimlik & güvenlik

JWT bearerPBKDF2-SHA256Rate limiter

Frontend

React 19TypeScriptViteTailwind CSS 4vite-plugin-pwa

Yazdırma

ESC/POSTCP :9100Windows spooler (P/Invoke)

Test

xUnitFluentAssertionsMoqVitest

Kiosk

HTMLCSSJavaScript

Mimari

Bağlantılar üzerindeki noktalar veri akışını gösterir.
hesapp — architectureReact PWAGarson tabletleri+ dokunmatik kasaKiosk menüHTML · CSS · JSEdge app moduASP.NET Core API.NET 10 · kasa PC’deistemciyi de sunarSignalR hubSQLiteWAL modu · EF Core 10YedeklerVACUUM INTO · 24 sason 14 saklanırTermal yazıcılarESC/POS · TCP :9100veya Windows USBREST /api · JWTSignalR /hubs/orderspublic menü · 60 snEF CoreBackupServiceReceiptPrinterhesapp — architectureReact PWATabletler+ kasaKiosk menüHTML · CSS · JSçevrimdışı önbellekASP.NET Core API.NET 10 · kasa PC’deistemciyi de sunarSignalR hubSQLiteWALEF Core 10YedeklerVACUUM INTO24 sa · son 14YazıcılarESC/POSTCP · USBREST + SignalRpublic menü · 60 snEF CoreBackupServiceReceiptPrinter

Gerçek kullanımın getirdiği problemler

01

Çok cihazlı eşzamanlılık

Aynı masada birden fazla tablet aynı anda çalışabiliyor. Filtreli bir benzersiz indeks masa başına tek açık adisyonu garanti ediyor; adisyon bazlı async kilitler değişiklikleri sıraya koyuyor, birleştirmeler kilitleri id sırasıyla alarak deadlock’u önlüyor. Merkezi bir sürüm sayacı sayesinde istemciler eski SignalR güncellemelerini yok sayıyor.

02

Anında oturum iptali

JWT’ler her istekte kontrol edilen bir token-sürüm bilgisi taşıyor. Personel pasifleştirildiğinde, rolü ya da PIN’i değiştiğinde eski oturumlar 12 saatlik süreyi beklemeden geçersiz oluyor. PIN’ler PBKDF2-SHA256 (100.000 iterasyon) ile saklanıyor, giriş IP başına dakikada 5 denemeyle sınırlı.

03

Ucuz yazıcıların da dayandığı yazdırma

ESC/POS işleri küçük parçalar ve kısa beklemelerle gönderiliyor; yazıcı başına bir kapı aynı anda tek iş gönderiyor. Böylece düşük maliyetli termal yazıcılar yoğun anlarda kilitlenmiyor.

04

Para asla iki kez sayılmıyor

Ürüne göre bölünmüş ödemelerde ödenen adetler satır bazında izleniyor, adisyon indirimi orantılı dağıtılıyor ve fazla ödemeler kalan tutara kırpılıyor. Adisyonla birlikte tahsil edilen eski borç ciroya değil cari hesaba yazılıyor; raporlarda iki kez görünmüyor.

05

Kararsız Wi-Fi’ye dayanıklı senkron

SignalR değişiklikleri anında iletiyor; istemciler otomatik yeniden bağlanıyor, bağlanınca tazeleniyor ve ayrıca 20 saniyede bir yokluyor. Sessizce kopan bir WebSocket, tableti eski veriyle bırakamıyor.

06

Otomatik ve güvenli yedekler

VACUUM INTO ile açılışta ve 24 saatte bir tutarlı, WAL-güvenli anlık görüntüler alınıyor (son 14 saklanıyor). Geçmiş siparişlerde kullanılan ürün ve masalar silinemiyor; sipariş geçmişi hiçbir zaman kaybolmuyor.

Karşılaşılan sorunlar & çözümler

Bölünmüş ödemede tutar uyuşmazlığı

Sorun

İndirimli bir adisyonda ürüne göre bölünmüş ödeme ekranı, sunucunun kaydettiğinden farklı bir tutar gösterebiliyordu.

Çözüm

Ekran artık sunucuyla birebir aynı formülü kullanan saf bir yardımcı fonksiyonla hesaplıyor (orantılı indirim, bankacı yuvarlaması, kalan tutara kırpma) ve Vitest testleriyle güvence altında.

Derlemede silinen kiosk fotoğrafları

Sorun

Her derleme web kök klasörünü temizlediği için yüklenen ürün fotoğrafları kayboluyordu.

Çözüm

Fotoğraflar veritabanının yanındaki kalıcı bir klasöre taşındı ve aynı URL’den sunuluyor; eski dosyalar bir kez, üzerine yazmadan taşınıyor — testlerle birlikte.

Raporlardan sessizce kaybolan satış

Sorun

Kapatma uç noktası nakit / kart / yemek kartı dışındaki yöntemleri de kabul ediyordu; bu satışlar raporlara yansımıyordu.

Çözüm

Bu üç uç nokta artık geçersiz yöntemleri 400 ile reddediyor; veresiye kapanışlar kendi uç noktasından ilerliyor.

Rakamlarla

Her güngerçek bir kafede kullanımda
208backend testi
3kullanıcı rolü
14otomatik yedek saklanır