# Vardiya — Muhasebe · Ticari · Personel

JSON dosya tabanlı, **bağımlılıksız** Node.js uygulaması. Veritabanı yok, `npm install` yok.

```bash
cd vardiya
node server.js          # http://localhost:3000
PORT=3100 node server.js  # port meşgulse
```

Varsayılan hesaplar (ilk açılışta oluşur): `admin/admin123` · `muhasebe/muhasebe123` · `sef/sef123` · `personel/personel123`

## Tamamlanan modüller

| # | Modül | İçerik |
|---|-------|--------|
| 1 | Giriş, rol, yetki | Oturum, 31 yetkilik rol matrisi, kullanıcı yönetimi, açık oturumlar, işlem günlüğü |
| 2 | Personel | Kimlik, görev, günlük/saatlik ücret modeli, mesai çarpanı, panel hesabı bağlama |
| 3 | Genel muhasebe | Hesap planı, çift taraflı yevmiye fişi, mizan, hesap ekstresi (muavin), ters kayıt |
| 4 | Cari hesaplar | Müşteri/tedarikçi, risk limiti, cari ekstresi (yevmiyeden hesaplanır) |
| 5 | Stok / çoklu depo | Malzeme kartı, çoklu depo, giriş/çıkış/transfer, ağırlıklı ortalama maliyet, kritik stok |
| 6 | Alış / satış faturası | Satır iskontosu, vergi kırılımı, otomatik stok hareketi + yevmiye fişi, iptal (ters kayıt) |
| 7 | Taksitli satış | Peşinat, n taksit, kuruş farkı son taksitte, gecikme takibi, tahsilat fişi |
| 8 | Çok dil + ülke | 5 dil (tr, ar, ku, ckb, fa), RTL desteği, 4 ülke vergi profili |
| 9 | Puantaj | Kartım (tek dokunuş giriş/çıkış), günlük kayıt, aylık cetvel, fazla mesai, gecikme, eksik gün |
| 10 | Personel hakedişi | Dönem bordrosu, stopaj/SGK/avans kesintileri, onay → yevmiye fişi, ödeme fişi |
| 11 | Rapor merkezi | Vergi beyan özeti, gelir tablosu, bilanço, cari yaşlandırma, stok değerleme, kasa/banka özeti, 7 CSV çıktısı |
| 12 | Cari tahsilat / tediye | Vadeli faturaların ödemesi; kasa/banka ↔ cari fişi |
| 13 | Çok şirket | Her şirketin defteri ayrı klasörde; kullanıcı bazlı erişim, başlıktan şirket değiştirme |
| 14 | Şubeler | Depolar şubelere bağlanır; merkez şube ikmalin kaynağıdır |
| 15 | Şube ikmali | Günlük eksik listesi → talep → merkez onayı → sevkiyatlı/sevkiyatsız gönderim → teslim |
| 16 | Taksitli satış sözleşmesi | Vade geldiğinde tahsilat yapılınca o taksitin faturası kesilir |
| 17 | Tanım tabloları | Vergi dairesi, banka, banka hesabı, kesinti/tevkifat oranı, sigorta ve emeklilik şirketi, ünvan, kademe, belge türü, risk grubu, harcırah ve masraf türü |
| 18 | Döviz kuru | Kur tablosu, global servis + elle giriş + varsayılan, kur hesaplama; para simgesi ve ondalık basamak ülke profilinden |
| 19 | Kurum hakedişi | İş/sözleşme, poz listesi, A–I hakediş şeması, kesintiler, tevkifatlı hizmet faturası

## Mimarinin özü

**Tek defter kuralı.** Fatura, taksit, stok — hepsi muhasebe kaydını `lib/muhasebe.js → fisOlustur()` üzerinden atar. Fiş borç/alacak eşitliği sağlanmadan kaydedilemez, bu yüzden mizan her zaman denk kalır. Fiş satırlarına `cariId`, `malzemeId`, `depoId`, `personelId` etiketleri düşülür; cari ekstresi ve stok izlenebilirliği ayrı tablo tutmadan bu etiketlerden üretilir.

**Hesap kodları kodda sabit değil.** `data/hesap-eslesme.json` mantıksal isimleri (kasa, alici, satici, stok, kdvHesaplanan…) plandaki koda bağlar. Ülke değişince plan değişir, modüller aynı kalır.

**Vergi oranları kodda sabit değil.** `lib/vergi.js` oranları ülke profilinden/ayarlardan okur. KDV'si olmayan bir ülkede aynı motor vergisiz veya satış vergisiyle çalışır; fişte KDV satırı hiç oluşmaz.

### Fatura kesinleştirme akışı

1. Muhasebe satırları kurulur — eksik hesap eşleşmesi varsa **hiçbir şeye dokunulmadan** durur.
2. Stok hareketleri yazılır; yetersiz stok varsa yazılanlar geri alınır.
3. Yevmiye fişi atılır; fiş denk değilse stok hareketleri geri alınır.
4. Taksitliyse plan üretilir, peşinat için ayrı tahsilat fişi atılır.

Satış fişi: cari **borç** genel toplam / satış geliri **alacak** matrah / hesaplanan KDV **alacak** vergi, ayrıca satılan mal maliyeti **borç** – stok **alacak** (ağırlıklı ortalama maliyetle).
Alış fişi: stok **borç** matrah / indirilecek KDV **borç** vergi / cari **alacak** genel toplam.

"Her ikisi" tipindeki bir cari için satış 120 Alıcılar'a, alış 320 Satıcılar'a gider.

## Ülke ve vergi profilleri

`data/ulkeler.json`: Türkiye (TRY), Irak (IQD), İran (IRR), Suriye (SYP). Her profil para birimi, sayı biçimi, mali yıl başlangıcı, vergi numarası deseni, hesap planı şablonu ve vergi listesi taşır.

> **Oranlar varsayılandır, mevzuat değildir.** Türkiye için KDV %20/%10/%1 ve yapım işleri stopajı; Irak ve Suriye'de genel KDV yerine satış/tüketim vergisi; İran için ماليات بر ارزش افزوده. Yürürlükteki oranları mali müşavirinizle doğrulayıp **Ayarlar** ekranından güncelleyin — kod değişikliği gerekmez.

İran profilinde mali yıl 21 Mart'ta başlar. Tarihler ISO olarak saklanır; Jalali/Hicri takvim gösterimi henüz eklenmedi.

## Diller

`data/i18n/*.json` — Türkçe, العربية, Kurdî (Kurmancî), کوردیی ناوەندی (Soranî), فارسی. Arapça, Soranî ve Farsça `rtl` olarak işaretli; arayüz yönü otomatik döner.

Yeni dil eklemek: `data/i18n/xx.json` dosyasını kopyalayıp çevirin, kod değişikliği gerekmez.

> Çeviriler makine değil ama uzman gözden geçirmesi de görmedi. Canlıya almadan önce her dili yerel bir muhasebeciye okutun; özellikle vergi ve muhasebe terimlerini.

## Klasör yapısı

```
server.js                  HTTP sunucusu (statik + /api yönlendirme)
lib/db.js                  JSON okuma/yazma (atomik)
lib/auth.js                scrypt şifre, oturum, yetki
lib/permissions.js         Yetki kataloğu — yeni yetki buraya
lib/validate.js            TC kimlik, IBAN (mod-97), telefon, tarih, tutar
lib/i18n.js                Diller, ülke profilleri, sistem ayarları
lib/muhasebe.js            Çift taraflı kayıt çekirdeği, mizan, muavin
lib/vergi.js               Vergi hesabı (satır + fatura + kırılım)
routes/api.js              Oturum, kullanıcı, rol, günlük
routes/personel.js         Personel kartları
routes/muhasebe.js         Hesap planı, fiş, mizan, ayarlar
routes/cari.js             Cari hesaplar + ekstre
routes/stok.js             Depo, malzeme, stok hareketi
routes/fatura.js           Fatura, kesinleştirme, iptal, taksit, tahsilat
data/*.json                Veri + i18n/ + hesap-planlari/
public/assets/js/ticari.js Cari, stok, fatura, taksit ekranları
public/assets/js/dashboard.js  Panel, muhasebe ve personel ekranları
```

## Puantaj ve hakediş

**Gün durumları:** tam, yarım, ücretli izin, ücretsiz izin, raporlu, devamsız, tatil, eksik.

Saat girilirse çalışma süresi giriş-çıkış farkından (mola düşülerek, gece yarısını geçen vardiya dahil) hesaplanır; girilmezse tam gün kabul edilir. `gunlukSaat` üzerindeki süre fazla mesai olur ve `mesaiCarpani` ile ücretlendirilir. Ücretli izin, saatlik personelin de ödenmesi için günlük çalışma süresi kadar sayılır.

**Çıkış saati girilmemiş gün "eksik" sayılır** ve varsayılan saat yazılmaz. Hakediş üretimi eksik gün varsa durur; bilinçli devam etmek için "eksikleri yoksay" gerekir. Şantiyede eksik kaydın sessizce tamamlanması yanlış hakedişten daha kötü sonuç veriyor.

**Gecikme** `Ayarlar → mesai başlangıcı` ve tolerans dakikasına göre bulunur.

Hakediş akışı: dönem seç → puantajdan taslak üret → ek ödeme/avans/diğer kesinti gir → onayla → öde.

Onay fişi: personel gideri **borç** brüt / personele borçlar **alacak** net (her personel ayrı satır, `personelId` etiketli) / ödenecek vergi **alacak** stopaj / ödenecek SGK **alacak** SGK / personel avansları **alacak** avans mahsubu / diğer çeşitli borçlar **alacak** diğer kesinti.
Ödeme fişi: personele borçlar **borç** / kasa veya banka **alacak**.

Onaylanan dönemin puantajı kilitlenir: kayıt eklenemez, düzeltilemez, silinemez.

Stopaj oranı ülke profilinden (`hakedisVarsayilani` işaretli vergi), SGK oranı `Ayarlar → sgkKesintiOrani` alanından gelir. İkisi de satır bazında elle değiştirilebilir.

## Çok şirketli mimari

```
data/                     GENEL: users, roles, sessions, audit, sirketler, i18n, ülke profilleri
data/sirket/ANA/          Şirkete özel: ayarlar, hesaplar, fisler, cari, depolar, malzemeler,
data/sirket/IRK/          stok-hareketleri, faturalar, sozlesmeler, personel, puantaj, hakedis, subeler…
```

Şirket verisi **dosya seviyesinde** ayrıdır; sorgu filtresi değil. Bir şirketin verisinin diğerine karışması mimari olarak mümkün değil. Her şirketin kendi ülkesi, hesap planı, vergi listesi ve para birimi olur — Türkiye'deki şirketle Irak'taki şirket aynı kurulumda yan yana çalışır.

- `lib/db.js` her isteğin başında `baglam(sirketKod)` ile hangi klasörü okuyacağını öğrenir.
- Kullanıcının `sirketler` alanı erişimi belirler; `['*']` hepsi demektir.
- Başlıktaki seçiciden şirket değiştirilir, oturum bunu hatırlar.
- Eski tek şirketli kurulum ilk açılışta otomatik taşınır: `data/*.json` → `data/sirket/ANA/`.

## Şube ikmali

1. **Günlük eksik listesi** — her deponun kritik stok altındaki kalemleri. Merkez stoğu yetmiyorsa satır kırmızı işaretlenir.
2. **Talep** — "Talepleri üret" günün eksiklerinden depo bazlı talep açar; aynı gün tekrar çalıştırılırsa kopya açmaz, mevcudu günceller. Şube elle de talep girebilir.
3. **Merkez onayı** — miktarlar düşürülerek onaylanır (merkez stoğu kısıtlıysa).
4. **Sevk** — iki türlü:
   - **Sevkiyatsız**: mal doğrudan hedef depoya geçer (elden teslim).
   - **Sevkiyatlı**: mal önce `YOLDA` sistem deposuna çıkar; plaka, sürücü ve irsaliye kaydedilir. Teslim alınınca hedef depoya girer.
5. **Teslim** — eksik gelen miktar girilebilir; **fark YOLDA deposunda kalır, kaybolmaz.** Sevkiyat "eksik teslim" olarak işaretlenir.

`YOLDA` deposu şirket açılışında otomatik kurulur, silinemez ve talep hedefi olamaz.

## Taksitli satış sözleşmesi

Peşin/vadeli faturadan farklı bir modeldir:

| Aşama | Ne olur |
|-------|---------|
| Sözleşme | Kalemler, peşinat, taksit sayısı ve vade tarihleri belirlenir. Fatura kesilmez. |
| Yürürlüğe alma | Taksit planı üretilir. Peşinat varsa **peşinatın faturası** kesilir ve tahsil edilir. |
| Teslim | Stok çıkar, malın maliyeti gidere alınır (satılan mal maliyeti / stok). Fatura kesilmez. |
| Taksit tahsilatı | **Vade gelip tahsilat yapıldığında o taksitin faturası kesilir.** Kısmi tahsilatta yalnızca tahsil edilen tutar faturalanır. |

Tahsilat fişi: kasa/banka **borç** tutar · satış geliri **alacak** matrah · hesaplanan vergi **alacak** vergi. Gelir ve vergi, taksit tahsil edildikçe doğar; sözleşme anında büyük bir alacak ve vergi yükü oluşmaz.

Taksit tutarı vergi dahil bölünür, matrah/vergi oranı korunur, kuruş farkı son taksite yazılır.

## Kurum hakedişi

Kamu hakediş dosyasındaki A–I şeması birebir uygulanır:

```
A  Sözleşme fiyatları ile yapılan iş tutarı (kümülatif)
B  Toplam fiyat farkı
C  Toplam tutar              (A + B)
D  Önceki hakediş tutarı     (kümülatif)
E  Bu hakediş tutarı         (C − D)
F  KDV                       (E × oran)
G  Tahakkuk tutarı           (E + F)
H  Kesintiler toplamı
I  Yükleniciye ödenecek      (G − H)
```

**İş / sözleşme:** işin adı, idare, yüklenici, sözleşme no/tarihi/bedeli, süre, proje kodu ve **poz listesi** (yapılacak işler: miktar, birim, birim fiyat).

**Kesintiler kodda sabit değil.** KDV tevkifatı 7/10, stopaj %3, damga, teminat, SGK… hepsi *Tanımlar → Vergi ve kesinti oranları* tablosundan gelir. Her kesintinin matrahı ayrıca seçilir: KDV tutarı, matrah veya genel toplam üzerinden. Tevkifatta pay/payda girilir (7/10), oran otomatik hesaplanır.

**Kümülatif kontrol:** her hakedişte önceki miktarlar otomatik gelir, kümülatif miktar sözleşme miktarını aşarsa kayıt reddedilir.

**Onay → fatura + fiş.** Hakediş onaylanınca:
- **Hizmet faturası** kesilir — ürün değil, tek satırlık hizmet kalemi; depo ve stok hareketi yoktur. Tevkifat ve kesintiler faturanın altında ayrı gösterilir.
- Yevmiye fişi: `Alıcılar BORÇ I` + `Kesinti hesapları BORÇ H` / `Satış geliri ALACAK E` + `Hesaplanan KDV ALACAK F`.

Örnek (yüklenen dosyadaki 1 nolu hakediş): A=C=E=50.000, F=10.000, G=60.000, KDV tevkifatı 7/10 = 7.000, I=53.000. Sistem aynı rakamları üretir.

## Tanım tabloları

Tek şema motoruyla yönetilen 11 tablo: vergi dairesi, banka, banka hesabı, vergi/kesinti oranı, sigorta-emeklilik şirketi, ünvan, kademe, belge türü, personel risk grubu, harcırah türü, masraf türü.

Yeni bir tanım tablosu eklemek için `routes/tanim.js` içindeki `TANIMLAR` nesnesine bir satır yazmak yeterli — ayrı uç nokta, ayrı ekran, ayrı doğrulama gerekmez. Alan tipleri: metin, sayı, oran, seçim, onay, muhasebe hesabı, başka tanıma bağ, çoklu bağ.

**Risk grubu → belge zinciri:** belge türlerinde geçerlilik süresi (ay) ve uyarı gün sayısı tutulur; risk grubu bu belgelerden bir set seçer. Örn. "Buraj makinesi operatörü" → sağlık raporu, göz taraması, psikoteknik.

## Rapor merkezi

Altı rapor, hepsi kayıtlı fişlerden üretilir — ayrı rapor tablosu yok, bu yüzden rapor ile muhasebe arasında fark oluşmaz.

| Rapor | Ne verir |
|-------|----------|
| Vergi beyan özeti | Hesaplanan − indirilecek vergi, ödenecek/devreden sonucu, oran bazında matrah-vergi kırılımı (beyan eki) |
| Gelir tablosu | Hesap planındaki `gelir`/`gider` etiketlerine göre dönem kârı |
| Bilanço | Aktif / yabancı kaynak / özkaynak + dönem sonucu, aktif=pasif denklik kontrolü |
| Cari yaşlandırma | Vadesi gelmemiş / 0-30 / 31-60 / 61-90 / 90+ kovaları |
| Stok değerleme | Ağırlıklı ortalama maliyetle kalem ve depo bazlı değer, beklenen kâr |
| Kasa / banka özeti | Devir, dönem girişi, çıkışı, kapanış bakiyesi |

**Yaşlandırma tahsilatları en eski belgeden düşer**, böylece toplam cari bakiyesiyle birebir örtüşür. Belgeye bağlanamayan bakiye (açılış kaydı, elle fiş) ayrı kolonda gösterilir.

Çapraz kontrol: stok değerleme toplamı ile bilançodaki stok hesabı bakiyesi eşit çıkmalıdır. Test verisinde ikisi de 57.600 ₺.

**CSV çıktıları:** mizan, yevmiye defteri, cari listesi, stok listesi, faturalar, puantaj, hakediş. Noktalı virgül ayırıcı + UTF-8 BOM ile üretilir, Excel doğrudan açar.

Gelir tablosu notu: Türkiye planında 7/A yansıtma hesapları (751/761/771/781) kullanılmaz; maliyet hesapları doğrudan gider sayılır. Resmî beyan için mali müşavirinizin dönem sonu kayıtları gerekir.

## Sıradaki adımlar

- **Çek / senet takibi** — keşide ve vade tarihleri, portföy, ciro, tahsil, vadesi yaklaşan uyarısı
- **Personel özlük dosyası** — okul, sağlık raporu, ehliyet/SRC, aile, SGK, sertifika, ünvan/kademe + risk grubuna göre eksik evrak ekranı
- **Personel harcırah, masraf fişi ve avans** (tanım tabloları hazır)
- Muhasebe hesap planında alt hesap üretimi (120.01.001) ve her seçimde hesap listesinden seçim
- Fatura satırlarında modal ürün seçici, irsaliye faturası, barkodla stok girişi
- Cari kartına ISO/sertifika/teminat/tevkifat alanları ve vergi dairesi seçimi
- Sözleşme faturalarının dönemsel raporu ve gecikme faizi
- **Kurumsal / taşeron hakedişi** — imalat kalemleri, sözleşme birim fiyatları, KDV tevkifatı ve teminat kesintisi (personel hakedişinden ayrı bir modül)
- Dönem kapanışı: 690/692 kâr hesapları, açılış-kapanış fişleri
- Fatura ve ekstre PDF çıktısı
- Jalali ve Hicri takvim gösterimi
- Fatura/ekstre PDF çıktısı, CSV dışa aktarma
- Kur takibi ve dövizli fatura

## Stoklu / hizmet ayrımı

Malzeme kartında ilk alan **Kalem tipi**:

- **Stoklu ürün** — depoda takip edilir, faturada depo zorunlu
- **Hizmet / stoksuz** — danışmanlık, bakım, kiralama… **depo hiç sorulmaz**

Faturada tüm satırlar hizmetse depo alanı **tamamen gizlenir**. Karışık faturada (hizmet + stoklu) depo istenir ve hata mesajı hangi kalemin stok takipli olduğunu söyler. Malzeme listesinde hizmet kalemleri rozetle, stok kolonunda "takip yok" olarak görünür.

## Çek ve senet takibi

Alınan ve verilen çekler ayrı izlenir; **keşide tarihi** (çekin üzerindeki tarih) ile **vade tarihi** ayrı tutulur.

| İşlem | Muhasebe kaydı |
|-------|----------------|
| Alınan çek girişi | Alınan çekler BORÇ / cari ALACAK |
| Verilen çek girişi | cari BORÇ / Verilen çekler ALACAK |
| Tahsil | kasa-banka BORÇ / Alınan çekler ALACAK |
| Ödeme | Verilen çekler BORÇ / kasa-banka ALACAK |
| Ciro | devredilen cari BORÇ / Alınan çekler ALACAK |
| Karşılıksız | cari BORÇ / Alınan çekler ALACAK (borç geri döner) |

Vadesi geçen çek satırı kırmızı, vadesine 7 günden az kalan sarı. Hesap planına `101 Alınan Çekler` ve `103 Verilen Çekler` eklendi.

## Ödeme şekilleri

*Tanımlar → Ödeme şekilleri*: nakit, havale/EFT, kredi kartı, çek, senet, vadeli. Her birinin tipi, varsayılan muhasebe hesabı ve vade günü var. Faturada seçilince **vade tarihi otomatik hesaplanır**.

## Personel masraf fişleri

Personel harcamalarını kalem kalem girer (tür, açıklama, belge no, matrah, KDV). Akış: **talep → onay → ödeme**.

- Onay: gider hesapları BORÇ + indirilecek KDV BORÇ / personele borçlar ALACAK
- Ödeme: personele borçlar BORÇ / kasa-banka ALACAK

Masraf türünde "belge zorunlu" işaretliyse belge numarası olmadan kayıt kabul edilmez.

## Personel self-servis

Personel rolüyle giren kullanıcı **kendi** izin, avans ve masraf kayıtlarını görür; başkasınınkini göremez, başkası adına izin talebi açamaz. Yetkisi geniş olan (`personel.view`) herkesi görür. Menüde: Kartım, İzinler, Avanslar, Masraf Fişleri, Hakedişim.

## Sayfalama ve arama

Tüm tablolar **20'şer kayıt** gösterir. Sayfalama bir katman olarak çalışır: ekran tabloyu çizer, katman satırları sayfalara böler ve alt çubuğu ekler. Yeni bir ekran yazınca ek iş gerekmez.

Başlıktaki arama kutusu aktif ekranın tablosunu süzer, sayfalama kalan satırlara göre yeniden kurulur. Ayrıca sunucu tarafı arama eklenen ekranlar: **sözleşmeler**, **vade takibi**, **işler/projeler**.

## Taksitli satışta faturalama

Sözleşme açarken iki model seçilir:

| Model | Davranış |
|-------|----------|
| **Tek fatura (senetli)** — varsayılan | Müşteri senet imzalar; fatura **genel tutar üzerinden** yürürlük anında bir kez kesilir. Taksitler yalnızca tahsilat takvimidir. Her tahsilat: `kasa/banka BORÇ / cari ALACAK` |
| Her taksitte fatura | Gelir tahsilat anında doğar; her taksit için ayrı fatura kesilir |

## Vade takibi

Artık tüm kişilerin taksitleri alt alta değil: **her sözleşme tek satır** — adı soyadı, ürün kodu/adı, vade başlangıcı, taksit sayısı (ödenen/toplam), peşinat, tutar, kalan, sıradaki vade. Geciken varsa satır kırmızı ve yanında uyarı simgesi.

**Taksitler** düğmesi o sözleşmenin taksitlerini modalda açar; hangi taksit ödenecekse yanındaki **Öde** ile tahsilat girilir.

## Stoklu / stoksuz ürün

Malzeme kartındaki **"Stok takibi"** kapatılırsa o kalem depo istemez. Faturada tüm kalemler stoksuzsa depo alanı soluklaşır ve boş bırakılabilir — hizmet, senetli satış veya dijital ürün faturası depo olmadan kesilir.

## Kurum hakedişleri

Menü artık binlerce hakedişi tek listede göstermiyor: önce **projeler** (iş no, proje adı, kurum, bedel, hakediş sayısı, gerçekleşme oranı, son hakediş tarihi), projeye tıklayınca **o projenin hakedişleri** 1, 2, 3… sırasıyla ve dönem aralıklarıyla açılır.

## Personel görevlendirme

Personel bir haftalığına başka şehirdeki şantiyeye gönderilir; orada yemek yer, otelde kalır, malzeme alır. Fişler birikir ve ay sonunda merkeze telefonla fotoğraf ya da Excel olarak gider. Kim, nerede, hangi iş için harcadı belli olmaz.

**Görevlendirme bu boşluğu kapatır:** masraf fişi bir göreve bağlanır, gider o projenin maliyetine düşer.

### Harcırah — iki yöntem karıştırılmamalı

| Yöntem | Nasıl işler |
|--------|-------------|
| **Maktu** | Günlük sabit tutar, fiş istenmez |
| **Gerçek gider** | Fişe dayalı, avanstan mahsup edilir |
| **Yok** | Yalnız fişler |

Hangisi olduğu görevlendirmede yazılır. İkisi karıştırılırsa hem fazla ödeme olur hem vergi sorunu çıkar.

### Avans ve kapanış

Yola çıkarken avans verilir — onaylandığında kasadan çıkar, muhasebeleşir. Dönüşte fişler toplanır ve kapanışta mahsuplaşır:

```
Verilen avans        10.000,00 ₺
Harcırah (5 × 1200)   6.000,00 ₺
Fiş toplamı (2)       2.756,00 ₺
─────────────────────────────────
Personelden iade      4.000,00 ₺
```

Onaysız fiş varsa kapanış engellenir. Kapanışta bakiye artı ise personele ödeme, eksi ise iade fişi oluşur.

Aynı kişi aynı tarihte iki görevde olamaz — masraf fişinin hangi göreve yazılacağı belirsizleşir ve harcırah iki kez hesaplanır.

### Mobil bağlantı

Personel mobilden masraf fişi çekerken **aktif görevlendirmesi hazır seçili gelir**. Fiş listesinde hangi göreve ait olduğu görünür. Merkez artık "bu masraf hangi işe ait" diye sormak zorunda değil.

## Bulunan ve düzeltilen hatalar

**Kılavuzun içeriği ilk ekrandan sonra kesiliyordu** — `theme.css` panel düzeni için `main { height: calc(100vh - 62px); overflow: hidden }` diyor. Kılavuzun içerik alanı da `<main>` olduğu için 7 bölümün 6700px'lik içeriği 844px'e sıkışıyor, sayfa kaymıyor, menüden atlama işe yaramıyordu. Ayrıca `html, body` da `overflow:hidden` alıyordu. İkisi de kılavuzda geçersiz kılındı.

**Kılavuz menüsü anlaşılmıyordu** — Yatay şeritte grup başlıkları (Başlangıç, Kullanım, Modüller) bağlantıların arasına karışıyor, hangisinin başlık hangisinin tıklanabilir olduğu belli olmuyordu. **Sol sidebar**'a çevrildi: her grup kendi kartında, bölümler numaralı, etkin başlık turuncu şeritle işaretli. Dar ekranda hamburger düğmesiyle açılıyor.


**Tanımlar tablosu normal kurulumda bomboştu** — Vergi dairesi, banka, birim, ünvan, kademe, izin türü, belge türü, ödeme şekli, masraf türü, risk grubu, kesinti, sigorta şirketi, harcırah türü: hepsi yalnız `demo.js` içinde üretiliyordu. Gerçek kurulumda cari açmaya çalışan kullanıcı vergi dairesi seçemiyor, personel eklerken ünvan bulamıyordu.

Tanımlar `lib/tanimlar.js` modülüne taşındı ve **kurulumda otomatik yükleniyor** — hem yeni şirket açılırken hem mevcut şirkette eksikler tamamlanırken. Aynı kod ikinci kez yazılmaz, kullanıcının düzenledikleri ezilmez. Test: temiz kurulumda **68 tanım**.

**Cari etiketleri kaydedilmiyordu** — Form alanı vardı, sunucu kabul ediyordu ama arayüzün `topla()` fonksiyonu `etiketler`, `iso`, `tevkifatOrani` ve `teminat` alanlarını hiç göndermiyordu. Kullanıcı yazıyor, kaydediyor, hiçbir şey olmuyordu. Dördü de eklendi; düzenleme modalı da artık bu alanları dolduruyor (önceden boş açılıp kaydedince kayıttaki değeri siliyordu).

**Açılır listeler yeni kayıtları göstermiyordu** — `if (options.length === 0)` koşulu yüzünden liste yalnız bir kez dolduruluyordu. Yeni satış noktası eklenip masa ekranına dönüldüğünde combo eski kalıyor, sayfayı yenilemek gerekiyordu. Altı ekranda aynı hata vardı (masa, hızlı satış, kasa vardiyası, satış fişi, NVR dağıtım, izleme bina). Hepsi her yüklemede tazeleniyor, seçili değer korunuyor.

**Mobilde çıkış `confirm()` kullanıyordu** — Tarayıcının sistem penceresi bazı gömülü mobil tarayıcılarda hiç görünmüyor, kullanıcı çıkış yapamıyordu. Kendi onay çekmecesine çevrildi; çıkıştan sonra `location.reload()` yerine doğrudan giriş ekranına dönülüyor, eski uyarı mesajı temizleniyor.


**Simge fontu internetten geliyordu** — Kapalı ağda ya da internet kesikken font yüklenmiyor, tarayıcı ligature çözemediği için ekranda `menu_book`, `arrow_forward` gibi ham adlar beliriyordu. Tek dosya olarak dağıtılan bir sistemde bu ciddi bir kusur. `simge.js` açılışta fontu ölçüyor; yüklenmediyse `<html>` öğesine `simgesiz` sınıfı ekleniyor ve simgeler gizleniyor. Yanlarındaki yazılar durduğu için anlam kaybolmuyor.

**Giriş ekranı aşağı kayıyordu** — Kılavuz, mobil şube, destek bloğu ve hesap listesi giriş kutusunun içindeydi; kutu uzayınca kullanıcı adı alanı ekran dışında kalıyordu. Bağlantılar ve destek bloğu sol sütuna taşındı, form sadeleşti.

**Kılavuz düzeni bozuktu** — Gövde yatay menüye çevrilmişti ama CSS eski yan menü kurallarını taşıyordu; menü sayfanın ortasında asılı kalıyordu. Stil baştan yazıldı.

**Sidebar'da menünün devamı belli olmuyordu** — Kaydırma çubuğu gizli olduğu için altta başka öğe kaldığı görünmüyordu. Alt ve üst kenarda gölge + ok belirir, tıklanınca kaydırır, kenara gelince söner.


**Kılavuz hiç kaymıyordu** — `theme.css` panel düzeni için `html, body`'ye `height:100%; overflow:hidden` veriyor (panelde kaydırma iç bölmede olur). Kılavuz normal bir belge olduğu için bu kısıt sayfayı kilitliyor, menüden atlama işe yaramıyordu. Kılavuzda ezildi.

**Giriş ekranında iki kılavuz düğmesi vardı** — Biri `/dokuman.html` adresine gidiyordu ama o dosya hiç yoktu; ölü bağlantıydı. Kaldırıldı.

**Mutfak ekranı düz ızgaraydı** — Bütün işler karışıyor, aşçı hangisinin beklediğini hangisinin ateşte olduğunu ayırt edemiyordu. **Kanban**'a çevrildi: Bekleyen / Hazırlanıyor / Hazır sütunları, her biri kendi içinde kayar. Sayfa aşağı uzamaz, ekran yüksekliği sabit kalır. Geciken işler (20 dk üstü) kırmızı, sütun başlığında sayısı yazar.


**Paketten basılan örnek veri yarım kalıyordu** — `data/hesap-planlari/` klasörü pakete gömülmemişti. Sadece `i18n` ve `sablonlar` gömülüyordu. DEMO şirketinde hesap planı yüklenemeyince `fisOlustur` sessizce başarısız oluyor, cari/yevmiye/çek/dolum zinciri baştan kopuyordu — tabloda yalnız malzeme ve personel görünüyordu.

Artık `data/` altındaki bütün klasörler gömülüyor (tek istisna `sirket/`, o müşterinin kendi verisi). Exe içinden basılan veri:

```
cari 15 · satış faturası 61 · alış faturası 12 · personel 12
çek 14 · kiralık makine 8 · yevmiye 338 fiş · mizan denk ✓
```

**Şirket seçici okunmuyordu** — Satır içi `background:none` açılan listeyi sistem varsayılanına bırakıyordu; koyu temada beyaz zemin üstünde beyaz yazı çıkıyordu. Stil CSS'e taşındı, `option` öğelerine açıkça renk verildi.

**Uyarılar sağ altta gözden kaçıyordu** — Kullanıcı formla uğraşırken bakışı ekranın üst yarısında oluyor, "kaydedildi" ya da hata mesajını görmüyordu. Panelde ve mobilde üste alındı, büyütüldü, renk kodu üst kenara taşındı.

**Mobilde deneme hesapları kapalı geliyordu** — Artık liste açık başlıyor; kurulumu deneyen kişi hangi hesapla gireceğini aramıyor.


**Header araması çoğu ekranda çalışmıyordu** — Süzme `style.display` ile yapılıyordu; ekranların kendi sayfalaması da aynı özelliği değiştirdiği için ikisi çakışıyor ve satırlar geri açılıyordu. Artık CSS sınıfıyla süzülüyor, sayfalama kendi işini yapıyor. Kutunun altında **sonuç rozeti** çıkıyor (`1 sonuç / 50`) — kullanıcı "çalışıyor mu" diye tereddüt etmiyor.

Test: cari 15→1, malzeme 50→1, bakım takibi 13→1, yevmiye 357→1, zimmet 12→1.

**Barkodlarda demo verisi yoktu** — 74 barkod, 4 oturum, 166 okuma eklendi.

İlk denemede tabloda `UNDEFINED` çıktı: demo `tur: 'tekli' / 'koli'` yazıyordu ama şemada alan adı `tip` ve değeri **barkod standardı** (ean13, code128, ic-kod). Ambalaj bilgisi ayrı alanda (`ambalaj`), çarpanla birlikte. Düzeltildi:

```
8694867170  EAN13   adet         ×1   varsayılan
8687570027  EAN13   24'lı koli   ×24
2991000030  İÇ-KOD  adet         ×1   Depo iç etiketi
```

Her malzemenin bir varsayılan tekil barkodu var; üçte birinde koli barkodu (okutunca çarpan devreye giriyor), birkaçında depo iç etiketi. Sayımlarda aynı malzeme birkaç kez okutuluyor, bazılarında fark çıkıyor.

**Masa ekranı ekranın üçte birini yiyordu** — Başlık bloğu, dört büyük sayı kartı ve ayrı araç çubuğu vardı; masalar kıvrımın altında kalıyordu. Hepsi 52px'lik tek şeride indirildi.

**Arama kutusu ve açılır listeler ilkeldi** — Arama kutusu odakta halka alıyor, ikonu renkleniyor. Açılır listelerin sistem oku yerine düzgün bir ok çizildi, yükseklikler 34px'te birleşti.

**Mobil modül kartları kesiliyordu** — Yatay kayan şeritti, dar ekranda kartların yarısı görünmüyordu. Üç sütunlu ızgaraya çevrildi; 360px'te bile kart kesilmiyor.


**Header araması yalnız bazı ekranlarda çalışıyordu** — Elle yazılmış bir eşleşme listesi vardı (`EKRAN_ARAMA`) ve her yeni ekranda güncellenmesi gerekiyordu; unutulduğu için satış faturasında çalışıp alışta çalışmıyordu. Artık aktif ekranın araç çubuğundaki ilk metin kutusu kendiliğinden bulunuyor — yeni ekran eklendiğinde hiçbir şey yapmaya gerek yok. Test: alış faturası 12 → 2 kayıt.

**Araç çubuğu hizası bozuktu** — Açılır liste, arama kutusu, tarih seçici ve düğmeler farklı yüksekliklerdeydi. Hepsi 34px'e sabitlendi, tarih kutusuna en az genişlik verildi.

**Boş masa kartları farklı boydaydı** — İki ayrı sebep vardı. Birincisi: yükseklik içeriğe bırakılmıştı, boş masada iki satır dolu masada üç satır yazı olduğu için ızgara satırları itişiyordu; sabit 108px verildi. İkincisi daha sinsiydi — kart `class="masa-kutu bos"` alıyordu ve `.bos`, boş-durum ekranının stiliydi (54px iç boşluk, soluk renk). Bu yüzden **boş masalarda masa adı hiç görünmüyordu**. Durum sınıfları `m-` öneki aldı.

**Mobil kartlar birbirine yapışıktı** — Kısayol kartlarına kendi zemini (degrade), gölge ve 12px boşluk verildi.


**NVR alarm denemesi "undefined" yazıyordu** — Sunucu her eylem için `{ eylem, sonuc, hata }` döndürüyor ama arayüz `s.ok` okuyordu. Artık sonuç okunabilir:

```
✓  Görüntü kaydı: kaydedildi
✓  Panel bildirimi: oluşturuldu
—  E-posta: atlandı (SMTP ayarı yapılmamış.)

Atlanan eylemler için ilgili ayar eksik. E-posta için Posta
Ayarı sekmesinden SMTP bilgilerini girin.
```


**"undefined gün"** — Mobil izin ekranı `gunSayisi` alanını okuyordu, panel `gun` yazıyordu. İzin türü de kod olarak geliyordu ("yillik"), artık `turAdi` ile tam adı görünüyor. Mobilden gönderilen izin talebi panelin beklediği `talep` durumuyla kaydediliyor — önceden `beklemede` yazıyordu ve onay kuyruğuna düşmüyordu.

**Personelde görev listesi yoktu** — Sekme yalnız saha elemanında açılıyordu. Ayrıca liste sadece bugün ve sonrasına bakıyordu; dün başlayıp bitmemiş bir iş listeden düşüyor ve kimse kapatmıyordu. Artık kapanmamış geçmiş görevler de görünüyor.

**Başlıktaki arama çalışmıyordu** — Kutu hiçbir yere bağlı değildi. Üç kademeli çalışıyor: ekranın kendi arama kutusu varsa oraya yazar (sunucu araması, bütün kayıtlarda arar), yoksa tablo satırlarını süzer ve sayfalamayı yeniden kurar, kart görünümlü ekranlarda kartları süzer.

**Sidebar kaydırma çubuğu** — Menünün yanında sürekli duran ince çizgi kaldırıldı. Kaydırma çalışıyor, çubuk görünmüyor.

**Demo görev dağıtımı** — `i % personeller.length` yüzünden ilk personele hiç görev düşmüyordu. Düzeltildi, ayrıca herkeste açık görev bulunsun diye altı görev eklendi.

## Destek ve bağış

Giriş ekranının sol sütununda: **%100 ücretsiz** rozeti, destek e-postası ve **Bizi destekleyin** düğmesi. Düğme bir pencere açar — cüzdan adresi, **QR kodu** ve kopyalama.

QR kodu `public/assets/js/qr.js` içinde üretilir: **bağımlılıksız, kendi yazılmış** bir kodlayıcı (Reed-Solomon hata düzeltme, byte kipi, sürüm 1-10). Sistem hiçbir dış paket kullanmıyor; bir adres göstermek için npm bağımlılığı ya da CDN eklemek bu ilkeyi bozardı, ayrıca kapalı ağda CDN'e erişilemez.

## Destek ve lisans

Sistem **%100 ücretsizdir**: lisans ücreti, kullanıcı başı ödeme, süre kısıtı yok. Giriş ekranında ve kılavuzda bu açıkça yazar.

Destek ve bağış bilgileri `data/destek.json` dosyasından okunur:

```json
{
  "eposta": "gazi.bastug@gmail.com",
  "cuzdanlar": [
    { "kod": "BTC",  "ag": "Bitcoin",       "adres": "" },
    { "kod": "USDT", "ag": "TRC-20 (Tron)", "adres": "" }
  ]
}
```

**Cüzdan adresleri boş bırakıldı — kendi adreslerinizi yazmalısınız.** Adres boşken kılavuzda o satır hiç görünmez, bağış kartı tamamen gizlenir. Yer tutucu bir adres göstermek, birinin hiçbir yere para göndermesine yol açardı.

## Kullanım kılavuzu

`/kilavuz.html` — giriş ekranındaki **Kullanım kılavuzu** bağlantısından açılır, oturum gerektirmez. Kurulum aşamasındaki kullanıcı henüz giriş yapmamıştır.

Menü **üst şeritte yatay** durur — yan menü dar ekranlarda kayboluyordu ve uzun sayfada kullanıcı nerede olduğunu göremiyordu. Şerit sığmazsa kendi içinde kayar, etkin başlık altı çizili görünür.

**Beş dilde**: Türkçe, Arapça, Kurmancî, Sorani, Farsça. Arapça, Sorani ve Farsça seçildiğinde yalnız metin değil düzen de sağdan sola döner — sol menü sağa geçer.

İçerik:

| Bölüm | Kapsam |
|-------|--------|
| Kurulum | Hazır dosya (Node gerekmez) ve kaynak kurulum, port çakışması, ağdan erişim, Windows güvenlik uyarısı |
| Örnek veri | Adım adım yükleme, kendi şirketini kurma sırası |
| Kullanıcılar | Dört hazır hesap, roller, kullanıcı adı havuzu |
| Günlük kullanım | Arama, tarih aralığı, şirket değiştirme, yedekleme |
| Mobil şube | Kim ne görür, saha elemanı hesabı açma |
| Modüller | 19 modülün her biri: ne yapar, hangi maddeleri kapsar |
| Destek | Ücretsizlik açıklaması, iletişim, bağış |

Kurulum bölümü teknik bilgisi olmayan kullanıcı düşünülerek yazıldı: *"Siyah bir pencere açılır ve içinde çerçeveli bir adres yazar"*, *"Windows bilinmeyen yayımcı uyarısı verirse Daha fazla bilgi → Yine de çalıştır"*.

Kılavuz pakete de gömülür; exe ile dağıtıldığında da açılır.

## Kurulum paketini indirme

Giriş ekranının sol menüsünde **Kaynağı indir** bağlantısı var — `vardiya.zip` olarak bütün kaynağı verir. Sistemi başka makineye taşımak ya da yedeklemek için.

ZIP üreteci `lib/zip.js` içinde, **bağımlılıksız**: CRC32 tablosu, yerel başlık, merkezi dizin ve deflate (Node'un çekirdeğindeki zlib ile). Sıkıştırma sonucu büyürse dosya ham hâliyle yazılır — zaten sıkıştırılmış dosyalarda deflate şişirir.

Pakete girmeyenler: `data/sirket` (müşterinin kendi kayıtları), oturum ve denetim dosyaları, `dagitim` klasörü. Açan kişi temiz bir kurulumla başlar.

Paketli (exe) sürümde kaynak diskte olmadığı için uç 404 döner ve bağlantı gizlenir.

## Tek dosya dağıtım

Müşteriye **tek dosya** verilir. Node.js kurulumu, npm, klasör yapısı gerekmez — çift tıklar, tarayıcı açılır.

```
node paketle.js              → vardiya-tek.js  (1.9 MB, Node gerekir)
node paketle.js --exe        → vardiya         (121 MB, Node gerekmez)
node paketle.js --exe --win  → vardiya.exe     (Windows)
```

### Müşterinin gördüğü

```
C:\Vardiya\
    vardiya.exe          ← tek dosya
    vardiya-veri\        ← kendi verisi (ilk çalıştırmada oluşur)
```

**Kaynak dosya yok.** `routes/`, `lib/`, `.js` uzantılı hiçbir şey klasörde bulunmaz.

### Kaynak koruma

Gömülü kod AES-256-GCM ile şifrelenir. Anahtar exe içinde durur ama tek parça değildir: derleme anında üretilen üç ayrı parçadan, farklı sırayla birleştirilerek çalışma anında türetilir.

Üretilen exe üzerinde ölçüm:

| Arama | Sonuç |
|-------|-------|
| İş mantığı fonksiyon adları (`kotaAsimi`, `puantajHesapla`…) | **0 eşleşme** |
| Gömülü bloğu `gunzip` ile açma | **başarısız** |

Koruma kapatılabilir (hata ayıklamak için): `node paketle.js --acik-kaynak`

### Bunun sınırı

Bu **mutlak koruma değildir** — istemci tarafında çalışan hiçbir yöntem değildir. Gördüğün C# resource yöntemi de aynı sınıfta; hatta genelde daha zayıftır çünkü resource'lar düz saklanır.

Ne yapar: kodu çıkarmayı *"tek satır komut"* olmaktan çıkarıp **tersine mühendislik gerektiren bir işe** dönüştürür. Şifre çözücünün nerede olduğunu bulmak, anahtar parçalarını toplamak, birleşme sırasını çözmek gerekir.

| Kim | Sonuç |
|-----|-------|
| Sıradan müşteri, rakip firma çalışanı | Hiçbir şey göremez |
| Meraklı yazılımcı | Saatler harcar, çoğu vazgeçer |
| Kararlı profesyonel | Çıkarır |

Gerçekten korunması gereken bir mantık varsa (hakediş formülü, fiyatlama algoritması) tek kesin yol, o kodun müşteri makinesinde **hiç bulunmamasıdır**: kritik hesap sizin sunucunuzda çalışır, exe ona bağlanır. Ama o zaman müşterinin internete bağlı olması gerekir.

Pratikte çoğu yerel ERP satışında bu şifreleme yeterlidir: müşteri kodu çalmaya değil, işini yürütmeye bakar.

### Örnek veri — panelden

Müşteri exe'yi çalıştırır, boş sistemle karşılaşır. **Yönetim → Şirketler** ekranının altındaki panelden tek düğmeyle örnek veri basar:

> *Sistemi denemek ister misiniz?*
> Gerçek bir şantiye kurgusu basılır: cari, stok, personel, fatura, yakıt, kiralık makine. Ayrı bir şirkete yazılır, kendi verinize karışmaz.

Veri **DEMO** adlı ayrı şirkete gider. Müşteri gezer, dener, sonra aynı panelden siler — kendi şirketinin verisine dokunulmaz.

`demo.js` diskte olmadığı için ayrı süreç başlatılamaz; üreteç pakete gömülür ve doğrudan çağrılır. Kaynak kurulumda ise eskisi gibi ayrı süreç çalışır.

Test: exe içinden 104 kayıt basıldı (6 sn), DEMO şirketinde 50 malzeme + 12 personel göründü, silme sonrası klasör temizlendi.

### Port

Sabit port dağıtımda sorun çıkarıyor: 3000 doluysa müşteri ne yapacağını bilemiyor.

```
vardiya --port 8080          komut satırı
PORT=8080 vardiya            ortam değişkeni
{"port": 8080}               vardiya-veri/ayar.json
```

Hiçbiri yoksa 3000 denenir. **Doluysa 3001, 3002… otomatik denenir** (20 kez).

Adres, konsolda çerçeve içinde büyük gösterilir — kullanıcıların çoğu teknik değil, "hangi adrese gireceğim" sorusunun yanıtı tek başına durmalı:

```
  ╔══════════════════════════════════════════════╗
  ║  TARAYICIDA ŞU ADRESİ AÇIN:                  ║
  ║                                              ║
  ║     http://localhost:3530                    ║
  ╚══════════════════════════════════════════════╝

  Kapatmak için bu pencereyi kapatın.
  Başka bir port için:  vardiya --port 8080
```

Aynı bilgi veri klasörüne **`ADRES.txt`** olarak da yazılır (adres + kullanıcı adı + parola). Konsolu kapatan kullanıcı dosyadan bakabilir.

Tarayıcı da gerçekten dinlenen adresle açılır — önceden sabit 3000 açılıyordu ve çakışma olunca yanlış sayfaya gidiyordu.

### Nasıl çalışıyor

62 modül, 18 arayüz dosyası ve başlangıç verisi şifrelenip gömülür. Çalışma anında:

- `require('./lib/db')` diskte dosya aramaz, bellekten çözülüp derlenir
- `public/` dosyaları bellekten servis edilir — `fs.stat`, `fs.readFile`, `fs.createReadStream` sarmalanır; sunucu kodunda tek satır değişmez
- Veri exe'nin **içinde tutulmaz**: yanında `vardiya-veri` klasörü açılır

Son madde önemli — veri exe'ye gömülseydi her güncellemede müşterinin kaydı silinirdi. Güncelleme = exe'yi değiştir, klasöre dokunma.

Windows exe'si Linux'ta üretilirken `node.exe` indirilir (çapraz derleme başka türlü olmaz). İnternet yoksa betik nereden indirileceğini söyler.

## Deneme verisi

```bash
node demo.js          # ANA şirketine basar
node demo.js IST      # başka şirkete
```

Her modüle **en az 10 kayıt** üretir; mevcut kayıtların üzerine ekler, silmez:

| Alan | Adet |
|------|------|
| Cari (VKN + vergi dairesi) | 15 |
| Malzeme (stoklu + stoksuz hizmet) | 18 |
| Depo / şube | 5 / 3 |
| Personel (özlük dosyalarıyla) | 12 |
| Evrak | 48 personel + 24 cari |
| Puantaj | 136 gün |
| İzin / avans | 10 / 10 |
| Alış + satış faturası | 61 |
| Taksitli satış sözleşmesi | 10 · 102 taksit (16'sı tahsil edilmiş) |
| Proje / iş sözleşmesi | 10 |
| Kurum hakedişi | 35 (25 onaylı, kalanı taslak) |
| Şube talebi / sevkiyat | 12 / 6 |
| Yevmiye fişi / stok hareketi | 93 / 157 |

Veri **bilerek düzensiz**: bazı evraklar eksik, bazılarının süresi geçmiş, bazı taksitler gecikmiş, bazı hakedişler taslak, bazı sevkiyatlar yolda. Böylece uyarı rozetleri, renklendirmeler ve filtreler boş görünmüyor.

Projelerin her biri 2–6 aylık hakediş üretir; farklı projelerde farklı kesinti parametreleri kullanılır (601 yapım 4/10, 602 danışmanlık 9/10, 603 bakım 7/10, 612 temizlik 9/10 + stopaj %3/%20 + teminat %6).

Mizan denk çıkar: **47.356.635,85 = 47.356.635,85**

## İnsan kaynakları## İnsan kaynakları: özlük dosyası ve evrak takibi

Personel listesindeki **klasör simgesi** özlük dosyasını açar. Yedi sekme:
öğrenim · sağlık · ehliyet/SRC · aile · sosyal güvenlik · ünvan-kademe · belgeler.

**Evrak zinciri şöyle işler:**

1. *Tanımlar → Belge türleri*: belge adı, kategorisi, **herkes için zorunlu mu**, geçerlilik süresi (ay) ve kaç gün önceden uyarılacağı.
2. *Tanımlar → Personel risk grupları*: gruba bağlı zorunlu belgeler seçilir. Örn. **Buraj Makinesi Operatörü → Sağlık Raporu, Göz Tarama Testi, Psikoteknik Test**.
3. Personelin özlük dosyasında **risk grubu** seçilir.
4. Beklenen belge listesi = herkes için zorunlu olanlar **+** risk grubunun gerektirdikleri.
5. Belge yüklenince geçerlilik tarihi belge türündeki süreden otomatik hesaplanır (sağlık raporu 12 ay → 10.01.2025 girildi, 10.01.2026 çıktı).
6. Süre dolunca kayıt **"süresi geçmiş"**, uyarı gününe girince **"süresi yaklaşıyor"** olur.

**Evrak yükleme:** her belge satırında "Yükle" düğmesi PDF veya resim alır (en fazla 6 MB), dosya şirket klasöründeki `dosyalar/` altına yazılır, JSON'a yalnız üstveri girer. Yüklü belgede indirme simgesi çıkar. Satırlar renklenir: **eksik ve süresi geçmiş kırmızı**, süresi yaklaşan sarı, tamam yeşil.

**Cari evrakları** aynı motoru kullanır: belge türünde "Kimden isteniyor" alanı *cari* seçilince vergi levhası, faaliyet belgesi, imza sirküleri, ticaret sicil gazetesi, ISO 9001, vergi borcu yoktur yazısı gibi belgeler cari kartından istenir.

**Personel → Evrak Takibi** ekranı tüm personeli tarar: kimde ne eksik, kimin belgesi bitmiş, kimin dosyası tam. Risk grubuna ve duruma göre süzülür.

## Kesinti oranları dosya parametresidir

**Oranlar sistem sabiti değildir.** Her hakediş dosyası (iş/sözleşme) açılırken kendi kesinti parametreleri girilir; bu oranlar dosyaya yazılır ve sözleşme süresince değişmez. Aynı kesinti başka bir taşeronun dosyasında farklı oranda olabilir.

Her kesinti satırında girilenler:

| Alan | Anlamı |
|------|--------|
| Ad | "KDV Tevkifatı 2/10", "Yapım İşleri Stopajı %3" … |
| Tip | tevkifat · stopaj · damga · teminat · SGK · avans · ceza · diğer |
| Pay / Payda | Kesir olarak (2/10) — oran otomatik hesaplanır |
| Oran % | Doğrudan yüzde (%3, %20) |
| Matrah | KDV tutarı · Matrah (E) · Genel toplam (G) |
| Hesap | Kesintinin işleneceği muhasebe hesabı |

Örnek — aynı 50.000 ₺ hakediş, iki farklı dosya:

```
A TAŞERONU (altyapı yapım işi)          B TAŞERONU (makine bakım hizmeti)
  KDV tevkifatı 2/10  10.000×%20 = 2.000  KDV tevkifatı 7/10  10.000×%70 =  7.000
  Yapım stopajı %3    50.000×%3  = 1.500  Serbest meslek %20  50.000×%20 = 10.000
  Teminat %6          50.000×%6  = 3.000
  H = 6.500  →  I = 53.500              H = 17.000  →  I = 43.000
```

Tanımlar → kesinti tablosu yalnızca **şablon katalogudur**: dosya açarken oradan seçilir, oran dosyaya kopyalanır. Katalogdaki oran sonradan değişse bile açılmış dosyalar etkilenmez (test edildi: katalog 7/10 → 9/10 yapıldı, dosyanın 2. ay hakedişi %70 ile hesaplanmaya devam etti).

## KDV tevkifat oranları

`data/tevkifat-katalogu.json` — KDV Genel Uygulama Tebliği kod listesi (26 kalem):
601 yapım işleri 4/10, 602 etüt-proje 9/10, **603 makine-teçhizat bakım-onarım 7/10**, 606 işgücü temini 9/10, 612 temizlik 9/10, 624 ticari reklam 3/10…

*Tanımlar → Tevkifat katalogu*'ndan seçilenler şirketin kesinti tablosuna kopyalanır; oran, matrah ve muhasebe hesabı orada düzenlenir. Kurum hakedişinde ve faturada bu listeden seçilir.

> Oranlar tebliğ değişiklikleriyle güncellenir. Katalog başlangıç noktasıdır; yürürlükteki oranı mali müşavirinizle doğrulayın.

## Kurum hakedişi ekranı

Artık tüm kurumların hakedişleri tek listede değil: önce **hakedişi olan kurumlar** (iş sayısı, sözleşme toplamı, tahakkuk, kesinti, ödenecek, son hakediş tarihi), kurumun üzerine tıklayınca **yalnız o kurumun hakedişleri** açılır. "Kurumlara dön" düğmesiyle geri çıkılır.

## İzin ve avans

**İzinler:** yıllık izin hakkı kıdeme göre hesaplanır (1-5 yıl 14 gün, 5-15 yıl 20 gün, 15+ 26 gün), gün sayısından hafta tatilleri düşülür, çakışan izin engellenir, yıllık izinde bakiye aşımı uyarı verir. Talep → onay/ret akışı ve personel bazlı bakiye tablosu.

**Avanslar:** avans ödemesi `Personel avansları BORÇ / kasa-banka ALACAK` fişi üretir. Hakediş ekranında avans alanına yazılan tutar mahsup edilir; mahsup edilmiş avans silinemez, silinen avansın fişi ters kayıtla düzeltilir.

## Bu turda düzeltilen hatalar

- **Vazgeç düğmesi çalışmıyordu.** Sonradan üretilen modallarda yalnız başlıktaki ✕ bağlıydı; olay devrine geçildi.
- **Akordeon menü** — bir ana menü açılınca diğerleri kapanıyor.
- **Genel Bakış dil değiştirmiyordu** — metinler koda gömülüydü, sözlüğe taşındı.
- **Para birimi "₺" olarak sabitti.** Artık simge ve ondalık basamak sayısı aktif şirketin ülke profilinden geliyor (TRY 2 hane, IQD 0 hane).
- **Tarayıcı `confirm`/`alert` kutuları** yerine uygulamanın kendi modal diyaloğu (21 çağrı çevrildi).
- **Onay kutuları** tarayıcı varsayılanı yerine tasarlandı; tutar satırları büyütülüp renklendirildi.
- **Menü rozetleri** — bekleyen taslak fatura, onay bekleyen talep, yoldaki sevkiyat, vadesi gelen taksit sayısı kırmızı rozetle görünüyor.

## Kullanıcı, şirket ve şube bağı

- **Kullanıcı → şirket:** Kullanıcılar ekranındaki formda "Erişebileceği şirketler" listesi. Hiçbiri seçilmezse tüm şirketlere erişir. Kullanıcı listesinde her satırda rozet olarak görünür.
- **Personel → şube:** Personel kartında "Bağlı şube" alanı; şubeler aktif şirketin içinde tanımlanır.
- **Personel → birim:** Tanımlar → Birimler tablosundan beslenir.
- **Personel fotoğrafı:** kartta bağlantı (URL veya data URI) olarak tutulur, listede yuvarlak avatar olarak görünür.

## Panelim — personel özet ekranı

Personel rolüyle giren kişi muhasebe menüleri arasında kaybolmasın diye bütün kişisel bilgileri tek ekranda toplar: **7 kart** — bu ayki puantaj, yıllık izin bakiyesi, avans ve masraf, zimmetimdekiler, evrak durumu, hakedişlerim, malzeme taleplerim. Her kart tıklanınca ilgili ekrana gider.

Yetkili kullanıcı üstteki listeden başka bir personelin panelini de açabilir.

`node demo.js` çalıştırıldığında **personel** ve **sef** kullanıcıları otomatik olarak birer personel kartına bağlanır; aksi halde Panelim boş açılır.

## Sekmeli ekranlar

Bir ekranda birden çok tablo varsa alt alta dizilip kaydırma yaratmak yerine **sekme** kullanılır. İzinler ekranı: *İzin kayıtları* | *Yıllık izin bakiyeleri*. Aynı anda tek tablo görünür, sayfalama ve yazdır düğmesi aktif sekmeye göre yönlenir.

Bakiye tablosunda kıdem, hak edilen, kullanılan, kalan ve **kullanım oranı çubuğu** var. Renklendirme: hakkı bitmiş kırmızı, %75 üzeri kullanmış sarı, bol izni kalan yeşil, hak etmemiş soluk.

Yazdırma: `izinler` (kayıtlar) ve `izin-bakiye` (bakiyeler) ayrı listeler.

## Ürün seçici

Fatura, sözleşme ve malzeme talebi satırlarında açılır kutu yerine **aranabilir modal** kullanılır — 10.000 kalemde de çalışır:

- Kod, ad, barkod ve kategoride arama
- Kategori ve tip (stoklu/hizmet) süzgeci
- Stok ve fiyat kolonu, kritik stok renklendirmesi
- `↑ ↓` ile gezinme, `Enter` ile seçme
- Kendiliğinden açılmaz; ürün kutusuna tıklanınca gelir ve **her zaman en üst katmanda** durur (fatura formunun arkasında kalmaz)
- 200'den fazla sonuçta ilk 200 gösterilir, arama daraltılınca hepsi görünür

## Genel bakış panelleri

Ekran üç bölümden oluşur:

1. **Kişisel şerit** (kullanıcının personel kartı varsa) — avatar, bu ayki gün sayısı, kalan izin, açık avans, zimmet adedi, son hakediş neti; sağda "Panelim" düğmesi. Her öğe tıklanabilir.
2. **Kartlar** — yetkiye göre değişir. Yöneticide sekiz modül kartı; personel rolünde kendi verileri (puantajım, kalan iznim, açık avansım, zimmetimdekiler, son hakedişim) — böylece dar yetkili kullanıcı boş ekranla karşılaşmaz.
3. **İki blok yan yana** — bekleyen işler ve son muhasebe hareketleri.

Sekiz canlı kart: satış/alış faturaları (6 aylık mini sütun grafikle), çek portföyü, cari bakiye, kasa-banka, stok değeri, aktif personel, kurum hakedişi. Değerler **sayarak** belirir, kartlar sırayla açılır, üst çizgi duruma göre renklenir (yeşil/sarı/kırmızı/mavi). Karta tıklayınca ilgili ekrana gider.

Altında **bekleyen işler** listesi: taslak fatura, vadesi gelen taksit, vadesi geçen çek, onay bekleyen talep/izin/masraf, yoldaki sevkiyat, eksik evrak. Her satır tıklanabilir. `prefers-reduced-motion` açıksa animasyonlar kapanır.

## Tedarikçi arama

**Problem:** "Motorun X parçasını arıyorum ama hangi firma satıyor bilmiyorum." Cari listesinde 500 firma var, hangisinin ne sattığı kayıtlı değil.

**Çözüm:** Cari kartına serbest etiket eklenir (*hidrolik, rulman, elektrik pano, nakliye*). Arama ekranı hem etiketlere hem **geçmişte faturalanan kalemlere** bakarak firma önerir ve neden önerdiğini gösterir.

Sıralama: etiket tam eşleşmesi (100 puan) > geçmiş fatura (70+) > ünvan eşleşmesi (40) > evrak tamlığı (30) > işlem sayısı. **Evrakları tam olanlar öne çıkar** — devlet kurumu gibi belge arayan yerlerde işi hızlandırır.

Test:
```
"motor parçası" → Karadeniz Makine (112p, etiket-tam) · Selçuk Otomotiv (112p)
"hidrolik"      → Karadeniz Makine (112p, etiket-tam) · Akdeniz Elektrik (85p, geçmiş fatura)
"kablo"         → Marmara Enerji (121p) · Akdeniz Elektrik (110p) · Yıldız İnşaat (102p, geçmiş)
```

Cari kartında ayrıca **evrak klasörü** var (personeldeki gibi): vergi levhası, faaliyet belgesi, imza sirküleri, ISO 9001, vergi borcu yoktur — dosya yüklenir, süresi dolan kırmızıya döner. Kurumsal alanlar: ISO belgeleri, teminat bilgisi, tevkifat oranı.

## Giriş ekranı

İki sütunlu: solda yazılım tanıtımı (çift taraflı muhasebe, çok şirket/şube, hakediş ve tevkifat, personel özlük), sağda giriş formu. Sidebar giriş öncesinde de gerçek modül yapısını gösterir — **Finans · Operasyon · Personel · Yönetim** gruplarında 13 modül, soluk ve edilgen, altta "Menü giriş sonrası açılır" satırı.

Tümü beş dile çevrilir ve RTL'de doğru yönlenir (test edildi: Arapça `dir=rtl`, "إدارة من مكان واحد"). 1180px altında tanıtım paneli gizlenir, form ortalanır; sayfa hiçbir boyutta taşmaz.

## Giriş ekranı — yıldız geçidi

Açılışta bir Stargate dönüyor. Halka her durduğunda bir chevron kilitleniyor ve o modülün tanıtımı halkanın ortasında beliriyor:

```
Kilitleniyor: Muhasebe   →  chevron yanar, listede işaretlenir
Kilitlendi · 1/7
...
Geçit açıldı — sisteme hoş geldiniz
```

Yedi modül kilitlendiğinde olay ufku patlayarak açılıyor, ardından sakin su yüzeyine oturuyor. Sonrasında halka ağır ağır dönmeyi sürdürüyor ve modüller sırayla tanıtılmaya devam ediyor.

Teknik: SVG (39 sembol, 7 chevron) + canvas yıldız alanı + `requestAnimationFrame`. **Kütüphane yok.** Yıldızlar 30 kare/sn'de çiziliyor, sekme arka plana geçince animasyon duruyor (pil dostu). `prefers-reduced-motion` açıksa animasyon çalışmıyor, geçit doğrudan açık gösteriliyor. 720px altında sahne gizleniyor.

İkon kutularının genişliği sabit — ikon fontu yüklenemezse (ağ kesik, kurumsal güvenlik duvarı) ligatür adı düz metin olarak görünüp satırı dağıtmasın diye.

## Merkezi NVR yönetimi

Sahada tek marka olmuyor: şantiyede Hikvision, depoda Dahua, eski binada ONVIF uyumlu başka bir cihaz. Hepsi tek ekrandan yönetilir.

**Dört sürücü:**

| Marka | Protokol | Kayıt arama | Olay günlüğü | Disk durumu |
|-------|----------|-------------|--------------|-------------|
| **Hikvision** | ISAPI (HTTP+XML) | ✓ CMSearch | ✓ | ✓ |
| **Dahua** | HTTP CGI | ✓ mediaFileFind | ✓ | ✓ |
| **ONVIF** | SOAP (Profile S/G) | ✓ FindRecordings | — | — |
| **Genel** | Snapshot adresi | — | — | — |

Üçü de HTTP Digest kimlik doğrulaması kullanır; iki aşamalı imzalama kendi yazıldı (bağımlılık yok).

**Parola güvenliği** — cihaz parolası her istekte gönderilmek zorunda olduğu için özet değil AES-256-GCM ile şifrelenip saklanır. Anahtar dosya sisteminde ayrı tutulur. Parola hiçbir API yanıtında dönmez:

```
açık parola yanıtta: False
parolaSifreli alanı:  False
```

**Harita** — cihazlar enlem/boylamla yerleştirilir. Zemin OpenStreetMap karolarıdır ama ham bırakılmaz: CSS süzgeciyle ters çevrilip renk döndürülür, koyu temayla uyumlu bir haritaya dönüşür. Soldaki ağaçtan cihaz seçilince harita oraya uçar ve kanalları açılır.

Kapalı ağda karolar yüklenemezse kendiliğinden **şema kipine** düşer: ızgara, işaretçiler ve bağlantı durumu çalışmaya devam eder, kırık resim simgesi görünmez. Kip elle de değiştirilebilir.

**Kamera duvarı** — 2×2'den 5×5'e düzen, sayfalı (82 kamera → 10 sayfa).

**Erişilemeyen cihaz koruması** — 16 kutuluk duvarda cihazlar kapalıysa saniyede 16 istek boşa gider; her biri cihazın zaman aşımını bekler ve sistem gözle görülür yavaşlar. Üç katmanlı koruma:

| Katman | Ne yapar |
|--------|----------|
| İstemci | Çevrimdışı bilinen kanala hiç istek atmaz, kutuya "Çevrimdışı" yazar |
| Sunucu | Hata veren kanalı karantinaya alır: 15sn → 30sn → 60sn → 5dk |
| Akış motoru | Aynı anda en çok 12 ffmpeg süreci (`VARDIYA_AKIS_SINIRI` ile değişir) |

Ölçüm: ilk istek cihaza gider (502), sonrakiler **7-8 ms'de 503** döner — cihaza hiç gidilmez. Cihaz "durum yokla" ile geri gelince karantina kalkar. Tarayıcı NVR'a doğrudan bağlanamaz (farklı ağ, kimlik doğrulama); sunucu araya girer, **NVR parolası istemciye hiç gitmez**.

### Akış motoru (ffmpeg)

Snapshot yoklaması donma yapar: her kare için yeni HTTP bağlantısı, NVR her seferinde JPEG üretir, ağ gecikmesi doğrudan görüntüye yansır. 16 kameralı duvarda saniyede 16 istek demektir.

ffmpeg RTSP'yi **bir kez** açar ve sürekli okur:

| Biçim | Nasıl oynar | Gecikme | Kullanım |
|-------|-------------|---------|----------|
| **MJPEG** | `<img>` ile doğrudan, kütüphane gerekmez | ~0,5 sn | Kamera duvarı |
| **HLS** | `.m3u8` + `.ts`, Safari yerel oynatır | ~4 sn | Uzun izleme, düşük bant |

**Süreç havuzu** — aynı kamerayı beş kişi izlese de tek ffmpeg süreci çalışır, kareler hepsine dağıtılır. Test:

```
3 izleyici → akış sayısı: 1 · izleyici: 3
```

Son izleyici ayrılınca süreç 30 saniye sonra kapanır; kimse izlemiyorken CPU yakmaz. 25 saniyedir kare gelmeyen akış (kamera düştü) kendiliğinden kapatılır. Kamera kapalıysa yeniden bağlanma aralığı kademeli uzar, sonsuz döngüye girmez.

**Üç kalite kademesi:** düşük 480p/4fps · orta 854p/8fps · yüksek 720p/12fps. Duvarda alt akış, büyük görüntüde ana akış kullanılır.

HLS **kopyalama kipinde** çalışır: kamera zaten H.264 gönderdiği için yeniden kodlama yapılmaz, CPU neredeyse boşta kalır.

**Klip dışa aktarma** — Dahua'nın `.dav` ve Hikvision'ın ham akışı tarayıcıda oynamaz; ffmpeg MP4'e çevirir. Önce kopyalama denenir (59 ms), olmazsa yeniden kodlanır.

ffmpeg kurulu değilse sistem çalışmaya devam eder: kamera duvarı kare yoklama kipine düşer, panoda uyarı çıkar.

**Kırpma ve kare kaydetme** — görüntüye tıklayınca büyür, fareyle dikdörtgen çizilir, not yazılıp kaydedilir. Tutanağa eklenecek deliller böyle toplanır.

**Kayıt arama** — birden çok kamerada aynı anda: "dün 14:00–16:00 arası bütün depo kameraları". Bulunan kayıtlar indirilir ya da RTSP adresi alınıp VLC'de açılır.

**Durum izleme** — bütün cihazlar yoklanır, çevrimdışı olan ve diski %92'yi geçen için uyarı üretilir:

```
[baglanti-kesildi] Şantiye NVR çevrimdışı — Cihaz 403 döndü. ISAPI açık mı?
[baglanti-kesildi] Eski Bina NVR çevrimdışı — ONVIF hatası (403).
```

Cihaz geri geldiğinde de kaydedilir. Kanal senkronu kullanıcının verdiği adları ve grupları korur; cihazdan kaybolan kanal silinmez, pasife çekilir.

## Satış noktası (POS) ve restoran

**İki çalışma biçimi:** perakende (barkod okut, öde, fiş bas) ve restoran (masa aç, sipariş ekle, mutfağa düşür, hesap al).

**Kasa vardiyası** — gün başında devir tutarıyla açılır, sonunda sayılan nakitle karşılaştırılır:

```
VRD-20260807-01 · 2 fiş · net satış 1.206,46 · ortalama fiş 603,23
  nakit 217,22 · kart 325,84 · veresiye 663,40
  sayılan 682,22 vs beklenen 717,22 → FARK −35,00
  kasa noksanı muhasebeleştirildi
```

Açık adisyon varken vardiya kapanmaz. Fark 680/679 hesabına yazılır.

**Parçalı ödeme** — bir hesap birden çok araçla ödenir: 217 nakit + 326 kart. Altı ödeme türü: nakit, kredi kartı, havale, yemek kartı, **veresiye** (cari hesaba yazılır), **ikram** (gider yazılır).

Nakit ödemede yuvarlak para tuşları çıkar (kalan tutar, 50'lik, 100'lük…), para üstü hesaplanır.

**Adisyon** — servis ücreti (nokta bazında %), oransal indirim, ürün notu ("az pişmiş"), ikram işaretleme, masa taşıma.

```
AD-20260807-0001 · Masa 1 · 3 kişi
   ara toplam 431,00 · servis %5 21,55 · KDV 90,51 → TOPLAM 543,06
```

**Mutfak ekranı** — her ürünün hazırlandığı birim bellidir (mutfak, bar, ızgara, tatlı). Sipariş girilince oraya düşer; bekliyor → hazırlanıyor → hazır → servis edildi. 20 dakikayı aşanlar kırmızı yanıp söner. 15 saniyede bir kendiliğinden tazelenir.

Her satış **stoktan düşer**, muhasebe fişi kesilir (kasa/banka → satış geliri + KDV, ayrıca satılan malın maliyeti). Fiş iptali stok ve muhasebeyi geri alır.

**Fiş** dar termal biçimde (80 mm) basılır, **Z raporu** ürün bazlı satış dökümüyle birlikte.

## Barkod

**Bir malzemenin birden çok barkodu olur** — okunan hangisiyse miktar o katsayıyla çarpılır:

```
8690000000012  → 1 adet
2990000000019  → 24 adet (koli)   ← sistem üretti
```

EAN-13 kontrol hanesi doğrulanır (`8690000000099` reddedilir). Barkodu olmayan malzemeler için **299 ön ekli iç barkod** üretilir.

**Okuma oturumu** — el terminaliyle çalışırken her okuma tek tek kaydedilir, oturum sonunda toplu işlenir. Dört tür:

| Tür | Neyle karşılaştırır | Kapanışta |
|-----|---------------------|-----------|
| **Sayım** | Depodaki kayıtlı stok | Fark stoğa işlenir + muhasebe fişi |
| **Mal kabul** | Alış faturası | Eksik/fazla raporlanır |
| **Sevkiyat** | Satış faturası | Eksik varsa çıkışa izin verilmez |
| **Transfer** | — | Kaynaktan düşer, hedefe girer |

Okuma sırasında anında geri bildirim: *listede yok*, *fazla okundu*, *tanınmayan barkod*. Tanınmayan barkod da kaydedilir, sonradan eşleştirilir.

Barkod etiketleri 48×30 mm yapışkan etiket sayfası olarak basılır (ürün adı, kod, çizgi, fiyat).

## Depo yerleşimi — hangi dolapta ne var

**Problem:** "Adam malzeme arıyor ama hangi dolapta vida var bilmiyor."

Üç kademeli fiziksel adres: **dolap → raf → göz**.

```
"civata" → Cıvata M10 · stok 1.138 adet
   → Merkez Deposu · A-01 · A-01-R2 · A-01-R2-G3
      tarif: Depo girişinden sola, ikinci sıra
      etiket: M10 galvaniz
```

Her göze malzeme yerleştirilir, göz etiketi ve "en az bulunması gereken" miktar tanımlanır. Stok o miktarın altına düşerse **azalmış** işareti çıkar. Yeri tanımlı olmayan malzemeler **adressiz** olarak sayılır ve listelenir.

Arama **Türkçe karakter duyarsız**: "civata" yazan "Cıvata"yı, "sase" yazan "Şase"yi, "govde" yazan "Gövde"yi bulur. Bu kural bütün modüllerin aramalarında geçerli.

## Aidat gider şablonları

Site, OSB ve lojman yönetimleri her ay aynı gider kalemlerini aynı anahtarlarla paylaştırır. Şablon bir kez tanımlanır, aidat dağıtımında seçilir.

**Altı dağıtım anahtarı:** eşit · m² başına · oda başına · **daire tipine göre** · arsa payı · kişi başına.

**Daire tipi katsayısı** — 1+0: 0,7 · 1+1: 1 · 2+1: 1,4 · 3+1: 1,8. Site yönetimi kendi katsayılarını tanımlar.

Aidat dağıtırken şablon seçilir (kalemler, katsayılar ve kapsam otomatik gelir) ya da elle girilir — ikisi de mümkün.

**Dönem özeti** — "Ağustos ayında ne dağıttık?" sorusunun cevabı:

```
2026-08  toplam 56.579,22 · açık 19.676,00 · tahsilat %65,2 · 16 abone
    Klima / soğutma      8 adet ·  5.213 kWh ·  24.879,75
    Elektrik            14 adet ·  4.233 kWh ·  16.256,20
    Su                  15 adet ·    277 m³  ·  14.031,45
    Doğalgaz             6 adet ·    344 m³  ·   5.514,24
    Güneş (üretim)       3 adet ·  1.892 kWh ·  −4.222,95
```

## Üretim

**Zincir:** ürün ağacı → rota → iş emri → üretim kaydı → maliyet.

**Ürün ağacı (reçete)** çok kademeli. Yarı mamuller açılır, fire payı miktara eklenir:

```
Konveyör Bandı 3m
  Boyalı Gövde              1,00 adet  × 7.610,03  [YARI MAMUL]
    Kaynaklı Şase           1,00 adet  × 6.699,25  [YARI MAMUL]
      Çelik Profil 40x40   12,60 metre ×   285,00   (fire %5 dahil)
      Sac Levha 2mm         2,59 m²    ×   640,00   (fire %8 dahil)
      Kaynak Teli           1,85 kg    ×   195,00
    Elektrostatik Boya      0,95 kg    ×   420,00
  Elektrik Motoru 1.5kW     1,00 adet  × 4.850,00
  Rulman 6204               8,16 adet  ×   168,00
  → malzeme 14.405,56 + işçilik 944,33 + GÜG 264,41 = BİRİM 15.614,30
```

**Rota** — hangi istasyonda kaç dakika, kaç kişiyle. İstasyonun işçilik ve makine saat ücreti maliyetin temeli.

**İş emri** — reçeteden ihtiyaç listesi çıkar, stok yeterliliği kontrol edilir. Eksik varsa uyarır; zorlayarak da başlatılabilir. Atölyeye verilecek **iş emri belgesi** yazdırılır (malzeme çekme listesi + operasyon rotası + imza satırları).

**Üretim bildirimi** — sağlam / normal fire / **anormal fire** ayrı ayrı girilir. Hammadde stoktan düşer, mamul stoğa girer, muhasebe fişi atılır (150 → 152). Fiili tüketim reçeteden farklıysa elle düzeltilir; maliyet anında yeniden hesaplanır.

**İki tür fire:**
- **Normal fire** — beklenen kayıp (kesim payı), maliyete dahil
- **Anormal fire** — hata/bozuk parti, maliyete girmez, doğrudan gider yazılır (680 hesabı) ve %10 üstündeyse onaya düşer

**Maliyet karşılaştırması** — planlanan (reçeteden) ile gerçekleşen (fiili stok maliyetinden) yan yana:

```
IE-2026-0001 Kaynaklı Şase    30/30  planlanan 200.978  gerçekleşen 200.977  sapma  %+0,0
IE-2026-0002 Boyalı Gövde     26/25  planlanan 190.251  gerçekleşen 213.082  sapma  %+7,7
IE-2026-0003 Konveyör Bandı   12/12  planlanan 187.372  gerçekleşen 194.397  sapma  %+3,7
```

Kırılım çubuklu: malzeme %78 · işçilik %12 · makine %6 · genel üretim gideri %4.

**Üretim panosu** — açık emirler ilerleme çubuklarıyla, 6 aylık maliyet grafiği, mamul bazlı üretim, istasyon doluluk oranları.

Üretim kaydı geri alınabilir: stok hareketleri iade edilir, muhasebe fişi ters çevrilir, tamamlanan emir yeniden açılır.

## Mutabakatlar

Kayıtlarımızı karşı tarafın beyanıyla karşılaştırır. Beş tür: **banka** (ekstre), **cari** (mutabakat mektubu), **stok** (fiziki sayım), **personel** (bordro/ödeme listesi), **hakediş** (idare tahakkuku).

**Kademeli eşleştirme** — her kayıt en fazla bir kez eşleşir:

| Kademe | Ölçüt |
|--------|-------|
| Kesin | Belge/dekont no + tutar |
| Güçlü | Tarih + tutar (tam) |
| Olası | Tutar + ±3 gün |
| Toplu | Karşıdaki bir kayıt bizdeki 2–3 kaydın toplamı |

Sonuç üç kümede: eşleşen · yalnız bizde (karşı taraf işlememiş) · yalnız karşıda (biz işlememişiz).

```
Banka mutabakatı · Ana Vadesiz TL      [farkli ] eşleşen 1 · fark 142,25
  YALNIZ KARŞIDA: HESAP ISLETIM UCRETI −185,00 · VADESIZ FAIZ TAHAKKUKU 42,75
Cari mutabakatı · Yıldız İnşaat        [mutabik] eşleşen 17 · fark 0,00
```

Banka ekstresi **metin yapıştırarak** yüklenir; tarih, açıklama ve tutar otomatik ayrıştırılır (CSV, noktalı virgül, Excel kopyala).

**Tutarlılık kontrolü** — dosya açmadan sistemin kendi içindeki tutarsızlıklar: mizan denkliği, banka hareket/muhasebe farkı, eksi stok, cari-hesap uyumu, açık avanslar, ayrılan personelde kalan zimmet, hakediş aşımı.

## Malzeme izleme

**Problem:** "Personel zimmetli malzemeyi bırakıp gidiyor, sonra malzeme nerede kimde bilinmiyor. Adam fabrika içinde malzemeyi bulamıyor."

**Üç teknoloji, tek model:**

| Teknoloji | Nerede | Nasıl çalışır |
|-----------|--------|---------------|
| **GPS / LoRa** | Açık alan | Enlem/boylam gelir, harita üzerinde nokta |
| **Beacon (BLE)** | İç mekan | Sabit okuyucular sinyali duyar; en güçlü duyanın konumu = etiketin konumu. RSSI'dan yaklaşık uzaklık çıkar |
| **RFID / UWB** | Geçiş noktası | Kapıdan geçince kaydedilir |

**"Nerede?" araması** — asıl ihtiyacın cevabı:

```
"matkap" → 2 sonuç
  Şarjlı Matkap → B Blok · Zemin · Üretim (~1,4 m)
    durum: bolge-disi · 180 dk önce · İHLAL: A Blok depo alanı
  Şarjlı Matkap → B Blok · Zemin · Bakım atölyesi (~2,5 m)
```

**Ekran üç bölümlü:** solda süzülebilir varlık listesi, sağda harita, üstte görünüm/iz/canlı anahtarları.

**Gerçek harita** — bağımlılıksız slippy map (OpenStreetMap karoları). Sürükle, tekerlekle yakınlaştır, "hepsini sığdır". Ölçek çubuğu ve lejant var. İnternet yoksa karolar yüklenmez ama işaretçiler yine doğru konumda durur.

**İz sürme** — bir varlık seçip iz sürmeyi açınca geçmiş hareketi kesikli çizgiyle çizilir; başlangıç noktası büyük daire. Bina planında geçtiği odalar **sırayla numaralanır**.

**Arama** — kutuya yazınca liste süzülür; tek sonuç kalırsa harita otomatik oraya gider ve bilgi kartı açılır. İç mekandaki bir varlık aranırsa görünüm otomatik bina planına geçer.

**Durum süzgeci** — Hepsi (18) · Bölge dışı (3) · Sessiz (6) · Normal (8); tıklayınca hem liste hem harita süzülür.

**Canlı görünüm** — 20 saniyede bir sessizce tazelenir.

**Bina planı** — kat sekmeleri, oda blokları, her odada o an bulunan varlıklar. Oda başlığında sayı rozeti.

**Bölge (geofence)** iki türlü: daire (merkez + yarıçap, haversine ile mesafe) ve iç mekan (okuyucu listesi). Etiket bölge dışına çıkarsa **alarm** üretilir ve denetim kaydına düşer.

**Durum tespiti:** normal · sessiz (eşik süresi sinyal yok) · bölge dışı · sinyal yok · pil zayıf (%15 altı).

Etiketler malzemeye, demirbaşa, **zimmete** ya da personele bağlanır; izlenen değer toplamı hesaplanır (deneme verisinde 4,6 milyon ₺).

Toplu sinyal uç noktası var — gateway bir seferde çok etiket bildirebilir.

## Abone ve sayaç yönetimi

Belediye, OSB, site yönetimi ve lojman işleten kurumlar için. **Dokuz sayaç türü:**

| Tür | Birim | Not |
|-----|-------|-----|
| Su | m³ | kademeli tarife |
| Elektrik | kWh | trafolu sayaçta çarpan |
| Doğalgaz | m³ | kışın tüketim 1,8 kat |
| Isıtma (kalorimetre) | kcal | lojman/ortak alan |
| **Klima / soğutma** | kWh | yazın 2,2 kat, kışın 0,15 kat |
| Sıcak su | m³ | |
| **Güneş enerjisi** | kWh | **üretim sayacı** — akış ters |
| Atık su | m³ | |
| Buhar | ton | |

**Güneş enerjisi mahsuplaşması:** çatısına panel kuran abone şebekeye elektrik satar. Bu bir üretim sayacıdır; tahakkuk **eksi tutarla** oluşur ve abonenin borcunu düşürür:

```
Zeynep Arslan Dairesi · 794 kWh üretim → −1.772,21 (abonenin alacağı)
Kardeşler Market      · 440 kWh üretim →   −982,08
```

**Mevsimsellik** tür bazında ayrı: doğalgaz ve ısıtma kışın artar, klima ve güneş yazın.

**Kademeli tarife** — su faturası genelde kademelidir: ilk 10 m³ ucuz, sonrası pahalı. Tüketim dilim dilim fiyatlanır:

```
Ayşe Demir Dairesi · 23 m³ tüketim · Mesken su tarifesi
  0–10 m³     10 × 18,50 =  185,00
  11–20 m³    10 × 27,40 =  274,00
  21–30 m³     3 × 41,20 =  123,60
  Sabit bedel                25,00
  Atık su payı (%40)        233,04
  matrah 840,64 + KDV%20 168,13 = TOPLAM 1.008,77
```

Ek kalemler iki türlü: **oran** (tüketim bedelinin yüzdesi — atık su payı) ve **birim** (tüketim × fiyat — dağıtım bedeli). Tarife ekranında 25 birimlik örnek üzerinden canlı önizleme var.

**Okuma → tahakkuk** — endeks girilir, tüketim = (yeni − eski) × çarpan. Endeks geriye gidemez; sayaç turladıysa ayrı işaretlenir. Tahakkuk otomatik kesilir.

**Anormal tüketim uyarıları:**
- Ortalamanın 3 katından fazla → *kaçak veya arıza olabilir*
- Sıfır tüketim → *sayaç durmuş olabilir*
- Ortalamanın %20'sinin altı → *sayaç müdahalesi olabilir*

**Toplu okuma** — mobil cihazdan gelen liste tek istekte işlenir, hatalı satırlar ayrı raporlanır. Ekranda endeks girilirken tüketim anlık hesaplanır.

**Ön ödeme ve tahsilat** — abone önceden para yatırabilir (bakiye eksiye geçer). Tahsilat girilince **en eski tahakkuktan başlayarak** otomatik kapatılır, makbuz numarası üretilir, muhasebe fişi atılır.

**İki türlü faturalama:**
- **Tekil** — her aboneye ayrı fatura (cari kartına bağlı olmalı)
- **Toplu** — bütün tahakkuklar tek faturada (kurum kendi içinde dağıtır)

**Abone panosu** — aktif abone/sayaç sayısı, bu ay tahakkuk, toplam borç, gecikmiş tahakkuk, okunmayan sayaç; tür bazlı tüketim dağılımı, 6 aylık seyir grafiği, en çok tüketenler ve en borçlular.

**Abone dosyası** dört sekmeli: sayaçlar (son okumalarıyla), tahakkuklar, tahsilatlar, zaman çizelgesi.

Deneme verisi: 16 abone, 39 sayaç (10'u uzaktan okumalı), 6 tarife, 179 okuma ve tahakkuk, mevsimsel tüketim (kışın doğalgaz 1,8 kat).

## Yakıt takibi — "yakıt girdabı" çözümü

**Problem:** Tankerci az boşaltıp çok yazıyor. Operatör bidonla çekiyor, "eksavatöre koydum" diyor. Buharlaşma bahane ediliyor. Araca tanımlı günlük yakıttan fazlası çıkıyor, kimse fark etmiyor. Depo eksiliyor ama kimin aldığı belli değil.

**Altı katmanlı kontrol:**

**1. Depo muhasebesi** — teorik bakiye = alım + transfer − dolum. Fiziki sayım girilince fark çıkar, tolerans (varsayılan %0,5 buharlaşma payı) aşılırsa alarm. Fark muhasebeleştirilebilir (kayıp gider yazılır).

**2. Tüketim normu** — her aracın normu tanımlı (6,8 lt/100km; 12,5 lt/saat). İki dolum arası gerçek tüketim hesaplanır, norm aşımı yüzdesi kırmızıya döner.

**3. Sayaç tutarlılığı** — km/saat geriye gidemez (kayıt reddedilir). **Sayaç ilerlemeden yakıt alınması en güçlü hırsızlık sinyali** — tek başına 45 puan.

**4. Çift kayıt** — her dolumda veren (tankerci/pompacı) ve alan (şoför/operatör) ayrı yazılır. İkisi aynı kişiyse +18 puan.

**5. Tanker seferi mutabakatı** — tankere yüklenen ile araçlara dağıtılan karşılaştırılır; fark şoför sorumluluğuna yazılır.

**6. Anomali puanı (0–100)** — sekiz sinyal toplanır:

| Sinyal | Puan |
|--------|------|
| Sayaç ilerlememiş | 45 |
| Depo kapasitesinden fazla dolum | 40 |
| Norm %50'den fazla aşılmış | 35 |
| Bir günde aşırı mesafe | 20 |
| Veren ve alan aynı kişi | 18 |
| Aynı gün ikinci dolum | 15 |
| Mesai dışı saat | 12 |
| Tam yuvarlak miktar (göz kararı) | 8 |

40 üstü şüpheli, 70 üstü ciddi. Satır kırmızılaşır, denetim kaydına düşer.

**Tüketim karnesi:** her aracın fazla yakılan litresi paraya çevrilir.

```
ARAÇ         DOLUM   LİTRE  MESAFE  GERÇEK  NORM  SAPMA  FAZLA BEDEL
Jeneratör       11   4.703     314    13,4  12,5  %+7,4       13.545
Kamyonet        11     648   4.551    13,2  12,5  %+6,0        1.502
Binek Araç      10     276   3.575     6,8   6,8   %0,0            0
```

Tank sayımı örneği — kaçak yakalanıyor:
```
Merkez sabit tank      bakiye 2.332 lt  → sayım farkı  −54 lt (%−2,29)
Şantiye mobil tanker   bakiye 1.026 lt  → sayım farkı  −97 lt (%−8,63)
```

## Onay akışı (workflow)

**Problem:** "Personel izin alacak: önce proje yöneticisi, sonra departman müdürü, sonra İK. Ama başka şubede başka sırayla olabilir. Müdür tatildeyse kim onaylayacak?" Onayı kullanıcıya sabitlemek çalışmaz — kişi ayrılır, akış çöker.

**Çözüm — üç katman:**

**1. İş modeli** — adlandırılmış şablon ("Standart personel izin akışı"). Hangi konuda çalışacağı (12 konu: izin, avans, masraf, malzeme talebi, fatura, kurum hakedişi, bordro, ihale, teklif, servis, sözleşme, şube ikmali) ve hangi adımlardan geçeceği burada tanımlanır. Şube ve birime bağlanır; kapsamı dar olan model önceliklidir.

**2. Adım** — onaylayan **kişi değil konum** olarak yazılır:

| Tip | Anlamı |
|-----|--------|
| `rol` | O role sahip herkes |
| `unvan` | O ünvana sahip personel |
| `birim` | Birimin sorumlusu |
| `amir` | **Talebi açanın amiri** — dinamik çözülür |
| `kisi` | Belirli bir personel |
| `sube-sorumlusu` | Kaydın şubesinin sorumlusu |

Ek kurallar: **tutar eşiği** (alt/üst sınır), paralel onay (biri yeter / hepsi gerekli), süre limiti, ret davranışı.

**3. Talep** — kayıt onaya girince model çözülür, adımlar sırayla açılır, onaylayanlara bildirim düşer. Her karar kim-ne zaman-hangi notla verildiğiyle saklanır (denetim izi).

**Vekalet:** tatile çıkan onaylayıcı vekil bırakır; onaylar ona yönlenir ve *"Murat Aydın adına Hasan Kurt onayladı"* diye kaydedilir.

Test çıktısı — tutar eşiği aynı modelde farklı akış üretiyor:
```
15.000 TL → 2 adım: Amir onayı → Muhasebe onayı
40.000 TL → 3 adım: Amir onayı → Muhasebe onayı → Genel müdür onayı
```

Uçtan uca: talep → 3 aşamalı onay → ödeme → muhasebe fişi, mizan denk.

**Bağlı modüller:** izin, avans talebi, masraf fişi, malzeme talebi. Kurum hakedişi, servis ve teklif için modeller hazır. Model tanımlı değilse kayıt onaya girmez, doğrudan işlenir — geriye dönük uyumlu.

**Bildirim çanı** başlıkta: okunmamış sayısı rozetle, tıklayınca panel açılır, bildirime tıklayınca talep detayı gelir, dakikada bir tazelenir.

## Avans talebi

Personel artık avans **talep edebiliyor** (eskiden yalnız muhasebe ödeme girebiliyordu). Talep onay akışından geçer, onaylanınca muhasebe "Öde" der ve avans kaydı + muhasebe fişi oluşur.

## İhale modülü

Kamu ihale süreci (4734 sayılı KİK mantığı) baştan sona takip edilir:

**1. Takip** — İlan görülür, **İKN** ile kaydedilir (2026/458912 biçimi doğrulanır). Usul (açık, belli istekliler, pazarlık, doğrudan temin, 21/b), tür (yapım, mal, hizmet, danışmanlık), yaklaşık maliyet, teminat oranları, yeterlik şartları girilir.

**2. Birim fiyat teklif cetveli** — Her poz için **maliyet analizi**: malzeme + işçilik + makine + taşıma + diğer = birim maliyet. Kâr oranı yazılınca birim fiyat hesaplanır; birim fiyat elle yazılırsa kâr oranı hesaplanır. Maliyetin altında fiyatlanan poz **kırmızı** gösterilir.

**3. Kırım oranı** — Yaklaşık maliyete göre teklifin ne kadar altında olduğu sürekli hesaplanır. Eksi çıkarsa (yaklaşık maliyetin üstünde teklif) kırmızı uyarı.

**4. Teminat** — Geçici (%3) ve kesin (%6) teminat mektupları; banka, mektup no, vade, süresiz seçeneği. Komisyon girilirse gider fişi atılır. İade takibi yapılır.

**5. Sonuç** — Rakip teklifleri girilir, sıralama otomatik çıkar (kendi teklifimiz de listede işaretli). Kaybedilirse kazanan firma ve bedel kaydedilir.

**6. Kazanılırsa → İŞE dönüşür.** İhale pozları iş pozlarına aktarılır, sözleşme bedeli teklif tutarı olur, iş no üretilir. Buradan sonra **Kurum Hakedişi** modülü devralır ve A–I şemasıyla hakediş kesilir.

Yazdırma: ihale listesi, birim fiyat cetveli (**idareye verilecek** sürüm ve **maliyet bilgili iç kullanım** sürümü ayrı).

## Müşteri teklifi (proforma)

İhaleden farkı: müşterinin "şu işi kaça yaparsınız" sorusuna verilen cevap.

`taslak → gönderildi → (kabul | red | süresi geçti)`

- **Kâr takibi:** her satırda maliyet tutulur, satır ve toplam kâr marjı anlık hesaplanır; zararına satılan satır kırmızı.
- **Revizyon:** pazarlık sonrası teklif revize edilir; eski sürüm silinmez, `TKL-2026-0001-R1` diye saklanır — hangi fiyattan neye indiğimiz görünür.
- **Dönüşüm:** kabul edilen teklif tek tuşla **faturaya** ya da **taksitli satış sözleşmesine** dönüşür; kalemler ve fiyatlar aynen aktarılır.
- **A4 teklif belgesi:** firma/müşteri kutuları, kalem tablosu, toplamlar, "Yalnız …" satırı, ödeme şekli, teslim süresi, garanti, geçerlilik.

## Varlık dosyası — bir cihazın hayat hikâyesi

**Problem:** Bir ultrasonik ölçüm cihazı alınıyor, aradan yıllar geçiyor. Teknik özellikleri neydi, şeması nerede? Kimden alındı, hangi sözleşmeyle, kim onayladı? Kaç kez arızalandı, neden? Nereye tamire gitti, ne değişti, hangi firmadan parça alındı? Toplam ne kadar harcandı, kim götürdü, kim onayladı, kim yaptı? Kim kullandı, kaç saat çalıştı? Cihaz elde ama **geçmişi yok**.

Her demirbaşın altında yedi kayıt kümesi tutulur ve hepsi tek bir **zaman çizelgesinde** birleşir:

| Sekme | İçerik |
|-------|--------|
| **Künye** | Üretici, üretim yılı, voltaj, güç, ağırlık, boyut + sınırsız özellik çifti (işlemci, kapasite, gaz tipi…), bakım periyodu (ay ve sayaç) |
| **Belgeler** | Teknik şema, kullanım kılavuzu, sözleşme, fatura, garanti, sertifika, ruhsat, sigorta, fotoğraf — dosya yüklenir |
| **Parçalar** | Cihazın bileşen ağacı: parça no, marka, seri no, adet, ömür, kritik mi, son değişim tarihi |
| **Arızalar** | Ne zaman, ne oldu, belirti, ağırlık (düşük→kritik), kim bildirdi, kaç gün durdu, nasıl giderildi |
| **Servis geçmişi** | Nereye gitti, hangi firma, şikâyet, tespit, yapılan iş, **değişen parçalar** (adet, fiyat, değişim sebebi), işçilik, nakliye, **kim götürdü / kim onayladı / kim teslim aldı / hangi teknisyen yaptı**, servis fatura no |
| **Kullanım** | Hangi personel, hangi tarihler arası, hangi şantiye, hangi görev |
| **Sayaç** | Çalışma saati / km okumaları, geriye gidemez |

**Maliyet takibi:** alım maliyeti + bütün servis harcamaları = **toplam sahiplik maliyeti**. Örnek çıktı:

```
DB-2026-0009 · Jeneratör · Aksa 60 kVA
  üretici: Aksa Power Generation | güç: 60 kVA | bakım: 6 ayda bir / 250 saatte bir
  MALİYET: alım 340.000 + servis 66.398 = TOPLAM SAHİPLİK 406.398
  3 servis · 2 arıza · 10 parça değişti · 712 gün duruş · 1.710 saat
```

Servis tamamlanınca: gider fişi atılır (`bakım onarım gideri BORÇ / kasa-banka-satıcı ALACAK`), depodan çıkan parçalar stoktan düşer, cihaz aktife döner, bağlı arıza kapanır, değişen parçaların son değişim tarihi güncellenir.

## Bakım takibi

Periyodik bakımı **yaklaşan, geçen ve arızalı** cihazlar tek listede. Bakım zamanı iki türlü hesaplanır: takvim (ay) ve sayaç (saat/km). Satıra tıklayınca varlık dosyası açılır. Aciliyet sırasına göre dizilir: arızalı → bakımı geçmiş → yaklaşan → normal.

## Demirbaş (sabit kıymet)

**Zimmetten farkı:** zimmet, depodaki malzemenin personele verilmesidir (stok hareketi). Demirbaş ise şirketin **duran varlığıdır** — araç, sunucu, jeneratör, mobilya. Stokta durmaz, sabit kıymet hesabında durur ve amortismana tabidir. Bir demirbaş ayrıca personele zimmetlenebilir (laptop gibi); biri muhasebe kaydı, diğeri sorumluluk kaydıdır.

| İşlem | Muhasebe |
|-------|----------|
| Alış | Demirbaşlar BORÇ / kasa-banka-satıcı ALACAK |
| Amortisman | Amortisman gideri BORÇ / Birikmiş amortisman ALACAK |
| Satış | Birikmiş amortisman + kasa BORÇ / Demirbaşlar ALACAK, fark kâr/zarar |
| Hurda | Birikmiş amortisman BORÇ / Demirbaşlar ALACAK, kalan net değer zarar |

Amortisman **normal (eşit tutarlı)** yöntemle ay bazında hesaplanır: `(maliyet − kalıntı değer) / (faydalı ömür × 12)`. Faydalı ömür dolunca durur. "Amortisman ayır" düğmesi bekleyen tutarı tek fişte döneme yazar.

Hesap planına eklendi: `254 Taşıtlar`, `255 Demirbaşlar`, `257 Birikmiş Amortismanlar`, `679/689 Diğer olağandışı gelir-gider`.

## Personel malzeme talebi ve zimmet

**İş mantığı — iki tür malzeme:**

| Tür | Örnek | Ne olur |
|-----|-------|---------|
| **Sarf** | Eldiven, kalem, maske | Depodan çıkar, **gider yazılır**, geri istenmez |
| **Demirbaş / zimmet** | Laptop, telsiz, matkap, iş elbisesi | Depodan çıkar ama **şirketin malı kalır**, personele **zimmetlenir**, çıkışta geri istenir |

Ayrım malzeme kartındaki **"zimmetli"** işaretiyle yapılır.

**Akış:** personel talep açar → birim amiri onaylar (miktar düşürülebilir) → depo teslim eder → sarf gidere yazılır, demirbaş için **zimmet kaydı** açılır (kime, ne zaman, seri no) → iade edilince stoğa geri girer.

Muhasebe: sarf `genel yönetim gideri BORÇ / stok ALACAK`, zimmet `255 Demirbaşlar (zimmetli) BORÇ / stok ALACAK`. İadede ters kayıt.

**Çıkış kontrolü:** `/api/personel/:id/zimmet-kontrol` açık zimmeti olan personelin çıkışını engeller. Test: *"Selin Arslan üzerinde 2 açık zimmet var (4.150 ₺). Çıkış için iade edilmeli."*

## Banka işlemleri

Her banka hesabı ayrı bir muhasebe alt hesabına bağlanır (102.01, 102.02, 102.03), bakiyeler ayrı izlenir.

| İşlem | Kayıt |
|-------|-------|
| Tahsilat | banka BORÇ / cari ALACAK |
| Ödeme | cari BORÇ / banka ALACAK |
| Virman | hedef banka BORÇ / kaynak banka ALACAK |
| Banka masrafı | gider BORÇ / banka ALACAK |
| Faiz geliri | banka BORÇ / gelir ALACAK |

**Toplu maaş ödemesi:** onaylanmış bordronun netleri tek fişte ödenir — her personel ayrı satır (`335 Personele Borçlar` borç), toplam banka hesabından çıkar, hakediş "ödendi" olur.

Hesap ekstresi: devir + hareketler + yürüyen bakiye (`/api/banka/:id/ekstre`).

## Menü geçiş animasyonu

Sidebar'dan bir modül seçilince ekranın **tam ortasında** yaklaşık 2 saniyelik bir geçit açılır: dış halka döner, iç halka ters yönde döner, çember üzerindeki 9 sembol sırayla yanar, ortadaki yüzey içeri çekilip dalgalanır, hedef ekranın adı altta belirir. Yeni ekran geçitten çıkıyormuş gibi bulanıklıktan netleşerek gelir.

`prefers-reduced-motion` açıksa animasyon hiç çalışmaz. Aynı ekrana tekrar tıklanınca tetiklenmez.

## Liste yazdırma

Her listenin araç çubuğunda **Yazdır** düğmesi var; A4 yatay tablo olarak açılır:

`malzemeler · personel · depolar · stok-hareketleri · talepler · sevkiyatlar · kurum-hakedis · isler · hakedis · cekler`

Her ekranın araç çubuğunda **iki düğme** var:

- **Yazdır** — bütün kolonlarla basar
- **Kolon simgesi** — pencere açar, hangi kolonların basılacağını seçtirir (`?kolon=0,2,5`)

Yazdırılabilir listeler: `hesap-plani · yevmiye · mizan · malzemeler · personel · depolar · stok-hareketleri · talepler · sevkiyatlar · eksikler · kurum-hakedis · isler · hakedis · avanslar · masraflar · personel-talepler · zimmetler · cekler · banka · demirbaslar` — 20 liste, hepsi test edildi, 200 dönüyor.

Ayrıca her satırda kendi yazıcı simgesi vardır (`?id=3` ile tek kayıt).

## Ekrana sığan düzen

Sayfa artık aşağı doğru uzamıyor. Başlık, özet kutuları ve araç çubuğu sabit kalıyor; **yalnız tablonun gövdesi kendi içinde kayıyor**, tablo başlığı yapışık duruyor, sayfalama çubuğu her zaman altta görünüyor.

**Tabloda dikey kaydırma yoktur.** Sayfa başına satır sayısı sabit değil; ekrana kaç satır sığıyorsa o kadar gösterilir (en az 3, en çok 30). Pencere büyütülüp küçültüldüğünde yeniden hesaplanır.

Ölçüm:

```
1700×900   hesap planı 11 · yevmiye 9 · satış fat. 9 · cari 9 · stok 11 · personel 9 satır
1400×700   hesap planı  8 · yevmiye 7 · satış fat. 4 · cari 7 · stok  8 · personel 5 satır
```

Sayfa taşması her ekranda **0px**. 700px yükseklikte özet kutuları gizlenir, başlık alanı daralır.

Tablo **tam genişlikte** kalır (`display:table` korunur); kaydırma tablonun kendisinde değil sarmalayıcısında olur. Ölçüm (1700×900): ana alan 1480px, tablo 1442px — boşluk yok. Sayfa yüksekliği 900px / pencere 900px, **taşma yok**.

Birden çok tablo veya kart içeren ekranlarda (raporlar, izin bakiyeleri) ekranın tamamı kayar; bunu `App.duzeniAyarla()` kendiliğinden belirler.

## Yazdırma ve PDF

Bağımlılık eklemek yerine tarayıcının **"Yazdır → PDF olarak kaydet"** yeteneği kullanılıyor: sunucu A4 düzeninde, yazdırmaya hazır HTML döndürüyor.

| Belge | Uç nokta |
|-------|----------|
| Fatura (tevkifatlı düzen dahil) | `/api/yazdir/fatura/:id` |
| Kurum hakedişi (A–I tablosu) | `/api/yazdir/hakedis/:id` |
| Cari ekstresi | `/api/yazdir/ekstre/:id` |
| Çek / senet bilgi formu | `/api/yazdir/cek/:id` |
| Taksitli satış sözleşmesi + ödeme planı | `/api/yazdir/sozlesme/:id` |

Yazıcı simgesi şu listelerde her satırda var: **satış faturaları, alış faturaları, çek/senet, cari (ekstre), vade takibi (ödeme planı), sözleşmeler, kurum hakedişleri**.

Fatura çıktısı yüklediğiniz e-arşiv örneğinin düzenini izliyor: satıcı/alıcı kutuları, fatura tipi-no-tarih tablosu, iskonto ve KDV kolonlu kalem tablosu, alt toplam bloğu (Mal Hizmet Toplam → Tevkifata Tabi İşlem → Ödenecek Tutar), **Tevkifat Sebebi** ve **"Yalnız: …"** satırı.

Tutar yazıyla yazılıyor: `53.000 → ELLİÜÇBİNTÜRKLİRASI`, `1.234,56 → BİNİKİYÜZOTUZDÖRTTÜRKLİRASIELLİALTIKURUŞ`.

## İade faturası

Kesinleşmiş faturanın **ters yönde** iadesi kesilir (satışın iadesi alış gibi işler). Kısmi iade için satır bazında miktar girilir. Orijinal fatura defterde kalır, iptal edilmez — mevzuat açısından doğru olan budur.

Test: `SF-2026-0011` (satış) → `IS-2026-0001`; kesinleştirildiğinde stok geri girdi (`153 Ticari Mallar` borç), `191 İndirilecek KDV` borç, karşı hesap alacak. Mizan denk kaldı. Aynı faturaya ikinci iade engelleniyor.

## Satır renklendirme

Vade takibindeki renklendirme tüm tablolara yayıldı (`data-vurgu` özniteliği + tek CSS kuralı):

- **kırmızı** — gecikmiş taksit, süresi geçmiş evrak, karşılıksız çek, eksi stok, risk limiti aşımı
- **sarı** — taslak fatura/hakediş, süresi yaklaşan belge, kritik stok altı, onay bekleyen izin
- **yeşil** — kesinleşmiş, tahsil edilmiş, tamamlanmış
- **soluk** — iptal ve pasif kayıtlar

## Duman testi

`tools-smoke.js` her ekranı gezip **her düğmeye tıklar, açılan her modalı ve modal içindeki her sekmeyi açar**, JS hatası olup olmadığını raporlar. Puppeteer kurulu bir ortamda:

```bash
node server.js &            # sunucu
node demo.js                # veri
node tools-smoke.js         # tarama
```

Son tarama: **263 düğme, 228 modal, 0 JS hatası.**

Bu test, "ekran listede çalışıyor ama modal açılınca patlıyor" türü hataları yakalamak için var — `bugun is not defined` hatası tam olarak böyle bir hataydı ve liste testleri onu görmüyordu.

## Bilinen sınırlar

- Sunucu tarafı doğrulama mesajları şimdilik Türkçe; arayüz metinleri 5 dilde.
- Eşzamanlı çok kullanıcıda fiş/fatura numarası çakışabilir (JSON dosya tabanlı, kilit yok). Tek şantiye/tek ofis ölçeği için yeterli.
- Şirket bağlamı istek başına modül düzeyinde tutulur; yeni bir uç nokta yazarken db çağrıları arasında `await` kullanmayın.
- Sözleşme modelinde gelir tahsilat anında doğar. Tahakkuk esasına göre raporlama isteyen mali müşavir için dönem sonu düzeltme kaydı gerekebilir.
- Uygulama HTTP üzerinden çalışır; şirket ağı dışına açacaksanız önüne HTTPS vekil sunucu (nginx/caddy) koyun.## Mobil şube

`/m.html` — webview için tek dosya. Ayrı CSS/JS dosyaları zayıf bağlantıda sırayla yüklenir; her şey tek dosyada olunca ilk açılış tek istekte tamamlanır.

### Tasarım

Şantiyenin kendi görsel dili: iş makinesi sarısı, asfalt siyahı, uyarı bandı. Sahada güneş altında eldivenle kullanılır — dokunma alanları 56px, sayılar iri, kontrast yüksek.

İkonların tamamı **inline SVG**. Emoji kullanılmadı (platforma göre başka görünür), ikon fontu kullanılmadı (kapalı ağda yüklenmez).

**Depo göstergesi** ekranın imzası: kalan yakıt bir depo penceresi gibi arkadan dolar. Operatör bir bakışta "yarısı bitmiş" görür, sayıyı okumak zorunda kalmaz. Kota dolduğunda kırmızıya döner.

**Barkod** SVG ile çizilir. Flex + `<i>` denemesi güvenilmez çıktı — tarayıcı 1-2px genişlikleri yuvarlayıp çubukları birleştiriyordu. SVG'de her çubuk kesin koordinatta durur.

### Açılış ekranı ve gezinme

Alt menüye her modül için sekme koymak sürdürülebilir değil: yedi sekmede yazılar okunmuyor, dokuzda parmak kayıyor. Bu yüzden **alt menü dört sekmede sabit** (Özet + en sık kullanılan iki iş + Ben), geri kalan her şey açılış ekranındaki **kısayol kartlarından** açılıyor.

Kartlar rozet taşıyor: bekleyen görev sayısı, ödenmemiş fatura tutarı, girilmemiş puantaj, "giriş yok". Kullanıcı ana ekrandan ne yapması gerektiğini görüyor, sekmeleri tek tek gezmiyor.

Sekmede olmayan bir ekran açıldığında üstte geri oku çıkıyor, başlıkta ekranın adı yazıyor.

**Barkod artık kapalı geliyor.** Önceden her açılışta yarım ekranı kaplıyordu; şimdi tek satırlık başlık, dokununca açılıyor.

### Giriş ekranı

Sabit üst şerit (marka), kayan orta bölüm, sabit alt şerit. Ortada altı modül kartı — Yakıt, Makine, Mesai, Masraf, Faturam, Salon — üç sütunlu ızgarada; her genişlikte tam sığar.

Form kendi paneli içinde. Alt şeritte kısa bilgi ve panele dönüş bağlantısı.

### Deneme hesapları

Giriş ekranında hangi rolün neyi gördüğü yazıyor — dokununca o hesapla giriyor:

| Hesap | Gördüğü |
|-------|---------|
| `admin` | Her şey · salon, dağıtım, panel |
| `hasan.op` | Yakıt hakkı, barkod, makine puantajı |
| `kemal.tk` | Barkod okutma, litre verme |
| `personel` | Mesai, izin, masraf, özlük |
| `abone` | Su/elektrik faturası, tüketim grafiği |

Bu bölüm yalnız demo verisiyle kurulmuş sistemlerde görünür. Gerçek kurulumda hesaplar bulunmaz, bölüm hiç açılmaz — müşteri ekranında deneme parolaları durmaz.

### Mobile geçiş — iki yerden

**Giriş ekranından:** `login.html` altında "Mobil şube" bağlantısı. Sahadaki kişi panele hiç uğramadan telefon ekranına gider.

**Panelden:** sidebar'ın altındaki düğme, yeni sekmede açar.

### Panelden mobile geçiş

Sidebar'ın altında **Mobil şube** düğmesi var. Aynı oturumla yeni sekmede açılıyor; kullanıcı yeniden giriş yapmıyor. (Panele giriş yapmış bir tarayıcıda `/m.html` doğrudan açılır — oturum çerezi ortak.)

### Kimlik tipi ekranı belirler

Ayrım **sunucuda** yapılır; istemciye güvenilmez.

| Kimlik | Menü |
|--------|------|
| **Saha elemanı** (makine sahibi/operatör) | Özet · Yakıtım · Makinem · Görevler |
| **Tankerci** | Özet · Dağıtım · Görevler |
| **Personel** | Özet · Mesai · İzin · Masraf · Görevler |

"Makinem" sekmesi yalnız kendisine makine tanımlı olanlara açılır.

Mobil hesaplar panel adresini elle yazarsa 302 ile mobil şubeye yönlendirilir.

### Makine puantajı — mobilden

Kiralık makine sahibi günlük çalışmayı kendi girer. Saatler türüne ayrılır ve **girerken ne ödeneceği anında görünür**:

```
7 verimli + 2 bekleme + 1 arıza = 10 saat girildi
→ 8 saat ödenecek  (7×100% + 2×50% + 1×0%)
⚠ Beyan 10 saat, sayaç 8 saat ilerlemiş (-2)
```

Sayaç sapması anında işaretlenir. Kayıt taslak olarak düşer, saha şefi onaylar, ay sonu mutabakatına girer. Böylece "9 saat çalıştım / 6 saat gördüm" tartışması gün gün kayda geçer.

Gelecek tarihe puantaj girilemez; onaylanmış gün değiştirilemez.

### Salon — komi ekranı

Komi salonda dolaşır, masaya gider, sipariş alır. Kasaya gidip beklemez.

**Masa haritası** bölgelere ayrılmış ızgara. Renk uzaktan okunur: boş gri, dolu **sarı**, hesap isteyen **kırmızı**. Her masada tutar, kalem sayısı ve kaç dakikadır oturulduğu yazar.

Boş masaya dokunmak adisyon açar. Ürünler kategori şeridiyle gezilir, dokundukça sepete düşer, `+ −` ile miktar ayarlanır ve tek dokunuşla mutfağa gider — üç çay bir kahve için dört ayrı istek atılmaz.

**Ödeme kasada kalır.** Komi yalnız "Hesap iste" der; iskonto, ikram, fiş kapatma kasanın işidir.

Menü süzgeci: satış fiyatı olan her malzeme kantinde satılmaz — çimentonun da satış fiyatı vardır. Hazırlık birimi (mutfak/bar) tanımlı ürünler önceliklidir. 40 malzemeden 10'u menüye düştü.

### Faturam — abone mobil şubesi

Lojmanda oturan personel kendi su/elektrik aidatını telefondan görür; idareye sormaz.

Fatura listesi, ödeme geçmişi ve **altı dönemlik tüketim grafiği**. Fatura detayında kademe dökümü var — *"neden bu kadar tuttu"* sorusunun yanıtı orada.

Son dönem tüketimi ortalamanın %60 üstündeyse uyarı çıkar: *"Kaçak ya da arıza olabilir."* Abone erken fark etsin.

Abonelik personele ya da cariye bağlıdır; kullanıcı yalnız kendi kayıtlarını görür — abone numarasıyla başkasının borcu sorgulanamaz.

### Özlüğüm

Personel kendi kartını görür: kıdem, ücret, izin bakiyesi, bu ayki puantaj, bordro geçmişi, üzerindeki zimmet, görevlendirmeleri.

**Eksik evrak uyarısı en üstte:** *"3 evrakınız eksik: SGK bildirgesi, sağlık raporu…"* İK'nın peşinden koşması yerine personel kendisi görür.

T.C. kimlik ve IBAN maskeli (`•••••7716`). Yalnız kendi kaydı döner — `personelId` kullanıcı oturumundan gelir, istemciden değil.

### Sahada kullanım

- **Litre girişi** büyük tuş takımıyla, klavye açılmaz. Kalan kota hazır düğme.
- **Masraf fotoğrafı** tarayıcıda küçültülür (1400px, %72 jpeg) — kamera 4-8 MB kare üretiyor.
- **Barkod alanı** kod tamamlanınca kendiliğinden sorgular; okuyucu Enter basmasa da çalışır.
- **Konum** mesai ve masrafta alınır; saha çemberi dışındaysa engellenmez ama işaretlenir.
- **Kota aşımı** onay sorusuna dönüşür; gerekçe kayda geçer ve anomali puanına işlenir.


