Teknik başvuru
Mimari, veri klasörü, ortam değişkenleri, güvenlik ve REST uçları. Yönetici için
Bu sayfa kurulumu/bakımı yapan teknik kişiler içindir.
#Mimari
| Katman | Teknoloji |
|---|---|
| Çalışma ortamı | Node.js ≥ 22.13, ES modülleri, düz JavaScript (derleme adımı yok) |
| Web / API | Express 5; yönetim paneli sunucu tarafında EJS ile üretilir; bağımlılıksız küçük bir istemci betiği |
| Mikro erişimi | mssql ile SQL Server'a doğrudan; tüm değerler parametreli (SQL enjeksiyonuna kapalı) |
| Yerel veri | Node'un yerleşik node:sqlite modülü (data/kernel.db, WAL kipinde) |
| POS istemcisi | WPF (.NET 8), offline-first; kernel'e REST ile bağlanır |
#Temel tasarım kararları
| Konu | Karar | Neden |
|---|---|---|
| POS katalog istekleri | SQLite aynasından okunur, Mikro'ya dokunmaz | POS toplu çeker; Mikro yavaş/kapalıyken POS çalışır |
| Ayna tazeleme | Zamanlayıcı: katalog 10 dk, stok 2 dk, cari 30 dk (panelden ayarlanır); hash karşılaştırmalı, yalnız değişen satır yazılır | Düşük yük, hızlı senkron |
| Satış aktarımı | Outbox: POS'a hemen 201, Mikro'ya arka planda; geçici hatada artan bekleme (15 sn × 2ⁿ, en çok 10 dk) | Mikro kapalıyken satış kaybolmaz |
| Çift kayıt koruması | sales.id2 UNIQUE → 409 DUPLICATE + Mikro'da cha_special2 = id2 kontrolü | POS yeniden gönderse de çift fatura olmaz |
| Politika ihlali | Satış reddedilmez, review olarak saklanır; onaylanınca Mikro'ya gider | Parası alınmış satış kaybolmamalı |
| Fiyat | Mikro satış fiyat listesi → KDV hariç net fiyat | POS birim fiyatı KDV hariç bekler |
#Veri klasörü
| Dosya | İçerik |
|---|---|
| data/kernel.db (+ -wal, -shm) | Tüm kernel verisi: ayarlar, kasiyer, terminal, cihaz anahtarları, satış kuyruğu, Mikro aynası, vardiyalar, denetim kaydı. Yedek = bu dosya (kernel çalışırken kopyalamayın; panelden Yedek indir kullanın). |
| data/config.json | İmza anahtarı (tokenSecret). Oturumlar, cihaz token'ları ve şifreli sırlar buna bağlıdır; taşırken kernel.db ile birlikte taşıyın. |
| data/logs/ | Servis olarak çalışırken konsol çıktıları (kernel-out.log, kernel-err.log). |
Klasörü NEMRA_DATA_DIR ile başka bir yere taşıyabilirsiniz. Veritabanı şeması, açılışta src/db/migrations.js'teki sıralı migrasyonlarla kendiliğinden güncellenir (mevcut migrasyonlar değişmez, yenileri eklenir).
#Güvenlik
- Panel oturumu: HMAC imzalı, HttpOnly + SameSite=Strict çerez; 12 saat. Tüm yazan (POST) isteklerde oturuma bağlı CSRF jetonu zorunlu.
- Parolalar/PIN'ler: scrypt ile tuzlanıp özetlenir; geri okunamaz. Mikro şifresi ve cihaz anahtarının panelde gösterilebilen kopyası AES ile şifreli saklanır (anahtar: config.json).
- Kaba kuvvet koruması: panel girişi ve kasiyer PIN'i 5 yanlıştan sonra 1 dk kilitlenir.
- Cihaz erişimi: POS yalnızca cihaz anahtarıyla alınan Bearer token'la konuşur; anahtar panelden iptal edilince token bir sonraki istekte düşer.
- Yardım Merkezi kernel'de değildir: pos.nemra.net/help altında herkese açık yayınlanır ve yalnızca kullanım bilgisi içerir. Kernel'in eski /help/... adresleri oraya yönlendirilir. Yönetim paneli ve API korumalıdır.
- Lisans: kernel yalnızca pos.nemra.net'e giden (dışarı) bir HTTPS bağlantısı kurar; kernel lisans anahtarını sorar, son başarılı yanıtı saklar ve sunucuya ulaşamazsa onunla çalışır. Bkz. Lisans ve yenileme.
- Kernel'i internete doğrudan açmayın; yalnızca mağaza ağında (veya VPN arkasında) çalıştırın. HTTPS gerekiyorsa önüne bir ters vekil (reverse proxy) koyun.
#REST uçları (POS sözleşmesi)
POS'un konuştuğu uçlardır. Giriş (device-login) ve health hariç hepsi Authorization: Bearer <token> ister. Hata yanıtı: { "error": "KOD", "message": "Türkçe açıklama" }.
| Uç | İşlev |
|---|---|
| GET /api/health | Sağlık denetimi: { ok, name, version, mikro: { connected } } (kimlik doğrulamasız). |
| POST /api/auth/device-login | Gövde: { deviceKey }. Başarılıysa { token, deviceName }; hatalıysa 401 INVALID_DEVICE_KEY. |
| GET /api/items | Ürün kataloğu (sayfalı; search, active); fiyat, KDV, birim, barkodlar. POS'ta gizli ürünler çıkmaz. |
| GET /api/inventory | Depo bazlı stok. |
| GET /api/warehouses, /api/units, /api/firms | POS'ta kullanılabilir depolar, birimler, firma bilgisi. |
| GET /api/quick-screen-layouts/:warehouseId | Depo için hızlı ürün ekranı grupları. |
| GET /api/settings/sale-policy | Sıfır fiyat/fiyatsız ürün politikası. |
| GET /api/cashiers?warehouseId= | Depoya atanmış aktif kasiyerler (PIN dönmez). |
| POST /api/cashiers/:id/verify-pin | PIN doğrulama; başarılıysa rol, indirim/cari yetkileri. Hatalı: 401 INVALID_PIN; kilit: 429 TOO_MANY_ATTEMPTS. |
| GET /api/pos-terminals/me | Bu cihaza bağlı terminal tanımı (fiş öneki, depo, ÖKC, cari ayarları). Bağlı değilse 404 NOT_LINKED (POS bunu hata saymaz). |
| GET /api/pos-terminals/:id/partners | "Müşteri Seç" listesi; terminalin cari kalıbına göre süzülür, search parametresi alır. |
| GET /api/mikro-integration/partners/:id/balance | Carinin Mikro'daki güncel bakiyesi. |
| POST /api/invoices | Satış gönderimi. 201 + { _id, id2, status }; yinelenen id2 → 409 DUPLICATE; yapısal hata → 400 VALIDATION. |
| POST /api/pos-shifts, PUT /api/pos-shifts/by-id2/:id2/close | Vardiya açma ve kapama bildirimi (idempotent). |
Satış gövdesinin ana alanları: id2 (benzersiz kimlik), invoiceTypeCode (380 satış, 381 iade), partnerId (cari kodu), warehouseId, cashierId/cashierName, zeroPriceApprovedBy, date, posReceiptNo ve lines[] (productId, unitId, quantity, unitPrice KDV hariç, discountRate, vatRateId). İsteğe bağlı: paymentMethod veya payments[] (bkz. Bilinen sınırlar).
#Zamanlayıcı
Tek bir 5 saniyelik vuruşla tüm arka plan işleri yönetilir: zamanı gelen iş çalışır, çalışmakta olan atlanır (çakışma yok). Sıra: katalog → stok/cari → satış aktarımı. Aralıklar panelden değiştirilir ve her vuruşta yeniden okunur (yeniden başlatma gerekmez). Başarısız bir senkron 30 sn sonra yeniden denenir.
#Günlükler ve tanı
- Konsol/günlük: başlangıç, senkron, hata satırları. POS API'sindeki her 4xx/5xx yanıt [api] METHOD /url → durum olarak kaydedilir; "POS neden senkronlamıyor?" sorusunun ilk cevabıdır.
- Panel: Senkron ▸ Son çalıştırmalar (hata mesajlı), Satışlar (satır bazlı hata nedeni, deneme sayısı), Denetim Kaydı, Sistem (sürüm, adresler, veri boyutu).
- Sağlık: http://sunucu:4750/api/health yanıt veriyorsa kernel ayakta; mikro.connected Mikro bağlantısının durumunu verir.
- Destek için toplayın: kernel sürümü (Sistem sayfası), Node.js sürümü, ilgili saat aralığının günlük satırları, hatalı satışın ayrıntı sayfasındaki hata mesajı (ekran görüntüsü).
#Test ortamı
- cd kernel && npm test — birim testleri.
- node scripts/smoke.mjs — çalışan kernel'e uçtan uca duman testi; varsayılan olarak Mikro'ya yazmaz (aktarımı duraklatır).
- Gerçek yazım testini yalnızca test veritabanında yapın; yazılan kayıtlar NEMRAPOS ile işaretlidir, test sonunda geri silin.
- Mikro yapılandırılmış bir kernel bekleyen satışları kendiliğinden yazar; test öncesi aktarımı duraklatın.