{
  "openapi": "3.0.4",
  "info": {
    "title": "JOI_ULUPINAR.API",
    "description": "ETA muhasebe veritabanlarındaki **cari**, **stok** ve **hizmet** kartlarına; ETA\nkurulumunun ortak tanımlarına (**fiş tipleri**, **KDV kısımları**, **döviz ve kur türü\ntanımları**, **döviz kuru geçmişi**); ayrıca entegratörden gelen **e-Fatura** ve\n**e-İrsaliye** belgelerine JWT ile korunan, IP kısıtlı ve her kiracının yalnız kendi tanımlı\nveritabanlarını gördüğü bir REST API üzerinden erişim sağlar.\n\nBu belge uygulamanın kendi uç tanımlarından **çalışma zamanında** üretilir: elle\ngüncellenen bir kopya yoktur, sürüm yükseltmelerinde `/swagger/v1/swagger.json`\nadresinden yeniden çekmek yeterlidir.\n\n## Kullanım sırası\n\n1. `POST /api/auth/token` ile kullanıcı adı + şifre + `apiKey` karşılığında JWT alınır.\n2. `GET /api/v1/firmalar` ile token sahibinin erişebildiği ETA veritabanları\n   (geçerli `etaDb` değerleri) listelenir.\n3. Kart uçları seçilen `etaDb` üzerinden **sayfalı** veri döner.\n\n## Üç ayrı kaynak: firma, master ve entegratör\n\nUçlar verinin NEREDEN geldiğine göre üç gruba ayrılır ve grupların parametreleri farklıdır:\n\n| Grup | Uçlar | Kaynak | Anahtar parametre |\n|---|---|---|---|\n| Kartlar | `/api/v1/cariler`, `/stoklar`, `/hizmetler` | Firma ETA veritabanı | `etaDb` |\n| Master tanımları | `/api/v1/master/*` | ETA kurulumunun master veritabanı | `masterDb` |\n| Belgeler | `/api/v1/gelen-faturalar`, `/gelen-irsaliyeler` | **Entegratör** (EDM / Digital Planet) | `etaDb` |\n\nBelge uçları da `etaDb` alır ama veriyi o veritabanından OKUMAZ: entegratör kimliği\n(kullanıcı, şifre, entegratör tipi) ETA'daki `SABITLER` tablosundan okunur ve istek\nmüşterinin entegratör hesabına gider. Yani aynı uç, kiracıdan kiracıya farklı bir dış\nservise bağlanır.\n\n- Yalnız **GELEN** (alış) belgeler listelenir.\n- Entegratördeki **okundu/okunmadı işareti değiştirilmez** — müşterinin başka sistemleri\n  bu işarete bağlı olabilir.\n- Liste ucu belgenin UBL'ini indirmez, yalnız başlık döner; satır ayrıntısı için detay\n  ucu (`/{uuid}`) kullanılır.\n- Tarih aralığı **zorunludur ve en fazla 31 gündür**.\n- ⚠ `toplam` alanı bu uçlarda **`null` gelebilir**: entegratör gerçek bir \"eşleşen kayıt\n  sayısı\" döndürmez. Sayfalamanın bittiği, dönen kayıt sayısının `take`'ten küçük\n  olmasıyla anlaşılır.\n- Entegratör bu belge türünü sunmuyorsa `501 BELGE_TURU_DESTEKLENMIYOR` döner. Bu bir\n  yetki ya da yapılandırma hatası DEĞİLDİR; karşı taraf o belgeyi sunmuyordur.\n\n## İki ayrı kaynak: firma ve master\n\n`/api/v1/cariler`, `/api/v1/stoklar`, `/api/v1/hizmetler` bir FİRMA veritabanından\nokur ve `etaDb` ister. `/api/v1/master/*` uçları ise ETA kurulumunun **master**\nveritabanından (`ETA_MASTER` / `ETA_MASTERV8`) okur: fiş tipleri, KDV kısımları, döviz\nve kur türü tanımları ile döviz kuru geçmişi bir firmaya değil kurulumun tamamına aittir.\n\n- Master uçları `etaDb` değil **`masterDb`** alır ve `/api/v1/firmalar` listesindeki\n  değerler burada **kullanılamaz** (tersi de geçerlidir: master veritabanı `etaDb`\n  olarak verilemez; her iki durumda da `403 ETA_DB_YETKISIZ` döner).\n- `masterDb` **zorunlu değildir**: kiracıda tek master tanımlıysa o kullanılır. Birden\n  fazla tanımlıysa (ör. hem `ETA_MASTER` hem `ETA_MASTERV8`) hangisinin okunacağı\n  belirsiz olduğu için `400 PARAMETRE_GECERSIZ` döner ve ad açıkça istenir.\n- Kiracıda hiç master tanımı yoksa `409 MASTER_DB_TANIMSIZ` döner. Bu bir yetki hatası\n  DEĞİLDİR: yönetim panelinden tanım eklenmesi gerekir. Master veritabanı adları\n  hiçbir API ucundan öğrenilemez (firmalar ucu yalnız firma veritabanlarını listeler);\n  kurulumu yapan taraftan alınır.\n\n## Veri biçimi\n\n- Kart alan adları **ETA kolon adlarının küçük harfli halidir** (`CARKOD` → `carkod`)\n  ve değerler **HAMDIR**: doldurulmamış tarihler `1900-01-01`, metinler dolgu\n  boşluklarıyla döner. İstemci karşılaştırmadan önce kendi `trim` işlemini uygular.\n- Uçlar `SELECT *` ile çalışır; kart şemalarında adlandırılan alanlar istemcinin\n  güvenebileceği alanlardır, ETA sürümüne göre **ek alanlar da gelir**\n  (şemalarda `additionalProperties`).\n- **Delta (değişenleri ver) desteklenmez:** CARKART / STKKART / HIZMET ve master tanım\n  tablolarında güncelleme damgası tutulmaz; senkron eden istemci katalogun tamamını\n  sayfalayarak çeker.\n- Kart uçlarında sayfalama sıralaması **kart kodu** üzerindedir ve eşzamanlı yazımlara\n  karşı **kararlı değildir**: sayfalama sürerken araya kayıt eklenirse bir kayıt iki\n  sayfa arasına düşebilir. Bu yüzden bir taramada **görülmeyen kayıt silinmiş\n  sayılmamalıdır.**\n- Master uçlarında sıralama, tabloyu **tekil** olarak belirleyen alan(lar) üzerindedir\n  (tanım tablolarında fiş tipi numarası, döviz kurunda `dovhartar + dovharkod +\n  dovhartur`) ve **artan**dır. Döviz kuruna yeni satırlar hep en yeni tarihle eklendiği\n  için listenin sonuna düşerler; devam eden bir tarama bundan etkilenmez.\n\n## Döviz: üç ayrı uç, biri diğerinin sözlüğü değil\n\n`/api/v1/master/doviz-tanimlari` (DOVTAN) döviz cinslerini, `/api/v1/master/doviz-kur-turleri`\n(DOVTUR) kur türlerini, `/api/v1/master/doviz-kurlari` (DOVHAR) ise tarihli kur\ndeğerlerini döner.\n\n- `doviz-kurlari` ucundaki **`kurTuru`** parametresinin tanımlı değerleri\n  `doviz-kur-turleri` ucundan okunabilir. Liste \"kur bulunan türler\" değil \"tanımlı\n  türler\"dir: ölçülen bir kurulumda 13 tanımlı türden 8'inin hiç kur satırı yoktu.\n- ⛔ **`dovizKodu` için `doviz-tanimlari` YETMEZ.** İki tablo birbirini kapsamaz:\n  ölçülen bir kurulumda DOVHAR'da kur satırı bulunan sekiz kod (`AZN`, `AED`, `EUR`,\n  `KRW`, `PKR`, `QAR`, `STERLİN`, `XDR`) DOVTAN'da hiç yoktu; buna karşılık DOVTAN'daki\n  üç kod (`ILS`, `JOD`, `SYP`) için DOVHAR'da tek satır yoktu. Kur çekecek istemci kod\n  kümesini kur verisinin kendisinden öğrenmelidir.\n- `doviz-tanimlari` içindeki `dovtaneslkod`, ETA kodunun ISO 4217 karşılığıdır\n  (`EURO` → `EUR`); kendi sisteminde ISO kod kullanan istemcinin eşleme alanı budur.\n\n## Hatalar\n\nTüm `/api` hataları RFC 7807 `application/problem+json` gövdesiyle döner ve makine\ntarafından okunabilir bir `hataKodu` taşır (bkz. `ApiProblemDetails` şeması).\nTek istisna: geçerli bir token hiç gönderilmediğinde kimlik doğrulama katmanı\n**gövdesiz** `401` ve `WWW-Authenticate: Bearer` başlığı üretir.",
    "contact": {
      "name": "JOI Yazılım",
      "url": "https://joisoft.com.tr"
    },
    "version": "v1"
  },
  "servers": [
    {
      "url": "https://ulupinar.mentoryazilim.com"
    }
  ],
  "paths": {
    "/api/v1/gelen-faturalar": {
      "get": {
        "tags": [
          "Belgeler"
        ],
        "summary": "Tarih aralığındaki gelen e-Fatura başlıklarını sayfalı döner.",
        "description": "Yalnız GELEN (alış) belgeler listelenir ve entegratördeki okundu/okunmadı işareti\nDEĞİŞTİRİLMEZ — müşterinin başka sistemleri bu işarete bağlı olabilir.\n\nBaşlıklar UBL indirilmeden, entegratörün başlık yanıtından üretilir; bu yüzden liste\nhızlıdır ama satır ayrıntısı taşımaz. Satırlar için detay ucu kullanılır.\n\n⚠ `toplam` alanı bu uçta `null` gelebilir: EDM'in başlık sorgusu gerçek bir\n\"eşleşen kayıt sayısı\" döndürmez. Sayfalamanın bittiği, dönen kayıt sayısının\n`take`'ten küçük olmasıyla anlaşılır. (EDM kiracılarında her zaman `null`'dur.)\n\n⚠ `gonderenUnvan` BU UÇTA DOLMAZ. EDM'in başlık yanıtında gönderenin ünvanını taşıyan\nbir alan yoktur; yalnız VKN (`gonderenVkn`) gelir. Ünvan gerekiyorsa VKN üzerinden\n`/api/v1/cariler` ile eşleyin. Alan sözleşmede duruyor çünkü başka bir entegratör\nbunu sağlayabilir.",
        "operationId": "Fatura_Listele",
        "parameters": [
          {
            "name": "etaDb",
            "in": "query",
            "description": "Okunacak firma veritabanı; entegratör kimliği bu veritabanından okunur.",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "baslangicTarihi",
            "in": "query",
            "description": "Bu tarih DAHİL sonrası (yyyy-MM-dd). Zorunludur.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "bitisTarihi",
            "in": "query",
            "description": "Bu tarih DAHİL öncesi (yyyy-MM-dd). Zorunludur; aralık en fazla 31 gündür.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "skip",
            "in": "query",
            "description": "Atlanacak kayıt sayısı. Varsayılan: 0.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "take",
            "in": "query",
            "description": "Sayfa boyutu. Verilmezse veya 0 ise 100 kabul edilir, azami 500.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "gonderenVkn",
            "in": "query",
            "description": "Gönderenin VKN'si (10 hane) veya TCKN'si (11 hane) ile daraltır.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "belgeNo",
            "in": "query",
            "description": "Belge numarasına göre daraltır.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sayfalı fatura başlığı listesi.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SayfaliSonucGelenFaturaOzet"
                }
              }
            }
          },
          "400": {
            "description": "Zorunlu parametre eksik, take aralık dışı (PARAMETRE_GECERSIZ) ya da tarih aralığı geçersiz/31 günden uzun (TARIH_ARALIGI_GECERSIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Token yok, süresi dolmuş veya geçersiz (gövdesiz olabilir).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "etaDb kiracının tanımları arasında değil (ETA_DB_YETKISIZ) ya da IP kısıtı (IP_YETKISIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "ETA'da entegratör tanımı eksik (ENTEGRATOR_TANIMSIZ) ya da tipi desteklenmiyor (ENTEGRATOR_TIPI_DESTEKLENMIYOR).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen sunucu hatası (SUNUCU_HATASI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "501": {
            "description": "Bu entegratörde bu belge türü desteklenmiyor (BELGE_TURU_DESTEKLENMIYOR).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "502": {
            "description": "ETA'ya ya da entegratöre erişilemedi (ETA_ERISIM_HATASI / ENTEGRATOR_HATA).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "504": {
            "description": "Entegratör zamanında yanıt vermedi (ENTEGRATOR_ZAMAN_ASIMI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [ ]
          }
        ]
      }
    },
    "/api/v1/gelen-faturalar/{uuid}": {
      "get": {
        "tags": [
          "Belgeler"
        ],
        "summary": "Tek bir gelen e-Faturayı UBL'inden çözümleyerek tam detayıyla döner.",
        "description": "Liste ucundan farklı olarak burada belgenin UBL'i entegratörden indirilir ve çözümlenir:\ntaraflar, satırlar, vergiler ve referanslar dolu gelir. Liste ucuna göre yavaştır, tek\nbelge içindir.\n\n`durum` alanı UBL'de bulunmaz; belgenin entegratördeki durumu liste ucundan okunur.",
        "operationId": "Fatura_Detay",
        "parameters": [
          {
            "name": "uuid",
            "in": "path",
            "description": "Belgenin entegratördeki tekil kimliği (liste ucundaki `uuid`).",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "etaDb",
            "in": "query",
            "description": "Okunacak firma veritabanı; entegratör kimliği bu veritabanından okunur.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Çözümlenmiş fatura.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GelenFaturaDetay"
                }
              }
            }
          },
          "400": {
            "description": "etaDb eksik (PARAMETRE_GECERSIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Token yok, süresi dolmuş veya geçersiz (gövdesiz olabilir).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "etaDb yetki dışı (ETA_DB_YETKISIZ) ya da IP kısıtı (IP_YETKISIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Bu uuid ile belge bulunamadı (BELGE_BULUNAMADI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "ETA'da entegratör tanımı eksik ya da tipi desteklenmiyor.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen sunucu hatası (SUNUCU_HATASI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "501": {
            "description": "Bu entegratörde bu belge türü desteklenmiyor (BELGE_TURU_DESTEKLENMIYOR).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "502": {
            "description": "ETA'ya ya da entegratöre erişilemedi (ETA_ERISIM_HATASI / ENTEGRATOR_HATA).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "504": {
            "description": "Entegratör zamanında yanıt vermedi (ENTEGRATOR_ZAMAN_ASIMI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [ ]
          }
        ]
      }
    },
    "/api/v1/gelen-faturalar/{uuid}/xml": {
      "get": {
        "tags": [
          "Belgeler"
        ],
        "summary": "Tek bir gelen e-Faturanın entegratördeki UBL XML'ini ham hâliyle döner.",
        "description": "Detay ucuyla aynı belgeyi verir, ama ÇÖZÜMLEMEDEN: yanıt gövdesi JSON değil,\nentegratörden ne geldiyse o XML'dir (`application/xml`). Kendi UBL çözümleyicisi olan,\nbelgeyi arşivleyen ya da e-imzasını doğrulamak isteyen istemciler içindir.\n\n⛔ İÇERİK DEĞİŞTİRİLMEZ. Belge XAdES e-imzası taşır; yeniden biçimlendirme ya da tek\nkarakterlik bir düzeltme bile imzayı geçersiz kılardı. Bu yüzden XML ne girintilenir, ne\nad alanları sadeleştirilir, ne de alan sırası değiştirilir. Entegratör içeriği ZIP olarak\nverdiyse arşiv açılır ve UTF-8 BOM'u atılır; belgenin kendisine dokunulmaz.\n\nYanıt UTF-8 kodlanır. Belge, entegratörden geldiği gibi bir XML bildirimi\n(`<?xml ... ?>`) içerebilir; istemci gövdeyi metne çevirirken kendi bildirimine\ndeğil, yanıtın UTF-8 olduğuna güvenmelidir.\n\nHata gövdeleri bu uçta da `application/problem+json`'dır — yalnız 200 yanıtı XML'dir.",
        "operationId": "Fatura_Xml",
        "parameters": [
          {
            "name": "uuid",
            "in": "path",
            "description": "Belgenin entegratördeki tekil kimliği (liste ucundaki `uuid`).",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "etaDb",
            "in": "query",
            "description": "Okunacak firma veritabanı; entegratör kimliği bu veritabanından okunur.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Belgenin ham UBL XML'i.",
            "content": {
              "application/xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "etaDb eksik (PARAMETRE_GECERSIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Token yok, süresi dolmuş veya geçersiz (gövdesiz olabilir).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "etaDb yetki dışı (ETA_DB_YETKISIZ) ya da IP kısıtı (IP_YETKISIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Bu uuid ile belge bulunamadı (BELGE_BULUNAMADI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "ETA'da entegratör tanımı eksik ya da tipi desteklenmiyor.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen sunucu hatası (SUNUCU_HATASI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "501": {
            "description": "Bu entegratörde bu belge türü desteklenmiyor (BELGE_TURU_DESTEKLENMIYOR).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "502": {
            "description": "ETA'ya ya da entegratöre erişilemedi (ETA_ERISIM_HATASI / ENTEGRATOR_HATA).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "504": {
            "description": "Entegratör zamanında yanıt vermedi (ENTEGRATOR_ZAMAN_ASIMI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [ ]
          }
        ]
      }
    },
    "/api/v1/gelen-irsaliyeler": {
      "get": {
        "tags": [
          "Belgeler"
        ],
        "summary": "Tarih aralığındaki gelen e-İrsaliye başlıklarını sayfalı döner.",
        "description": "Kurallar fatura liste ucuyla aynıdır: yalnız GELEN belgeler, okundu işareti değiştirilmez,\naralık en fazla 31 gün, `toplam` alanı `null` gelebilir (EDM kiracılarında her\nzaman `null`'dur) ve `gonderenUnvan` dolmaz — ünvan için `gonderenVkn`'i\n`/api/v1/cariler` ile eşleyin.\n\n⚠ e-İrsaliye desteği ENTEGRATÖRE BAĞLIDIR. Kiracının entegratörü bu belge türünü\nsunmuyorsa uç `501 BELGE_TURU_DESTEKLENMIYOR` döner — bu bir yapılandırma ya da\nyetki hatası değildir.\n\n⚠ `skip` BU UÇTA PAHALIDIR. EDM'in irsaliye arama anahtarında fatura tarafındaki\n`OFFSET` alanının karşılığı yoktur; atlama entegratörden `skip + take` kadar\nkayıt çekilip fazlası API tarafında atılarak yapılır. Sonuç doğrudur ama derin\nsayfalamada (ör. `skip=5000`) her istek entegratörden 5000+ kayıt çeker. Geniş\ntaramaları `skip` ile değil TARİH ARALIĞINI DARALTARAK yapın.",
        "operationId": "Irsaliye_Listele",
        "parameters": [
          {
            "name": "etaDb",
            "in": "query",
            "description": "Okunacak firma veritabanı; entegratör kimliği bu veritabanından okunur.",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "baslangicTarihi",
            "in": "query",
            "description": "Bu tarih DAHİL sonrası (yyyy-MM-dd). Zorunludur.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "bitisTarihi",
            "in": "query",
            "description": "Bu tarih DAHİL öncesi (yyyy-MM-dd). Zorunludur; aralık en fazla 31 gündür.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "skip",
            "in": "query",
            "description": "Atlanacak kayıt sayısı. Varsayılan: 0.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "take",
            "in": "query",
            "description": "Sayfa boyutu. Verilmezse veya 0 ise 100 kabul edilir, azami 500.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "gonderenVkn",
            "in": "query",
            "description": "Gönderenin VKN'si (10 hane) veya TCKN'si (11 hane) ile daraltır.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "belgeNo",
            "in": "query",
            "description": "Belge numarasına göre daraltır.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sayfalı irsaliye başlığı listesi.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SayfaliSonucGelenIrsaliyeOzet"
                }
              }
            }
          },
          "400": {
            "description": "Zorunlu parametre eksik, take aralık dışı (PARAMETRE_GECERSIZ) ya da tarih aralığı geçersiz/31 günden uzun (TARIH_ARALIGI_GECERSIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Token yok, süresi dolmuş veya geçersiz (gövdesiz olabilir).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "etaDb yetki dışı (ETA_DB_YETKISIZ) ya da IP kısıtı (IP_YETKISIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "ETA'da entegratör tanımı eksik ya da tipi desteklenmiyor.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen sunucu hatası (SUNUCU_HATASI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "501": {
            "description": "Bu entegratörde e-İrsaliye desteklenmiyor (BELGE_TURU_DESTEKLENMIYOR).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "502": {
            "description": "ETA'ya ya da entegratöre erişilemedi (ETA_ERISIM_HATASI / ENTEGRATOR_HATA).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "504": {
            "description": "Entegratör zamanında yanıt vermedi (ENTEGRATOR_ZAMAN_ASIMI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [ ]
          }
        ]
      }
    },
    "/api/v1/gelen-irsaliyeler/{uuid}": {
      "get": {
        "tags": [
          "Belgeler"
        ],
        "summary": "Tek bir gelen e-İrsaliyeyi UBL'inden çözümleyerek tam detayıyla döner.",
        "description": "Taraflar, teslimat adresi, taşıyıcı (plaka, şoför) ve satırlar çözümlenir. Faturadan\nfarklı olarak irsaliyede tutar/vergi alanları YOKTUR — UBL'de taşınmazlar.",
        "operationId": "Irsaliye_Detay",
        "parameters": [
          {
            "name": "uuid",
            "in": "path",
            "description": "Belgenin entegratördeki tekil kimliği (liste ucundaki `uuid`).",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "etaDb",
            "in": "query",
            "description": "Okunacak firma veritabanı; entegratör kimliği bu veritabanından okunur.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Çözümlenmiş irsaliye.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GelenIrsaliyeDetay"
                }
              }
            }
          },
          "400": {
            "description": "etaDb eksik (PARAMETRE_GECERSIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Token yok, süresi dolmuş veya geçersiz (gövdesiz olabilir).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "etaDb yetki dışı (ETA_DB_YETKISIZ) ya da IP kısıtı (IP_YETKISIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Bu uuid ile belge bulunamadı (BELGE_BULUNAMADI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "ETA'da entegratör tanımı eksik ya da tipi desteklenmiyor.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen sunucu hatası (SUNUCU_HATASI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "501": {
            "description": "Bu entegratörde e-İrsaliye desteklenmiyor (BELGE_TURU_DESTEKLENMIYOR).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "502": {
            "description": "ETA'ya ya da entegratöre erişilemedi (ETA_ERISIM_HATASI / ENTEGRATOR_HATA).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "504": {
            "description": "Entegratör zamanında yanıt vermedi (ENTEGRATOR_ZAMAN_ASIMI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [ ]
          }
        ]
      }
    },
    "/api/v1/firmalar": {
      "get": {
        "tags": [
          "Firmalar"
        ],
        "summary": "Token sahibinin erişebileceği ETA veritabanlarını listeler. etaDb parametresinin geçerli değerleri budur.",
        "description": "Liste her istekte veritabanından okunur: panelden bir veritabanı kaldırıldığında ya da\npasife alındığında mevcut token'lar için de anında geçerli olur.",
        "operationId": "Firma_Listele",
        "responses": {
          "200": {
            "description": "Erişilebilir veritabanları.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/FirmaYanit"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Token yok, süresi dolmuş veya geçersiz (gövdesiz olabilir).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "İstek, kiracının IP beyaz listesi dışından geldi (IP_YETKISIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen sunucu hatası (SUNUCU_HATASI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [ ]
          }
        ]
      }
    },
    "/api/v1/rf-fisleri": {
      "post": {
        "tags": [
          "Fişler"
        ],
        "summary": "Fatura ya da irsaliyeyi ETA'nın fiş aktarım (RF) tablolarına yazar.",
        "description": "Fiş üç tabloya birden yazılır — RF_FISMASTER (başlık), RF_FISHAREKET (kalemler) ve\nRF_FISTOPLAM (KDV kırılımı ile iskonto satırları) — ve bunların hepsi TEK BİR\nveritabanı işlemi içindedir: ya üçü de yazılır ya da hiçbiri.\n\n⛔ GERÇEK ETA BELGESİ BU UÇTA OLUŞMAZ. Uç yalnız aktarım katmanına yazar; fişi\nFATFIS/IRSFIS belgesine çeviren saklı yordamı (SP_RFCREATEINVOICERECEIPT /\nSP_RFCREATEDISPATCHORDER) ETA tarafındaki kendi işiniz çağırır. Aktarımın sonucu\nGET /api/v1/rf-fisleri/{masterSatirId} ile izlenir.\n\nMÜKERRER YAZIM: aynı disReferans ikinci kez gönderilirse istek 409 FIS_ZATEN_KAYITLI\nile reddedilir ve hata detayında mevcut kaydın masterSatirId'si bildirilir. Koruma\nveritabanı düzeyindedir; yeniden deneyen bir istemci çift fiş oluşturamaz.\n\nÖN KOŞUL: cari kodu CARKART'ta, tüm stok kodları STKKART'ta TANIMLI OLMALIDIR; aksi\nhalde istek 409 KART_BULUNAMADI ile reddedilir. Kod karşılaştırması ETA'nın\nharmanlamasına göre büyük/küçük harf duyarlı olabilir.\n\nTUTARLAR: satır tutarları, KDV matrahı ve KDV kırılımı gönderilen miktar, fiyat,\niskonto ve KDV oranından hesaplanır; yanıtta hesaplanan toplamlar döner ve istemci\nbunları kendi hesabıyla karşılaştırabilir.",
        "operationId": "Fis_Yaz",
        "parameters": [
          {
            "name": "etaDb",
            "in": "query",
            "description": "Kiracının erişim izni olan ETA veritabanı (bkz. /api/v1/firmalar). Zorunludur.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Fiş gövdesi.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RfFisIstek"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/RfFisIstek"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/RfFisIstek"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Fiş yazıldı. Location başlığı durum sorgusunun adresini gösterir.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RfFisYanit"
                }
              }
            }
          },
          "400": {
            "description": "Gövde ya da parametreler geçersiz (PARAMETRE_GECERSIZ / TARIH_ARALIGI_GECERSIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Token yok, süresi dolmuş veya geçersiz (gövdesiz olabilir).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "ETA veritabanı yetki dışı (ETA_DB_YETKISIZ) ya da IP kısıtı (IP_YETKISIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Aynı dış referansla fiş zaten var (FIS_ZATEN_KAYITLI), cari/stok kartı yok\n(KART_BULUNAMADI) ya da veritabanında RF tabloları bulunmuyor (RF_TABLOLARI_TANIMSIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen sunucu hatası (SUNUCU_HATASI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "502": {
            "description": "ETA veritabanına erişilemedi (ETA_ERISIM_HATASI); istek tekrar denenebilir.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [ ]
          }
        ]
      }
    },
    "/api/v1/rf-fisleri/{masterSatirId}": {
      "get": {
        "tags": [
          "Fişler"
        ],
        "summary": "Yazılmış bir fişin aktarım durumunu döner.",
        "description": "Fişin gerçek ETA belgesine çevrilip çevrilmediğini gösterir. `aktarildi` alanı\nENTEGRASYONDONE bayrağına değil, belge türüne karşılık gelen referans numarasının\n(faturada FATFISREFNO, irsaliyede IRSFISREFNO) üretilmiş olmasına bakar — bayrağı\nirsaliye yordamı kendisi set etmediği için tek başına güvenilir değildir.\n\nBu uç, aynı tabloya yazan BAŞKA uygulamaların fişlerini de okuyabilir; öyle bir\nkayıtta `kaynakEtiketi` ULUPINAR'dan farklıdır ve tanınmayan bir modül için\n`belgeTuru` boş döner.",
        "operationId": "Fis_Durum",
        "parameters": [
          {
            "name": "masterSatirId",
            "in": "path",
            "description": "POST yanıtında dönen RF_FISMASTER.MASTERSATIRID.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "etaDb",
            "in": "query",
            "description": "Kiracının erişim izni olan ETA veritabanı. Zorunludur.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Fişin durumu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RfFisDurumYanit"
                }
              }
            }
          },
          "400": {
            "description": "etaDb verilmedi (PARAMETRE_GECERSIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Token yok, süresi dolmuş veya geçersiz (gövdesiz olabilir).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "ETA veritabanı yetki dışı (ETA_DB_YETKISIZ) ya da IP kısıtı (IP_YETKISIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Bu numarada fiş yok (FIS_BULUNAMADI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen sunucu hatası (SUNUCU_HATASI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "502": {
            "description": "ETA veritabanına erişilemedi (ETA_ERISIM_HATASI); istek tekrar denenebilir.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [ ]
          }
        ]
      }
    },
    "/api/v1/cariler": {
      "get": {
        "tags": [
          "Kartlar"
        ],
        "summary": "Cari kartları sayfalı döner; her kayıtta adres ve kimlik satırları iç içedir.",
        "description": "Alt listeler yalnız o sayfadaki cari kodları için okunur (N+1 sorgu yoktur); toplam\nalanı CARKART üzerinde gerçek COUNT(*) sonucudur.\n\nAlanlar ETA kolon adlarının küçük harfli halidir (CARKOD -> carkod) ve DEĞERLER HAMDIR:\nETA'da doldurulmamış tarihler 1900-01-01 olarak, metinler dolgu boşluklarıyla döner —\nistemci karşılaştırma yapmadan önce kendisi trim uygulamalıdır.\n\nCARKART'ta güncelleme damgası bulunmadığı için \"değişenleri ver\" (delta) desteklenmez;\nsenkron eden istemci katalogun tamamını sayfalayarak çeker.\n\nOFFSET tabanlı sayfalama eşzamanlı yazımlara karşı KARARLI DEĞİLDİR: sayfalama sürerken\naraya yeni bir cari eklenirse, ekleme noktasından sonraki bir kayıt iki sayfa arasına\ndüşüp hiç dönmeyebilir. Bu yüzden bir taramada görülmeyen kayıt SİLİNMİŞ sayılmamalıdır —\nistemci \"listede yok\" durumunu karta pasif/silinmiş damgası vurmak için kullanmamalıdır.",
        "operationId": "Cari_Listele",
        "parameters": [
          {
            "name": "etaDb",
            "in": "query",
            "description": "Kiracının erişim izni olan ETA veritabanı (bkz. /api/v1/firmalar). Zorunludur.",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "kodOnek",
            "in": "query",
            "description": "Cari kodu başlangıcı. Örn. 120 (ETA'da müşteri/satıcı ayrımı kod önekiyle yapılır).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "aktif",
            "in": "query",
            "description": "true: yalnız CARCALFLAG=1, false: yalnız 0, verilmezse hepsi.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "skip",
            "in": "query",
            "description": "Atlanacak kayıt sayısı. Varsayılan: 0.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "take",
            "in": "query",
            "description": "Sayfa boyutu. Verilmezse veya 0 ise 100 kabul edilir, azami 500.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sayfalı cari kart listesi.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SayfaliSonucCariKayit"
                }
              }
            }
          },
          "400": {
            "description": "etaDb boş, skip negatif ya da take aralık dışı (PARAMETRE_GECERSIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Token yok, süresi dolmuş veya geçersiz (gövdesiz olabilir).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "ETA veritabanı yetki dışı (ETA_DB_YETKISIZ) ya da IP kısıtı (IP_YETKISIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen sunucu hatası (SUNUCU_HATASI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "502": {
            "description": "ETA veritabanına erişilemedi (ETA_ERISIM_HATASI); istek tekrar denenebilir.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [ ]
          }
        ]
      }
    },
    "/api/v1/hizmetler": {
      "get": {
        "tags": [
          "Kartlar"
        ],
        "summary": "Hizmet kartlarını sayfalı döner.",
        "description": "Cari ve stok uçlarından farklı olarak İÇ İÇE ALT LİSTE YOKTUR: hizmet kartının çoklu bir\nyan tablosu bulunmaz.\n\nAlanlar ETA kolon adlarının küçük harfli halidir (HIZKOD -> hizkod) ve DEĞERLER HAMDIR:\nETA'da doldurulmamış tarihler 1900-01-01 olarak, metinler dolgu boşluklarıyla döner.\n\nAKTİFLİK FİLTRESİ YOKTUR: HIZMET tablosunda CARCALFLAG / STKCALFLAG karşılığı bir alan\nbulunmadığı için (ETA'da doğrulandı) uç böyle bir parametre sunmaz.",
        "operationId": "Hizmet_Listele",
        "parameters": [
          {
            "name": "etaDb",
            "in": "query",
            "description": "Kiracının erişim izni olan ETA veritabanı (bkz. /api/v1/firmalar). Zorunludur.",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "kodOnek",
            "in": "query",
            "description": "Hizmet kodu başlangıcı.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "skip",
            "in": "query",
            "description": "Atlanacak kayıt sayısı. Varsayılan: 0.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "take",
            "in": "query",
            "description": "Sayfa boyutu. Verilmezse veya 0 ise 100 kabul edilir, azami 500.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sayfalı hizmet kartı listesi.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SayfaliSonucHizmetKayit"
                }
              }
            }
          },
          "400": {
            "description": "etaDb boş, skip negatif ya da take aralık dışı (PARAMETRE_GECERSIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Token yok, süresi dolmuş veya geçersiz (gövdesiz olabilir).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "ETA veritabanı yetki dışı (ETA_DB_YETKISIZ) ya da IP kısıtı (IP_YETKISIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen sunucu hatası (SUNUCU_HATASI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "502": {
            "description": "ETA veritabanına erişilemedi (ETA_ERISIM_HATASI); istek tekrar denenebilir.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [ ]
          }
        ]
      }
    },
    "/api/v1/stoklar": {
      "get": {
        "tags": [
          "Kartlar"
        ],
        "summary": "Stok kartlarını sayfalı döner; istenirse her kayıtta fiyat satırları iç içedir.",
        "description": "Alanlar ETA kolon adlarının küçük harfli halidir (STKKOD -> stkkod) ve DEĞERLER HAMDIR:\nETA'da doldurulmamış tarihler 1900-01-01 olarak, metinler dolgu boşluklarıyla döner —\nistemci karşılaştırma yapmadan önce kendisi trim uygulamalıdır.\n\nSTKKART'ta güncelleme damgası bulunmadığı için \"değişenleri ver\" (delta) desteklenmez;\nsenkron eden istemci katalogun tamamını sayfalayarak çeker.\n\nOFFSET tabanlı sayfalama gibi burada da sıralama STKKOD üzerindedir ve eşzamanlı\nyazımlara karşı KARARLI DEĞİLDİR: bir taramada görülmeyen kayıt SİLİNMİŞ sayılmamalıdır.",
        "operationId": "Stok_Listele",
        "parameters": [
          {
            "name": "etaDb",
            "in": "query",
            "description": "Kiracının erişim izni olan ETA veritabanı (bkz. /api/v1/firmalar). Zorunludur.",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "kodOnek",
            "in": "query",
            "description": "Stok kodu başlangıcı.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "aktif",
            "in": "query",
            "description": "true: yalnız STKCALFLAG=1, false: yalnız 0, verilmezse hepsi.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "fiyatlar",
            "in": "query",
            "description": "true ise her kayda STKFIYAT satırları \"fiyatlar\" dizisi olarak eklenir. Varsayılan false — bir stokta 70'e kadar fiyat satırı olabildiği için yanıtı gereksiz büyütmemek adına kapalıdır.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "skip",
            "in": "query",
            "description": "Atlanacak kayıt sayısı. Varsayılan: 0.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "take",
            "in": "query",
            "description": "Sayfa boyutu. Verilmezse veya 0 ise 100 kabul edilir, azami 500.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sayfalı stok kartı listesi.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SayfaliSonucStokKayit"
                }
              }
            }
          },
          "400": {
            "description": "etaDb boş, skip negatif ya da take aralık dışı (PARAMETRE_GECERSIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Token yok, süresi dolmuş veya geçersiz (gövdesiz olabilir).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "ETA veritabanı yetki dışı (ETA_DB_YETKISIZ) ya da IP kısıtı (IP_YETKISIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen sunucu hatası (SUNUCU_HATASI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "502": {
            "description": "ETA veritabanına erişilemedi (ETA_ERISIM_HATASI); istek tekrar denenebilir.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [ ]
          }
        ]
      }
    },
    "/api/v1/stoklar/birimler": {
      "get": {
        "tags": [
          "Kartlar"
        ],
        "summary": "Stok birim tanımlarını (STKBIRIM) sayfalı döner.",
        "description": "Bu tablo stok kartına BAĞLI DEĞİLDİR: kurulum geneli küçük bir katalogdur (ölçülen dört\nkurulumda 21–31 satır) ve stok kartlarındaki birim alanları buna atıfta bulunur.\nDört kolon taşır: birim kodu, adı, çarpan ve bölen.\n\nAlanlar ETA kolon adlarının küçük harfli halidir (STKBIRIMKOD -> stkbirimkod) ve\nDEĞERLER HAMDIR: metinler dolgu boşluklarıyla döner.\n\n⚠ Sıralama stkbirimkod + stkbirimad üzerindedir ama bu bileşim TEKİL OLMAYABİLİR:\nölçülen bir kurulumda aynı birim kodu iki kez tanımlanmıştı. Tablo tek sayfaya\nsığdığı için pratikte etkisizdir.\n\n⚠ Çarpan ve bölen alanları ölçülen kurulumların tamamında 0'dır; birim dönüşümünde\ndoğrudan kullanılamazlar.",
        "operationId": "Stok_Birimler",
        "parameters": [
          {
            "name": "etaDb",
            "in": "query",
            "description": "Kiracının erişim izni olan ETA veritabanı (bkz. /api/v1/firmalar). Zorunludur.",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "kodOnek",
            "in": "query",
            "description": "Birim kodu başlangıcı.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "skip",
            "in": "query",
            "description": "Atlanacak kayıt sayısı. Varsayılan: 0.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "take",
            "in": "query",
            "description": "Sayfa boyutu. Verilmezse veya 0 ise 100 kabul edilir, azami 500.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sayfalı birim tanımı listesi.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SayfaliSonucStokBirimKayit"
                }
              }
            }
          },
          "400": {
            "description": "etaDb boş, skip negatif ya da take aralık dışı (PARAMETRE_GECERSIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Token yok, süresi dolmuş veya geçersiz (gövdesiz olabilir).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "ETA veritabanı yetki dışı (ETA_DB_YETKISIZ) ya da IP kısıtı (IP_YETKISIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen sunucu hatası (SUNUCU_HATASI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "502": {
            "description": "ETA veritabanına erişilemedi (ETA_ERISIM_HATASI); istek tekrar denenebilir.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [ ]
          }
        ]
      }
    },
    "/api/v1/stoklar/fiyatlar": {
      "get": {
        "tags": [
          "Kartlar"
        ],
        "summary": "Stok fiyat satırlarını (STKFIYAT) sayfalı döner.",
        "description": "Aynı satırlar /api/v1/stoklar ucunda fiyatlar=true ile stok kartının İÇİNDE de dönebilir.\nBu uç onları karttan BAĞIMSIZ çekmek içindir: fiyatlar sık, katalog seyrek değişir —\nayrı uç olmasaydı fiyat tazelemek için 157 kolonluk stok kartlarını da her seferinde\nindirmek gerekirdi.\n\nAlanlar ETA kolon adlarının küçük harfli halidir (STKFIYTUTAR -> stkfiytutar) ve\nDEĞERLER HAMDIR: doldurulmamış tarihler 1900-01-01 olarak döner.\n\n⛔ MÜKERRER SATIRLAR OLABİLİR: bu tabloda hiçbir kolon bileşimi tekil değildir ve\nölçülen kurulumlarda 26 kolonun TAMAMI aynı olan TAM KOPYA satırlar bulundu\n(ETA_IZYAPIAS_2026: 12.170 satırın 11.975'i farklı; bir grupta 7 kopya). Bunun\nsonucu: art arda çekilen iki sayfada bir kopya iki kez görünüp diğeri hiç\ngörünmeyebilir. Satırlar birbirinin aynısı olduğu için veri kümesi yine de doğrudur;\n\"kayıt kayboldu\" diye yorumlanmamalıdır.",
        "operationId": "Stok_Fiyatlar",
        "parameters": [
          {
            "name": "etaDb",
            "in": "query",
            "description": "Kiracının erişim izni olan ETA veritabanı (bkz. /api/v1/firmalar). Zorunludur.",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "stokKodu",
            "in": "query",
            "description": "TAM EŞLEŞEN stok kodu. Tek bir stokun fiyatları için bunu kullanın; kodOnek ile birlikte de verilebilir.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "kodOnek",
            "in": "query",
            "description": "Stok kodu başlangıcı. Dikkat: \"159\" ön eki \"159 03 01 001\" gibi alt kodları da getirir.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "depoKodu",
            "in": "query",
            "description": "TAM EŞLEŞEN depo kodu. ⚠ Bu alan bazı kurulumlarda tamamen boştur; filtre o kurulumlarda hiç sonuç döndürmez.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fiyatNo",
            "in": "query",
            "description": "Fiyat listesi numarası (STKFIYNO). Ölçülen kurulumda 1..5 değerleri kullanılıyor.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "skip",
            "in": "query",
            "description": "Atlanacak kayıt sayısı. Varsayılan: 0.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "take",
            "in": "query",
            "description": "Sayfa boyutu. Verilmezse veya 0 ise 100 kabul edilir, azami 500.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sayfalı fiyat satırı listesi.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SayfaliSonucStokFiyatKayit"
                }
              }
            }
          },
          "400": {
            "description": "etaDb boş, fiyatNo negatif, skip negatif ya da take aralık dışı (PARAMETRE_GECERSIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Token yok, süresi dolmuş veya geçersiz (gövdesiz olabilir).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "ETA veritabanı yetki dışı (ETA_DB_YETKISIZ) ya da IP kısıtı (IP_YETKISIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen sunucu hatası (SUNUCU_HATASI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "502": {
            "description": "ETA veritabanına erişilemedi (ETA_ERISIM_HATASI); istek tekrar denenebilir.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [ ]
          }
        ]
      }
    },
    "/api/auth/token": {
      "post": {
        "tags": [
          "Kimlik"
        ],
        "summary": "Kullanıcı adı, şifre ve API anahtarı ile JWT üretir.",
        "description": "Üç bilgi de yönetim panelinden kiracıya tanımlanır.\n\nGüvenlik gereği HANGİ ALANIN YANLIŞ OLDUĞU AYRIŞTIRILMAZ: eksik/boş alan, olmayan\nkullanıcı, yanlış şifre ve yanlış apiKey durumlarının hepsi aynı 401 KIMLIK_GECERSIZ\nyanıtını döndürür.\n\nÜretilen token'a yalnız kiracı kodu (sub) konur; izinli ETA veritabanı listesi token'a\ngömülmez — yetki her istekte veritabanından okunur, böylece yetki kaldırıldığında elde\nkalan token'la erişim sürmez.",
        "operationId": "Auth_Token",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TokenIstek"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/TokenIstek"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/TokenIstek"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Token üretildi.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TokenYanit"
                }
              }
            }
          },
          "401": {
            "description": "Kullanıcı adı, şifre veya API anahtarı hatalı (KIMLIK_GECERSIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen sunucu hatası (SUNUCU_HATASI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/master/fatura-fis-tipleri": {
      "get": {
        "tags": [
          "Master Tanımları"
        ],
        "summary": "Fatura fiş tiplerini (FATGENFISTIP) sayfalı döner.",
        "description": "Alanlar ETA kolon adlarının küçük harfli halidir (FATGENFTKOD -> fatgenftkod) ve DEĞERLER\nHAMDIR: metinler dolgu boşluklarıyla döner, doldurulmamış tarihler 1900-01-01 gelir —\nistemci karşılaştırma yapmadan önce kendisi trim uygulamalıdır.\n\nBu tablolar KATALOG verisidir ve güncelleme damgası taşımazlar; \"değişenleri ver\" (delta)\ndesteklenmez. Kayıt sayıları küçüktür (ölçülen kurulumlarda 8-25 satır), tek sayfada\nçekilebilirler.",
        "operationId": "Master_FaturaFisTipleri",
        "parameters": [
          {
            "name": "masterDb",
            "in": "query",
            "description": "Okunacak master veritabanı. Kiracıda TEK master tanımlıysa boş bırakılabilir; birden\nfazla tanımlıysa (ör. hem ETA_MASTER hem ETA_MASTERV8) zorunludur.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "kodOnek",
            "in": "query",
            "description": "Fiş tipi kodunun (FATGENFTKOD) başlangıcı.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "skip",
            "in": "query",
            "description": "Atlanacak kayıt sayısı. Varsayılan: 0.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "take",
            "in": "query",
            "description": "Sayfa boyutu. Verilmezse veya 0 ise 100 kabul edilir, azami 500.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sayfalı fatura fiş tipi listesi.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SayfaliSonucFaturaFisTipiKayit"
                }
              }
            }
          },
          "400": {
            "description": "skip negatif ya da take aralık dışı (PARAMETRE_GECERSIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Token yok, süresi dolmuş veya geçersiz (gövdesiz olabilir).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "masterDb kiracının tanımları arasında değil (ETA_DB_YETKISIZ) ya da IP kısıtı (IP_YETKISIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Kiracıda master veritabanı tanımlı değil (MASTER_DB_TANIMSIZ); yönetim panelinden eklenmelidir.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen sunucu hatası (SUNUCU_HATASI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "502": {
            "description": "Master veritabanına erişilemedi (ETA_ERISIM_HATASI); istek tekrar denenebilir.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [ ]
          }
        ]
      }
    },
    "/api/v1/master/irsaliye-fis-tipleri": {
      "get": {
        "tags": [
          "Master Tanımları"
        ],
        "summary": "İrsaliye fiş tiplerini (IRSGENFISTIP) sayfalı döner.",
        "description": "Alan ve sayfalama kuralları fatura fiş tipleri ucuyla aynıdır.",
        "operationId": "Master_IrsaliyeFisTipleri",
        "parameters": [
          {
            "name": "masterDb",
            "in": "query",
            "description": "Okunacak master veritabanı. Tek master tanımlıysa boş bırakılabilir.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "kodOnek",
            "in": "query",
            "description": "Fiş tipi kodunun (IRSGENFTKOD) başlangıcı.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "skip",
            "in": "query",
            "description": "Atlanacak kayıt sayısı. Varsayılan: 0.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "take",
            "in": "query",
            "description": "Sayfa boyutu. Verilmezse veya 0 ise 100 kabul edilir, azami 500.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sayfalı irsaliye fiş tipi listesi.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SayfaliSonucIrsaliyeFisTipiKayit"
                }
              }
            }
          },
          "400": {
            "description": "skip negatif ya da take aralık dışı (PARAMETRE_GECERSIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Token yok, süresi dolmuş veya geçersiz (gövdesiz olabilir).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "masterDb yetki dışı (ETA_DB_YETKISIZ) ya da IP kısıtı (IP_YETKISIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Kiracıda master veritabanı tanımlı değil (MASTER_DB_TANIMSIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen sunucu hatası (SUNUCU_HATASI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "502": {
            "description": "Master veritabanına erişilemedi (ETA_ERISIM_HATASI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [ ]
          }
        ]
      }
    },
    "/api/v1/master/cari-fis-tipleri": {
      "get": {
        "tags": [
          "Master Tanımları"
        ],
        "summary": "Cari fiş tiplerini (CARGENFISTIP) sayfalı döner.",
        "description": "Alan ve sayfalama kuralları fatura fiş tipleri ucuyla aynıdır.",
        "operationId": "Master_CariFisTipleri",
        "parameters": [
          {
            "name": "masterDb",
            "in": "query",
            "description": "Okunacak master veritabanı. Tek master tanımlıysa boş bırakılabilir.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "kodOnek",
            "in": "query",
            "description": "Fiş tipi kodunun (CARGENFTKOD) başlangıcı.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "skip",
            "in": "query",
            "description": "Atlanacak kayıt sayısı. Varsayılan: 0.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "take",
            "in": "query",
            "description": "Sayfa boyutu. Verilmezse veya 0 ise 100 kabul edilir, azami 500.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sayfalı cari fiş tipi listesi.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SayfaliSonucCariFisTipiKayit"
                }
              }
            }
          },
          "400": {
            "description": "skip negatif ya da take aralık dışı (PARAMETRE_GECERSIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Token yok, süresi dolmuş veya geçersiz (gövdesiz olabilir).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "masterDb yetki dışı (ETA_DB_YETKISIZ) ya da IP kısıtı (IP_YETKISIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Kiracıda master veritabanı tanımlı değil (MASTER_DB_TANIMSIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen sunucu hatası (SUNUCU_HATASI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "502": {
            "description": "Master veritabanına erişilemedi (ETA_ERISIM_HATASI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [ ]
          }
        ]
      }
    },
    "/api/v1/master/stok-fis-tipleri": {
      "get": {
        "tags": [
          "Master Tanımları"
        ],
        "summary": "Stok fiş tiplerini (STKGENFISTIP) sayfalı döner.",
        "description": "Alan ve sayfalama kuralları fatura fiş tipleri ucuyla aynıdır.",
        "operationId": "Master_StokFisTipleri",
        "parameters": [
          {
            "name": "masterDb",
            "in": "query",
            "description": "Okunacak master veritabanı. Tek master tanımlıysa boş bırakılabilir.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "kodOnek",
            "in": "query",
            "description": "Fiş tipi kodunun (STKGENFTKOD) başlangıcı.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "skip",
            "in": "query",
            "description": "Atlanacak kayıt sayısı. Varsayılan: 0.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "take",
            "in": "query",
            "description": "Sayfa boyutu. Verilmezse veya 0 ise 100 kabul edilir, azami 500.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sayfalı stok fiş tipi listesi.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SayfaliSonucStokFisTipiKayit"
                }
              }
            }
          },
          "400": {
            "description": "skip negatif ya da take aralık dışı (PARAMETRE_GECERSIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Token yok, süresi dolmuş veya geçersiz (gövdesiz olabilir).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "masterDb yetki dışı (ETA_DB_YETKISIZ) ya da IP kısıtı (IP_YETKISIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Kiracıda master veritabanı tanımlı değil (MASTER_DB_TANIMSIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen sunucu hatası (SUNUCU_HATASI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "502": {
            "description": "Master veritabanına erişilemedi (ETA_ERISIM_HATASI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [ ]
          }
        ]
      }
    },
    "/api/v1/master/muhasebe-fis-tipleri": {
      "get": {
        "tags": [
          "Master Tanımları"
        ],
        "summary": "Muhasebe fiş tiplerini (MUHGENFISTIP) sayfalı döner.",
        "description": "Alan ve sayfalama kuralları fatura fiş tipleri ucuyla aynıdır.",
        "operationId": "Master_MuhasebeFisTipleri",
        "parameters": [
          {
            "name": "masterDb",
            "in": "query",
            "description": "Okunacak master veritabanı. Tek master tanımlıysa boş bırakılabilir.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "kodOnek",
            "in": "query",
            "description": "Fiş tipi kodunun (MUHGENFTKOD) başlangıcı.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "skip",
            "in": "query",
            "description": "Atlanacak kayıt sayısı. Varsayılan: 0.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "take",
            "in": "query",
            "description": "Sayfa boyutu. Verilmezse veya 0 ise 100 kabul edilir, azami 500.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sayfalı muhasebe fiş tipi listesi.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SayfaliSonucMuhasebeFisTipiKayit"
                }
              }
            }
          },
          "400": {
            "description": "skip negatif ya da take aralık dışı (PARAMETRE_GECERSIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Token yok, süresi dolmuş veya geçersiz (gövdesiz olabilir).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "masterDb yetki dışı (ETA_DB_YETKISIZ) ya da IP kısıtı (IP_YETKISIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Kiracıda master veritabanı tanımlı değil (MASTER_DB_TANIMSIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen sunucu hatası (SUNUCU_HATASI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "502": {
            "description": "Master veritabanına erişilemedi (ETA_ERISIM_HATASI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [ ]
          }
        ]
      }
    },
    "/api/v1/master/kdv-kisimlari": {
      "get": {
        "tags": [
          "Master Tanımları"
        ],
        "summary": "KDV kısımlarını (KDVKISIM) sayfalı döner.",
        "description": "Oran `kdvkisoran` alanındadır ve yüzde olarak gelir (20 = %20). Açıklama metnindeki\nyüzde (ör. \"TEMEL GIDA %8\") kurulumla birlikte eskimiş olabilir; güvenilecek değer\norandır.",
        "operationId": "Master_KdvKisimlari",
        "parameters": [
          {
            "name": "masterDb",
            "in": "query",
            "description": "Okunacak master veritabanı. Tek master tanımlıysa boş bırakılabilir.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "kodOnek",
            "in": "query",
            "description": "Özel kodun (KDVKISOZELKOD) başlangıcı. Bu alan birçok kurulumda boştur.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "skip",
            "in": "query",
            "description": "Atlanacak kayıt sayısı. Varsayılan: 0.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "take",
            "in": "query",
            "description": "Sayfa boyutu. Verilmezse veya 0 ise 100 kabul edilir, azami 500.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sayfalı KDV kısmı listesi.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SayfaliSonucKdvKisimKayit"
                }
              }
            }
          },
          "400": {
            "description": "skip negatif ya da take aralık dışı (PARAMETRE_GECERSIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Token yok, süresi dolmuş veya geçersiz (gövdesiz olabilir).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "masterDb yetki dışı (ETA_DB_YETKISIZ) ya da IP kısıtı (IP_YETKISIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Kiracıda master veritabanı tanımlı değil (MASTER_DB_TANIMSIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen sunucu hatası (SUNUCU_HATASI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "502": {
            "description": "Master veritabanına erişilemedi (ETA_ERISIM_HATASI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [ ]
          }
        ]
      }
    },
    "/api/v1/master/doviz-tanimlari": {
      "get": {
        "tags": [
          "Master Tanımları"
        ],
        "summary": "Döviz tanımlarını (DOVTAN) sayfalı döner.",
        "description": "Kurulumda tanımlı döviz cinsleri: kod (`dovtankod`, ör. \"USD\" / \"EURO\"), ad\n(`dovtanadi`) ve ISO 4217 eşleşme kodu (`dovtaneslkod`, ör. \"EURO\" → \"EUR\").\nKendi sisteminde ISO kod kullanan istemcinin eşleme yapacağı alan sonuncusudur.\n\n⛔ BU LİSTE `doviz-kurlari` UCUNUN `dovizKodu` PARAMETRESİ İÇİN GEÇERLİ\nDEĞERLER LİSTESİ DEĞİLDİR. İki tablo birbirini kapsamaz: ölçülen bir kurulumda\n(2026-08-28) DOVHAR'da kur satırı bulunan sekiz kod (AZN, AED, EUR, KRW, PKR, QAR,\nSTERLİN, XDR) DOVTAN'da hiç yoktu; buna karşılık DOVTAN'daki üç kod (ILS, JOD, SYP)\niçin DOVHAR'da tek satır yoktu. Kur çekecek istemci kod kümesini DOVHAR'ın kendisinden\nöğrenmelidir.\n\n`dovtancarpan` / `dovtanbolen` ölçülen kurulumların hepsinde `0` geldi;\nbölme işleminde doğrudan kullanılmamalıdır.\n\nAlan ve sayfalama kuralları diğer master tanım uçlarıyla aynıdır (sıralama\n`dovtansno` üzerinde ve artan).",
        "operationId": "Master_DovizTanimlari",
        "parameters": [
          {
            "name": "masterDb",
            "in": "query",
            "description": "Okunacak master veritabanı. Tek master tanımlıysa boş bırakılabilir.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "kodOnek",
            "in": "query",
            "description": "Döviz kodunun (DOVTANKOD) başlangıcı.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "skip",
            "in": "query",
            "description": "Atlanacak kayıt sayısı. Varsayılan: 0.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "take",
            "in": "query",
            "description": "Sayfa boyutu. Verilmezse veya 0 ise 100 kabul edilir, azami 500.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sayfalı döviz tanımı listesi.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SayfaliSonucDovizTanimiKayit"
                }
              }
            }
          },
          "400": {
            "description": "skip negatif ya da take aralık dışı (PARAMETRE_GECERSIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Token yok, süresi dolmuş veya geçersiz (gövdesiz olabilir).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "masterDb yetki dışı (ETA_DB_YETKISIZ) ya da IP kısıtı (IP_YETKISIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Kiracıda master veritabanı tanımlı değil (MASTER_DB_TANIMSIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen sunucu hatası (SUNUCU_HATASI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "502": {
            "description": "Master veritabanına erişilemedi (ETA_ERISIM_HATASI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [ ]
          }
        ]
      }
    },
    "/api/v1/master/doviz-kur-turleri": {
      "get": {
        "tags": [
          "Master Tanımları"
        ],
        "summary": "Kur türü tanımlarını (DOVTUR) sayfalı döner.",
        "description": "`doviz-kurlari` ucundaki `kurTuru` parametresinin sözlüğüdür: Merkez Bankası\nalış/satış, efektif alış/satış, serbest piyasa, değerleme gibi türlerin kod\n(`dovturkod`) ve ad (`dovturadi`) karşılıkları.\n\nÖlçülen kurulumda bu liste DOVHAR'daki türleri KAPSIYORDU (kur satırlarında bulunup\nburada bulunmayan tür çıkmadı), ama tersi geçerli değildir: tanımlı 13 türden 8'i o\nkurulumda hiç kullanılmıyordu. Yani liste \"kur bulunan türler\" değil \"tanımlı\ntürler\"dir; bir türle sorgu boş sonuç dönebilir.\n\nKodlar TÜRKÇE KARAKTER İÇEREBİLİR (ör. `DEĞERLEMEK`); `kurTuru` olarak\ngönderilirken sorgu dizesinde UTF-8 yüzde kodlaması gerekir.",
        "operationId": "Master_DovizKurTurleri",
        "parameters": [
          {
            "name": "masterDb",
            "in": "query",
            "description": "Okunacak master veritabanı. Tek master tanımlıysa boş bırakılabilir.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "kodOnek",
            "in": "query",
            "description": "Kur türü kodunun (DOVTURKOD) başlangıcı.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "skip",
            "in": "query",
            "description": "Atlanacak kayıt sayısı. Varsayılan: 0.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "take",
            "in": "query",
            "description": "Sayfa boyutu. Verilmezse veya 0 ise 100 kabul edilir, azami 500.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sayfalı kur türü listesi.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SayfaliSonucKurTuruKayit"
                }
              }
            }
          },
          "400": {
            "description": "skip negatif ya da take aralık dışı (PARAMETRE_GECERSIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Token yok, süresi dolmuş veya geçersiz (gövdesiz olabilir).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "masterDb yetki dışı (ETA_DB_YETKISIZ) ya da IP kısıtı (IP_YETKISIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Kiracıda master veritabanı tanımlı değil (MASTER_DB_TANIMSIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen sunucu hatası (SUNUCU_HATASI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "502": {
            "description": "Master veritabanına erişilemedi (ETA_ERISIM_HATASI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [ ]
          }
        ]
      }
    },
    "/api/v1/master/doviz-kurlari": {
      "get": {
        "tags": [
          "Master Tanımları"
        ],
        "summary": "Döviz kuru geçmişini (DOVHAR) sayfalı döner.",
        "description": "Diğer master uçlarından farklı olarak bu bir KATALOG DEĞİL GEÇMİŞTİR: ölçülen bir\nkurulumda 55.000'den fazla satır bulundu (satır sayısı tarih aralığından çok, kurulumda\ntanımlı döviz ve kur türü sayısından gelir). Tüm geçmişi çekmek meşru bir kullanımdır,\nbu yüzden tarih aralığında gün sınırı YOKTUR — ama sayfalama vardır.\n\nSıralama `dovhartar, dovharkod, dovhartur` üçlüsü üzerindedir ve ARTAN'dır. Üçlü\nbirlikte tekildir; tek başına tarih tekil değildir (aynı günde her döviz ve kur türü için\nayrı satır vardır). Artan sıralama, devam eden bir taramanın araya giren yeni kur\nsatırlarından etkilenmemesini sağlar: yeni satırlar listenin sonuna eklenir.\n\n`dovizKodu` ve `kurTuru` ÖN EK DEĞİL TAM EŞLEŞMEDİR; gerekçe için ilgili\nparametre açıklamalarına bakın. `kurTuru` için tanımlı değerler\n`doviz-kur-turleri` ucundan okunabilir; `dovizKodu` için ise\n`doviz-tanimlari` ucu YETMEZ — iki tablo birbirini kapsamaz (bkz. o ucun açıklaması).",
        "operationId": "Master_DovizKurlari",
        "parameters": [
          {
            "name": "masterDb",
            "in": "query",
            "description": "Okunacak master veritabanı. Tek master tanımlıysa boş bırakılabilir.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "dovizKodu",
            "in": "query",
            "description": "Döviz kodu (DOVHARKOD) TAM EŞLEŞME. Ön ek araması bilinçli olarak yoktur: aynı kurulumda\nhem \"EUR\" hem \"EURO\" kodu bulunabiliyor ve \"EUR\" ön eki ikisini birden getirirdi. Geçerli\ndeğerler ETA kurulumunun kendi tanımlarıdır (ISO 4217 olmak zorunda değil; \"STERLİN\" gibi\nTürkçe kodlar da görülür).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "kurTuru",
            "in": "query",
            "description": "Kur türü (DOVHARTUR) TAM EŞLEŞME, ör. MBNKALS / MBNKSAT / MBNKEALS / MBNKESAT.\nKümesi kuruluma göre değişir.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "baslangicTarihi",
            "in": "query",
            "description": "Bu tarih DAHİL sonrası (yyyy-MM-dd). Verilmezse alt sınır yoktur. Geçerli aralık 1753-01-01 ile 9999-12-30 arasıdır (SQL Server datetime sınırı).",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "bitisTarihi",
            "in": "query",
            "description": "Bu tarih DAHİL öncesi (yyyy-MM-dd). Verilmezse üst sınır yoktur. Geçerli aralık 1753-01-01 ile 9999-12-30 arasıdır.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "skip",
            "in": "query",
            "description": "Atlanacak kayıt sayısı. Varsayılan: 0.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "take",
            "in": "query",
            "description": "Sayfa boyutu. Verilmezse veya 0 ise 100 kabul edilir, azami 500.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sayfalı döviz kuru listesi.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SayfaliSonucDovizKuruKayit"
                }
              }
            }
          },
          "400": {
            "description": "skip negatif, take aralık dışı (PARAMETRE_GECERSIZ) ya da bitisTarihi baslangicTarihi'nden küçük (TARIH_ARALIGI_GECERSIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Token yok, süresi dolmuş veya geçersiz (gövdesiz olabilir).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "masterDb yetki dışı (ETA_DB_YETKISIZ) ya da IP kısıtı (IP_YETKISIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Kiracıda master veritabanı tanımlı değil (MASTER_DB_TANIMSIZ).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "500": {
            "description": "Beklenmeyen sunucu hatası (SUNUCU_HATASI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          },
          "502": {
            "description": "Master veritabanına erişilemedi (ETA_ERISIM_HATASI).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [ ]
          }
        ]
      }
    },
    "/api/v1/ping": {
      "get": {
        "tags": [
          "Servis"
        ],
        "summary": "Servisin ayakta olduğunu ve sürümünü bildirir. Kimlik doğrulama istemez.",
        "description": "İzleme / uptime kontrolü için kullanılabilir.",
        "operationId": "Ping_Get",
        "responses": {
          "200": {
            "description": "Servis ayakta.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PingYanit"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ApiProblemDetails": {
        "required": [
          "hataKodu",
          "izlemeNo",
          "status",
          "title",
          "type"
        ],
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "description": "Hata türünün adresi: `https://joisoft.com.tr/hatalar/{hataKodu}`."
          },
          "title": {
            "type": "string",
            "description": "Kullanıcıya gösterilebilir hata başlığı."
          },
          "status": {
            "type": "integer",
            "description": "HTTP durum kodu.",
            "format": "int32"
          },
          "hataKodu": {
            "type": "string",
            "description": "Makine tarafından okunacak iş hata kodu. Olası değerler JOI_ULUPINAR.API.Hatalar.ApiHataKodu\nsabitleridir (KIMLIK_GECERSIZ, ETA_DB_YETKISIZ, PARAMETRE_GECERSIZ, ...)."
          },
          "detay": {
            "type": "string",
            "description": "Varsa hatanın ayrıntısı (ör. hangi parametrenin neden geçersiz olduğu).",
            "nullable": true
          },
          "izlemeNo": {
            "type": "string",
            "description": "İstek izleme numarası. Destek başvurusunda bu numara bildirilmelidir."
          }
        },
        "additionalProperties": false,
        "description": "`/api` uçlarının hata gövdesi (RFC 7807 `application/problem+json`).\n\nBu tip hem JOI_ULUPINAR.API.Hatalar.HataYakalamaMiddleware tarafından ÜRETİLİR hem de OpenAPI\nbelgesinde hata şeması olarak GÖSTERİLİR: ikisi tek kaynaktan beslendiği için belge\nile gerçek gövde birbirinden sapamaz. Middleware daha önce anonim bir nesne\nserileştiriyordu; alan eklendiğinde belge sessizce eskiyecekti."
      },
      "CariFisTipiKayit": {
        "required": [
          "cargenftno"
        ],
        "type": "object",
        "properties": {
          "cargenftno": {
            "type": "integer",
            "description": "Fiş tipi numarası (`CARGENFTNO`). Sayfalama sıralaması bu alan üzerindedir.",
            "format": "int32"
          },
          "cargenftkod": {
            "type": "string",
            "description": "Kısa kod (`CARGENFTKOD`). `kodOnek` filtresi bu alana uygulanır.",
            "nullable": true
          },
          "cargenftaciklama": {
            "type": "string",
            "description": "Açıklama (`CARGENFTACIKLAMA`).",
            "nullable": true
          }
        },
        "additionalProperties": { },
        "description": "Cari fiş tipi (`CARGENFISTIP` satırı)."
      },
      "CariKayit": {
        "required": [
          "adresler",
          "carkod",
          "kimlikler"
        ],
        "type": "object",
        "properties": {
          "carkod": {
            "type": "string",
            "description": "Cari kodu (`CARKOD`). Sayfalama sıralaması bu alan üzerindedir."
          },
          "carunvan": {
            "type": "string",
            "description": "Cari unvanı (`CARUNVAN`).",
            "nullable": true
          },
          "carcalflag": {
            "type": "integer",
            "description": "Aktiflik (`CARCALFLAG`): 1 aktif, 0 pasif.",
            "format": "int32",
            "nullable": true
          },
          "adresler": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HamSatir"
            },
            "description": "`ADRESLER` tablosundaki adres satırları (`ADRMODUL=2`, `ADRKONU=1`),\n`ADRITEMNO` sırasında. Kayıt yoksa boş dizi."
          },
          "kimlikler": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HamSatir"
            },
            "description": "`KIMLIKLER` tablosundaki kimlik satırları (`KIMMODUL=2`, `KIMKONU=1`),\n`KIMITEMNO` sırasında. Kayıt yoksa boş dizi."
          }
        },
        "additionalProperties": { },
        "description": "Cari kartı (`CARKART` satırı) ve ona bağlı alt listeler. Burada yalnız istemcinin\nher ETA sürümünde bulacağı alanlar adlandırılmıştır; kartın kalan tüm kolonları da\naynı nesnede döner."
      },
      "DovizKuruKayit": {
        "required": [
          "dovharkod",
          "dovhartar",
          "dovhartur"
        ],
        "type": "object",
        "properties": {
          "dovhartar": {
            "type": "string",
            "description": "Kur tarihi (`DOVHARTAR`). ETA'da `datetime`'dır; saat bileşeni tipik olarak\n00:00'dır. Sayfalama sıralaması (`dovhartar, dovharkod, dovhartur`) bu alanla başlar.\n\nDeğer `yyyy-MM-ddTHH:mm:ss` biçiminde, SAAT DİLİMİ TAŞIMADAN döner\n(ör. `2026-05-03T00:00:00`) — ETA bu alanı dilimsiz bir yerel zaman olarak tutar.\n\n⛔ TİP BİLİNÇLİ OLARAK `string`, `DateTime` DEĞİL: `DateTime` yazılsaydı\nbelge alanı `format: date-time` ilan ederdi ve OpenAPI 3'te bu RFC 3339 demektir —\nyani saat dilimi ofseti ZORUNLUDUR. Belgeden Go (`time.Time`) ya da Java\n(`OffsetDateTime`) istemcisi üreten bir müşteri, alan `required` olduğu için\nHER başarılı yanıtta çözümleme hatası alırdı. Değere `Z` eklemek de çözüm değil:\nETA'nın tarihi bilinmeyen bir dilimdedir, `Z` yazmak veriyi UYDURUR.\n(Belge ve gövde 2026-08-27'de canlı ölçülerek doğrulandı.)"
          },
          "dovharkod": {
            "type": "string",
            "description": "Döviz kodu (`DOVHARKOD`). Değerler KURULUMA GÖRE değişir ve ETA'nın kendi\ntanımlarıdır — ISO 4217 olmak zorunda değildir: aynı kurulumda hem `EUR` hem\n`EURO`, ayrıca `STERLİN` gibi Türkçe kodlar ölçüldü. Bu yüzden filtre ön ek\ndeğil TAM EŞLEŞMEDİR."
          },
          "dovhartur": {
            "type": "string",
            "description": "Kur türü (`DOVHARTUR`), ör. `MBNKALS` / `MBNKSAT` (Merkez Bankası alış /\nsatış), `MBNKEALS` / `MBNKESAT` (efektif alış / satış), `DEĞERLEMEK`.\nKümesi kuruluma göre değişir."
          },
          "dovhartut": {
            "type": "number",
            "description": "Kur değeri (`DOVHARTUT`). ETA'da `numeric(28,9)`.",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": { },
        "description": "Döviz kuru satırı (`DOVHAR`): bir tarih + döviz + kur türü için tek bir kur değeri."
      },
      "DovizTanimiKayit": {
        "required": [
          "dovtansno"
        ],
        "type": "object",
        "properties": {
          "dovtansno": {
            "type": "integer",
            "description": "Sıra numarası (`DOVTANSNO`). Sayfalama sıralaması bu alan üzerindedir.",
            "format": "int32"
          },
          "dovtankod": {
            "type": "string",
            "description": "Döviz kodu (`DOVTANKOD`), ör. `USD`, `EURO`. ETA'nın kendi kodudur,\nISO 4217 olmak zorunda değildir. `kodOnek` filtresi bu alana uygulanır.",
            "nullable": true
          },
          "dovtanadi": {
            "type": "string",
            "description": "Döviz adı (`DOVTANADI`), ör. \"ABD DOLARI\".",
            "nullable": true
          },
          "dovtancarpan": {
            "type": "number",
            "description": "Çarpan (`DOVTANCARPAN`). ETA'da `numeric(28,9)`. Ölçülen kurulumların\nhepsinde `0` geldi — kullanılmadan önce dolu olup olmadığı denetlenmelidir.",
            "format": "double",
            "nullable": true
          },
          "dovtanbolen": {
            "type": "number",
            "description": "Bölen (`DOVTANBOLEN`). ETA'da `numeric(28,9)`. `DOVTANCARPAN` ile aynı\nuyarı geçerlidir; `0` gelebileceği için BÖLME İŞLEMİNDE DOĞRUDAN KULLANILMAMALIDIR.",
            "format": "double",
            "nullable": true
          },
          "dovtaneslkod": {
            "type": "string",
            "description": "Eşleşme kodu (`DOVTANESLKOD`): ETA kodunun ISO 4217 karşılığı olarak doldurulur\n(ör. `EURO` → `EUR`). Kendi sisteminde ISO kod kullanan istemcinin eşleme\nyapacağı alan budur; doldurulduğu garanti edilmez.",
            "nullable": true
          }
        },
        "additionalProperties": { },
        "description": "Döviz tanımı (`DOVTAN` satırı): kurulumda tanımlı döviz cinsi.\n\n⛔ Bu liste `/api/v1/master/doviz-kurlari` ucunun `dovizKodu` filtresi için\nGEÇERLİ DEĞERLER LİSTESİ DEĞİLDİR — iki tablo birbirini kapsamaz, gerekçe ucun\naçıklamasındadır."
      },
      "FaturaFisTipiKayit": {
        "required": [
          "fatgenftno"
        ],
        "type": "object",
        "properties": {
          "fatgenftno": {
            "type": "integer",
            "description": "Fiş tipi numarası (`FATGENFTNO`). Sayfalama sıralaması bu alan üzerindedir.",
            "format": "int32"
          },
          "fatgenftkod": {
            "type": "string",
            "description": "Kısa kod (`FATGENFTKOD`), ör. \"SATIŞ\". `kodOnek` filtresi bu alana uygulanır.",
            "nullable": true
          },
          "fatgenftaciklama": {
            "type": "string",
            "description": "Açıklama (`FATGENFTACIKLAMA`), ör. \"YURT İÇİ SATIŞ FATURASI\".",
            "nullable": true
          },
          "fatgenfttip": {
            "type": "integer",
            "description": "Fiş tipi ayrımı (`FATGENFTTIP`): ETA'da alış/satış yönünü belirler.",
            "format": "int32",
            "nullable": true
          },
          "fatgenftiade": {
            "type": "integer",
            "description": "İade fişi mi (`FATGENFTIADE`): 1 iade, 0 normal.",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": { },
        "description": "Fatura fiş tipi (`FATGENFISTIP` satırı): ALIM, SATIŞ, İADE, ÜRETİME ÇIKIŞ gibi\nfatura türlerinin kurulum genelindeki tanımı."
      },
      "FaturaSatiri": {
        "type": "object",
        "properties": {
          "siraNo": {
            "type": "integer",
            "format": "int32"
          },
          "malKodu": {
            "type": "string",
            "nullable": true
          },
          "aciklama": {
            "type": "string",
            "nullable": true
          },
          "gtip": {
            "type": "string",
            "nullable": true
          },
          "miktar": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "birimKodu": {
            "type": "string",
            "nullable": true
          },
          "birimAdi": {
            "type": "string",
            "nullable": true
          },
          "birimFiyat": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "iskontoOrani": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "iskontoTutari": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "satirTutari": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "kdvOrani": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "kdvTutari": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "digerVergiler": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SatirVergi"
            }
          },
          "notlar": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "additionalProperties": false
      },
      "FirmaYanit": {
        "type": "object",
        "properties": {
          "etaDb": {
            "type": "string",
            "description": "Kart uçlarına `etaDb` parametresi olarak verilecek veritabanı adı."
          },
          "gorunenAd": {
            "type": "string",
            "description": "Panelde tanımlı, insan tarafından okunabilir firma adı."
          }
        },
        "additionalProperties": false
      },
      "GelenFaturaDetay": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string"
          },
          "belgeNo": {
            "type": "string"
          },
          "belgeTarihi": {
            "type": "string",
            "format": "date",
            "nullable": true
          },
          "belgeSaati": {
            "type": "string",
            "description": "Saat, saat dilimi taşımaz (HH:mm:ss).",
            "nullable": true,
            "example": "14:30:00"
          },
          "senaryo": {
            "type": "string",
            "nullable": true
          },
          "faturaTipi": {
            "type": "string",
            "nullable": true
          },
          "durum": {
            "type": "string",
            "nullable": true
          },
          "gonderen": {
            "$ref": "#/components/schemas/Taraf"
          },
          "alici": {
            "$ref": "#/components/schemas/Taraf"
          },
          "paraBirimi": {
            "type": "string",
            "nullable": true
          },
          "dovizKuru": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "vergiHaricTutar": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "satirIskontoToplam": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "vergiToplam": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "odenecekTutar": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "notlar": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "referanslar": {
            "$ref": "#/components/schemas/Referanslar"
          },
          "satirlar": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FaturaSatiri"
            }
          },
          "vergiToplamlari": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VergiToplami"
            }
          }
        },
        "additionalProperties": false,
        "description": "Detay ucunda dönen tam çözümlenmiş fatura."
      },
      "GelenFaturaOzet": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string"
          },
          "belgeNo": {
            "type": "string"
          },
          "belgeTarihi": {
            "type": "string",
            "format": "date",
            "nullable": true
          },
          "senaryo": {
            "type": "string",
            "nullable": true
          },
          "faturaTipi": {
            "type": "string",
            "nullable": true
          },
          "durum": {
            "type": "string",
            "nullable": true
          },
          "gonderenVkn": {
            "type": "string",
            "nullable": true
          },
          "gonderenUnvan": {
            "type": "string",
            "nullable": true
          },
          "paraBirimi": {
            "type": "string",
            "nullable": true
          },
          "odenecekTutar": {
            "type": "number",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Liste ucunda dönen hafif fatura başlığı (UBL çekilmeden entegratör başlığından üretilir)."
      },
      "GelenIrsaliyeDetay": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string"
          },
          "belgeNo": {
            "type": "string"
          },
          "duzenlemeTarihi": {
            "type": "string",
            "format": "date",
            "nullable": true
          },
          "duzenlemeSaati": {
            "type": "string",
            "description": "Saat, saat dilimi taşımaz (HH:mm:ss).",
            "nullable": true,
            "example": "14:30:00"
          },
          "fiiliSevkTarihi": {
            "type": "string",
            "format": "date",
            "nullable": true
          },
          "fiiliSevkSaati": {
            "type": "string",
            "description": "Saat, saat dilimi taşımaz (HH:mm:ss).",
            "nullable": true,
            "example": "14:30:00"
          },
          "senaryo": {
            "type": "string",
            "nullable": true
          },
          "irsaliyeTipi": {
            "type": "string",
            "nullable": true
          },
          "gonderen": {
            "$ref": "#/components/schemas/Taraf"
          },
          "alici": {
            "$ref": "#/components/schemas/Taraf"
          },
          "teslimatAdresi": {
            "$ref": "#/components/schemas/Taraf"
          },
          "tasiyici": {
            "$ref": "#/components/schemas/Tasiyici"
          },
          "notlar": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "siparisNo": {
            "type": "string",
            "nullable": true
          },
          "satirlar": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/IrsaliyeSatiri"
            }
          }
        },
        "additionalProperties": false
      },
      "GelenIrsaliyeOzet": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string"
          },
          "belgeNo": {
            "type": "string"
          },
          "duzenlemeTarihi": {
            "type": "string",
            "format": "date",
            "nullable": true
          },
          "durum": {
            "type": "string",
            "nullable": true
          },
          "gonderenVkn": {
            "type": "string",
            "nullable": true
          },
          "gonderenUnvan": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "HamSatir": {
        "type": "object",
        "additionalProperties": { },
        "description": "ETA'nın bir tablo satırı: kolon adlarının küçük harfli hali → ham değer eşlemesi\n(ör. `ADRADRES1` → `adradres1`). Değerler HAMDIR: metinler dolgu boşlukları\niçerir, doldurulmamış tarihler `1900-01-01` döner."
      },
      "HizmetKayit": {
        "required": [
          "hizkod"
        ],
        "type": "object",
        "properties": {
          "hizkod": {
            "type": "string",
            "description": "Hizmet kodu (`HIZKOD`). Sayfalama sıralaması bu alan üzerindedir."
          }
        },
        "additionalProperties": { },
        "description": "Hizmet kartı (`HIZMET` satırı). Cari ve stok kartlarından farklı olarak iç içe alt\nlistesi yoktur: hizmet kartının çoklu bir yan tablosu bulunmaz."
      },
      "IrsaliyeFisTipiKayit": {
        "required": [
          "irsgenftno"
        ],
        "type": "object",
        "properties": {
          "irsgenftno": {
            "type": "integer",
            "description": "Fiş tipi numarası (`IRSGENFTNO`). Sayfalama sıralaması bu alan üzerindedir.",
            "format": "int32"
          },
          "irsgenftkod": {
            "type": "string",
            "description": "Kısa kod (`IRSGENFTKOD`). `kodOnek` filtresi bu alana uygulanır.",
            "nullable": true
          },
          "irsgenftaciklama": {
            "type": "string",
            "description": "Açıklama (`IRSGENFTACIKLAMA`).",
            "nullable": true
          },
          "irsgenfttip": {
            "type": "integer",
            "description": "Fiş tipi ayrımı (`IRSGENFTTIP`).",
            "format": "int32",
            "nullable": true
          },
          "irsgenftiade": {
            "type": "integer",
            "description": "İade fişi mi (`IRSGENFTIADE`): 1 iade, 0 normal.",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": { },
        "description": "İrsaliye fiş tipi (`IRSGENFISTIP` satırı)."
      },
      "IrsaliyeSatiri": {
        "type": "object",
        "properties": {
          "siraNo": {
            "type": "integer",
            "format": "int32"
          },
          "malKodu": {
            "type": "string",
            "nullable": true
          },
          "aciklama": {
            "type": "string",
            "nullable": true
          },
          "miktar": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "birimKodu": {
            "type": "string",
            "nullable": true
          },
          "birimAdi": {
            "type": "string",
            "nullable": true
          },
          "siparisNo": {
            "type": "string",
            "nullable": true
          },
          "notlar": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "additionalProperties": false
      },
      "KdvKisimKayit": {
        "required": [
          "kdvkisno"
        ],
        "type": "object",
        "properties": {
          "kdvkisno": {
            "type": "integer",
            "description": "Kısım numarası (`KDVKISNO`). Sayfalama sıralaması bu alan üzerindedir.",
            "format": "int32"
          },
          "kdvkisaciklama": {
            "type": "string",
            "description": "Açıklama (`KDVKISACIKLAMA`), ör. \"TEMEL GIDA %8\".",
            "nullable": true
          },
          "kdvkisozelkod": {
            "type": "string",
            "description": "Özel kod (`KDVKISOZELKOD`). `kodOnek` filtresi bu alana uygulanır; birçok\nkurulumda BOŞTUR.",
            "nullable": true
          },
          "kdvkisoran": {
            "type": "number",
            "description": "KDV oranı (`KDVKISORAN`), yüzde olarak: 20 = %20. ETA'da `numeric(28,9)`\nolduğu için ondalıklı döner (ör. `20.000000000`) — AÇIKLAMA metninde yazan oran\n(ör. \"TEMEL GIDA %8\") kurulumla birlikte eskimiş olabilir, GÜVENİLECEK DEĞER BU ALANDIR.",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": { },
        "description": "KDV kısmı (`KDVKISIM` satırı): kurulumdaki KDV oran tanımları."
      },
      "KurTuruKayit": {
        "required": [
          "dovtursno"
        ],
        "type": "object",
        "properties": {
          "dovtursno": {
            "type": "integer",
            "description": "Sıra numarası (`DOVTURSNO`). Sayfalama sıralaması bu alan üzerindedir.",
            "format": "int32"
          },
          "dovturkod": {
            "type": "string",
            "description": "Kur türü kodu (`DOVTURKOD`), ör. `MBNKESAT`. Döviz kuru ucunda\n`kurTuru` olarak bu değer gönderilir. `kodOnek` filtresi bu alana uygulanır.\n\nKod TÜRKÇE KARAKTER İÇEREBİLİR (ölçülen kurulumda `DEĞERLEMEK`, `DEĞERLEME2`);\nsorgu dizesinde yüzde kodlaması (UTF-8) gerekir.",
            "nullable": true
          },
          "dovturadi": {
            "type": "string",
            "description": "Kur türü adı (`DOVTURADI`), ör. \"MERKEZ BANKASI EFEKTİF KUR SATIŞ FİYATI\".",
            "nullable": true
          },
          "dovtureslkod": {
            "type": "string",
            "description": "Eşleşme kodu (`DOVTURESLKOD`): ETA'nın iç kur türü numarası (ölçülen kurulumda\nMerkez Bankası türleri için `1`–`4`, diğerlerinde boş).",
            "nullable": true
          }
        },
        "additionalProperties": { },
        "description": "Kur türü tanımı (`DOVTUR` satırı): döviz kurunun hangi kaynağa/işleme ait olduğunu\nbelirten tür. `/api/v1/master/doviz-kurlari` ucundaki `kurTuru` parametresinin\nsözlüğüdür."
      },
      "MuhasebeFisTipiKayit": {
        "required": [
          "muhgenftno"
        ],
        "type": "object",
        "properties": {
          "muhgenftno": {
            "type": "integer",
            "description": "Fiş tipi numarası (`MUHGENFTNO`). Sayfalama sıralaması bu alan üzerindedir.",
            "format": "int32"
          },
          "muhgenftkod": {
            "type": "string",
            "description": "Kısa kod (`MUHGENFTKOD`). `kodOnek` filtresi bu alana uygulanır.",
            "nullable": true
          },
          "muhgenftaciklama": {
            "type": "string",
            "description": "Açıklama (`MUHGENFTACIKLAMA`).",
            "nullable": true
          },
          "muhgenfttip": {
            "type": "integer",
            "description": "Fiş tipi ayrımı (`MUHGENFTTIP`).",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": { },
        "description": "Muhasebe fiş tipi (`MUHGENFISTIP` satırı)."
      },
      "PingYanit": {
        "type": "object",
        "properties": {
          "uygulama": {
            "type": "string",
            "description": "Uygulama adı."
          },
          "surum": {
            "type": "string",
            "description": "Derleme sürümü."
          }
        },
        "additionalProperties": false
      },
      "Referanslar": {
        "type": "object",
        "properties": {
          "siparisNo": {
            "type": "string",
            "nullable": true
          },
          "irsaliyeNo": {
            "type": "string",
            "nullable": true
          },
          "irsaliyeTarihi": {
            "type": "string",
            "format": "date",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "RfAktarimDurumu": {
        "type": "object",
        "properties": {
          "aktarildi": {
            "type": "boolean",
            "description": "ETA belgesi üretilmiş mi. Bayrak değil GERÇEK KANITA bakılarak hesaplanır: belge türüne\nkarşılık gelen referans numarası (faturada FATFISREFNO, irsaliyede IRSFISREFNO) sıfırdan\nbüyük mü. Gerekçe ölçümdür — ENTEGRASYONDONE bayrağını irsaliye yordamı kendisi set etmez\nve banka yolunda hiç set edilmez, yani bayrak tek başına güvenilir değildir."
          },
          "entegrasyonDone": {
            "type": "boolean",
            "description": "RF_FISMASTER.ENTEGRASYONDONE bayrağının ham değeri."
          },
          "fatFisRefNo": {
            "type": "integer",
            "description": "Üretilen fatura fişinin numarası (FATFIS.FATFISREFNO); yoksa 0.",
            "format": "int32"
          },
          "irsFisRefNo": {
            "type": "integer",
            "description": "Üretilen irsaliye fişinin numarası (IRSFIS.IRSFISREFNO); yoksa 0.",
            "format": "int32"
          },
          "carFisRefNo": {
            "type": "integer",
            "description": "Üretilen cari fişinin numarası; yoksa 0.",
            "format": "int32"
          },
          "stkFisRefNo": {
            "type": "integer",
            "description": "Üretilen stok fişinin numarası; yoksa 0.",
            "format": "int32"
          },
          "muhFisRefNo": {
            "type": "integer",
            "description": "Üretilen muhasebe fişinin numarası; yoksa 0.",
            "format": "int32"
          },
          "etaEvrakNo": {
            "type": "string",
            "description": "RF_FISMASTER.FISEVRAKNO1'in son hali. Faturada aktarım sırasında ETA'nın kendi evrak\nsayacından üretilen numara buraya yazılır; irsaliyede gönderilen değer korunur."
          }
        },
        "additionalProperties": false,
        "description": "Fişin ETA'ya aktarılma durumu.\n\nBu API fişi yalnız ARA KATMANA yazar; gerçek ETA belgesini üreten saklı yordamı\n(SP_RFCREATEINVOICERECEIPT / SP_RFCREATEDISPATCHORDER) çağırmaz. Aktarım gerçekleştikten\nsonra bu alanlar dolar ve `GET /api/v1/rf-fisleri/{masterSatirId}` ile okunabilir."
      },
      "RfDovizBilgisi": {
        "type": "object",
        "properties": {
          "kod": {
            "type": "string",
            "description": "Döviz kodu (ETA MASTER'daki DOVTANKOD; ör. USD, EURO). Boşsa belge TL sayılır.",
            "nullable": true
          },
          "kurTuru": {
            "type": "string",
            "description": "Kur türü (ETA MASTER'daki DOVTURKOD; ör. MBNKSAT).",
            "nullable": true
          },
          "kur": {
            "type": "number",
            "description": "Kur değeri.",
            "format": "double"
          },
          "kurTarihi": {
            "type": "string",
            "description": "Kurun ait olduğu tarih. Verilmezse belge tarihi kullanılır.",
            "format": "date",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Fişin döviz bilgisi. Kur çevrimi YAPILMAZ; değerler ETA'ya olduğu gibi taşınır."
      },
      "RfFisDurumYanit": {
        "type": "object",
        "properties": {
          "masterSatirId": {
            "type": "integer",
            "description": "RF_FISMASTER.MASTERSATIRID.",
            "format": "int32"
          },
          "modulId": {
            "type": "integer",
            "description": "ETA modül numarası. 3 ve 6 dışında bir değer, fişin bu API dışında yazıldığını gösterir.",
            "format": "int32"
          },
          "belgeTuru": {
            "type": "string",
            "description": "Modül numarasının karşılığı; tanınmayan modülde boş döner."
          },
          "fisTipi": {
            "type": "integer",
            "description": "RF_FISMASTER.FISTIP.",
            "format": "int32"
          },
          "disReferans": {
            "type": "string",
            "description": "FISEVRAKNO2."
          },
          "belgeNo": {
            "type": "string",
            "description": "FISEVRAKNO1."
          },
          "tarih": {
            "type": "string",
            "description": "Belge tarihi, `yyyy-MM-dd` biçiminde.\n\n⛔ ALAN `DateTime` DEĞİL `string`'dir. `DateTime` yazılsaydı belge bu alanı\n`format: date-time` ilan ederdi; OpenAPI 3'te bu RFC 3339'dur ve SAAT DİLİMİ OFSETİ\nZORUNLUDUR. ETA'nın tarihi ise dilimsizdir ve `\"2026-04-25T00:00:00\"` olarak yazılırdı —\nbiçim doğrulaması açık bir Go/Java istemcisi HER başarılı yanıtta çözümleme hatası alırdı.\nSonuna `Z` eklemek de yanlış olurdu: ETA tarihi bilinmeyen dilimdedir, `Z` veriyi\nUYDURUR. Aynı karar projede daha önce `DovizKuruKayit.Dovhartar` için de verildi."
          },
          "cariKodu": {
            "type": "string",
            "description": "FISCARKOD."
          },
          "genelToplam": {
            "type": "number",
            "description": "FISGENTOPLAM.",
            "format": "double"
          },
          "kaynakEtiketi": {
            "type": "string",
            "description": "FISHAZKOD. Bu API'nin yazdığı fişlerde daima ULUPINAR'dır."
          },
          "aktarimDurumu": {
            "$ref": "#/components/schemas/RfAktarimDurumu"
          }
        },
        "additionalProperties": false,
        "description": "Durum sorgusunun yanıtı."
      },
      "RfFisIstek": {
        "required": [
          "belgeTuru",
          "cariKodu",
          "disReferans",
          "fisTipi",
          "girisCikis",
          "satirlar",
          "tarih"
        ],
        "type": "object",
        "properties": {
          "belgeTuru": {
            "type": "string",
            "description": "Belge türü: `fatura` veya `irsaliye`. Zorunludur.",
            "nullable": true
          },
          "disReferans": {
            "type": "string",
            "description": "Çağıran sistemdeki belge kimliği. ZORUNLUDUR ve MÜKERRER YAZIMI ENGELLEYEN ANAHTARDIR:\nRF_FISMASTER.FISEVRAKNO2 kolonuna yazılır ve üzerindeki filtreli benzersiz indeks\naynı değerin ikinci kez yazılmasını reddeder (409 FIS_ZATEN_KAYITLI).\n\nDeğer ETA'ya taşınır ve saklı yordamlar tarafından EZİLMEZ; üretilen ETA belgesinde\nFATFISEVRAKNO2 / IRSFISEVRAKNO2 olarak görünür, yani iki sistem arasında mutabakat\nalanı olarak kullanılabilir.",
            "nullable": true
          },
          "belgeNo": {
            "type": "string",
            "description": "Belgenin görünen numarası (RF_FISMASTER.FISEVRAKNO1).\n\n⛔ İKİ BELGE TÜRÜ ARASINDA ASİMETRİKTİR:\n• İRSALİYEDE ZORUNLUDUR — fişi ETA'ya çeviren SP_RFCREATEDISPATCHORDER irsaliye\nnumarasını KENDİSİ ÜRETMEZ, buradaki değeri kullanır (üretme satırı yordamda\nyorum satırıdır).\n• FATURADA İSTEĞE BAĞLIDIR ve gönderilse bile SP_RFCREATEINVOICERECEIPT bu alanın\nÜZERİNE ETA'nın kendi evrak sayacından ürettiği numarayı yazar. Kendi numaranızı\nkorumak için JOI_ULUPINAR.API.Fis.RfFisIstek.DisReferans kullanın.",
            "nullable": true
          },
          "tarih": {
            "type": "string",
            "description": "Belge tarihi (yyyy-MM-dd). Zorunludur. Satır ve toplam tarihlerine de aynen yazılır.",
            "format": "date",
            "nullable": true
          },
          "fisTipi": {
            "type": "integer",
            "description": "ETA fiş tipi numarası. Faturada FATFISTIP.FATFTNO, irsaliyede IRSFISTIP.IRSFTNO\ndeğeridir; kurulumdan kuruluma değişir. Ölçülen yaygın değerler — fatura: 1 alım,\n3 yurt içi satış, 2 alım iade, 4 satış iade; irsaliye: 1 alım, 3 yurt içi satış.\nZorunludur ve 0'dan büyük olmalıdır.",
            "format": "int32"
          },
          "girisCikis": {
            "type": "integer",
            "description": "Yön: 1 = giriş (alım), 2 = çıkış (satış). Zorunludur.",
            "format": "int32"
          },
          "kaynak": {
            "type": "integer",
            "description": "RF_FISMASTER.FISKAYNAK. Verilmezse ölçülen kurala göre türetilir: fatura + giriş\niçin 3, bunun dışındaki tüm fatura ve irsaliyeler için 6. Kurulumunuz farklı bir\nkaynak numarası kullanıyorsa burada açıkça verin.",
            "format": "int32",
            "nullable": true
          },
          "cariKodu": {
            "type": "string",
            "description": "Cari kart kodu (CARKART.CARKOD). Zorunludur ve ETA'da TANIMLI OLMALIDIR.",
            "nullable": true
          },
          "cariUnvan": {
            "type": "string",
            "description": "Cari unvanı. Verilmezse ETA'daki karttan okunur.",
            "nullable": true
          },
          "vergiNo": {
            "type": "string",
            "description": "Vergi kimlik numarası (RF_FISMASTER.FISVERHESNO).\n\n⛔ Fişi faturaya çeviren saklı yordam bu alanı yalnız UZUNLUĞU 10 İSE aktarır, aksi\nhalde SESSİZCE BOŞALTIR. Şahıs firmasının 11 haneli TCKN'si yalnız irsaliye yolunda\ntaşınabilir. (FISTCKIMLIKNO kolonu kullanılamaz: yordam onu da 10 hane şartına bağlar.)",
            "nullable": true
          },
          "vergiDairesi": {
            "type": "string",
            "description": "Vergi dairesi.",
            "nullable": true
          },
          "adres1": {
            "type": "string",
            "description": "Adres satırı 1. ETA'da her satır ayrı kolondur; uzun adres üçe bölünmelidir.",
            "nullable": true
          },
          "adres2": {
            "type": "string",
            "description": "Adres satırı 2.",
            "nullable": true
          },
          "adres3": {
            "type": "string",
            "description": "Adres satırı 3.",
            "nullable": true
          },
          "il": {
            "type": "string",
            "description": "İl.",
            "nullable": true
          },
          "ilce": {
            "type": "string",
            "description": "İlçe.",
            "nullable": true
          },
          "ulke": {
            "type": "string",
            "description": "Ülke.",
            "nullable": true
          },
          "postaKodu": {
            "type": "string",
            "description": "Posta kodu.",
            "nullable": true
          },
          "plasiyerKodu": {
            "type": "string",
            "description": "Plasiyer / satış temsilcisi kodu (RF_FISMASTER.FISSATKOD).",
            "nullable": true
          },
          "vadeTarihi": {
            "type": "string",
            "description": "Vade tarihi. Verilmezse belge tarihi kullanılır.",
            "format": "date",
            "nullable": true
          },
          "kdvDahil": {
            "type": "boolean",
            "description": "true ise satır fiyatları KDV DAHİL kabul edilir ve matrah geriye hesaplanır;\nfalse ise fiyatlar KDV hariçtir. RF_FISMASTER.FISKDVDAHILFLAG olarak taşınır."
          },
          "iade": {
            "type": "boolean",
            "description": "İade belgesi mi (RF_FISMASTER.FISIADEFLAG). İade için ayrı bir fiş tipi de seçilmelidir."
          },
          "doviz": {
            "$ref": "#/components/schemas/RfDovizBilgisi"
          },
          "aciklama1": {
            "type": "string",
            "description": "Fiş açıklaması 1.",
            "nullable": true
          },
          "aciklama2": {
            "type": "string",
            "description": "Fiş açıklaması 2.",
            "nullable": true
          },
          "aciklama3": {
            "type": "string",
            "description": "Fiş açıklaması 3.",
            "nullable": true
          },
          "olusturanKullanici": {
            "type": "string",
            "description": "Fişi oluşturan kullanıcı (RF_FISMASTER.OLUSTURANKULLANICI). Verilmezse token'daki\nkiracı kodu yazılır. İrsaliye yolunda bu değer ETA'da satış temsilcisi aramasında\nda kullanılır.",
            "nullable": true
          },
          "satirlar": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RfFisSatirIstek"
            },
            "description": "Fiş satırları. EN AZ BİR SATIR ZORUNLUDUR.",
            "nullable": true
          },
          "hamAlanlar": {
            "type": "object",
            "additionalProperties": {
              "nullable": true
            },
            "description": "RF_FISMASTER kolonlarını doğrudan yazmak için ad/değer sözlüğü. Anahtarlar ETA kolon\nadlarıdır (büyük/küçük harf duyarsız). Türetilmiş değerlerin ÜZERİNE yazılır.\n\nTanınmayan bir kolon adı 400 döner (sessizce yok sayılmaz). Kimlik, mükerrer koruması\nve aktarım durumu kolonları yazılamaz — listesi JOI_ULUPINAR.API.Fis.RfKolonAdi.KorunanKolonlar.",
            "nullable": true
          },
          "ekToplamSatirlari": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RfToplamSatirIstek"
            },
            "description": "RF_FISTOPLAM'a EK olarak yazılacak satırlar. KDV kırılımı ve kalem iskonto satırlarını\nAPI zaten üretir; burası serbest başlıklar (ör. TKONU=0 \"TOPLAM KOLİ ADEDİ\") ve\nkurulum özel satırları içindir.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "RF ara katmanına yazılacak fişin gövdesi.\n\nSözleşme HİBRİTTİR: sık kullanılan alanlar adlandırılmıştır ve API bunlardan ETA'nın\nyüzlerce kolonunu türetir; türetmenin yetmediği her yerde JOI_ULUPINAR.API.Fis.RfFisIstek.HamAlanlar ile\nistenen ETA kolonu doğrudan yazılabilir. Böylece basit bir fatura için ETA şemasını\nbilmek gerekmez, özel bir alan için de API değişikliği beklemek gerekmez.\n\n⛔ Alanların hiçbirinde [Required] YOKTUR. Zorunluluk çalışma zamanında\nJOI_ULUPINAR.API.Fis.RfFisDogrulayici içinde denetlenir ve belgeye\n`Swagger/RfFisIstekSemaFiltresi` ile yazılır. Gerekçe projede iki yerde yazılıdır\n(bkz. Swagger/ZorunluParametreFiltresi ve Sorgu/SorguDogrulayici): [Required] MVC model\ndoğrulamasını devreye sokar ve API'nin ProblemDetails hata sözleşmesi yerine\nValidationProblemDetails üreten başka bir 400 gövdesi döner."
      },
      "RfFisSatirIstek": {
        "required": [
          "miktar",
          "stokKodu"
        ],
        "type": "object",
        "properties": {
          "siraNo": {
            "type": "integer",
            "description": "Satır sırası (RF_FISHAREKET.HARSIRANO). Verilmezse listedeki sıraya göre 1'den\nbaşlayarak atanır. Verilirse fiş içinde TEKİL olmalıdır — ETA'nın satır yazan\nsorgularının tamamı bu kolona göre sıralanır.",
            "format": "int32",
            "nullable": true
          },
          "stokKodu": {
            "type": "string",
            "description": "Stok kartı kodu (STKKART.STKKOD). Zorunludur ve ETA'da TANIMLI OLMALIDIR.",
            "nullable": true
          },
          "stokAdi": {
            "type": "string",
            "description": "Stok adı. Verilmezse ETA'daki karttan okunur.",
            "nullable": true
          },
          "birim": {
            "type": "string",
            "description": "Birim (ör. ADET, KG). ⛔ ETA harmanlaması büyük/küçük harf duyarlı olabilir.",
            "nullable": true
          },
          "depoKodu": {
            "type": "string",
            "description": "Depo kodu. RF_FISHAREKET'te iki kolona birden yazılır (biri fatura, diğeri irsaliye yolunda okunur).",
            "nullable": true
          },
          "miktar": {
            "type": "number",
            "description": "Miktar. Zorunludur ve 0 olamaz.",
            "format": "double"
          },
          "fiyat": {
            "type": "number",
            "description": "Birim fiyat. JOI_ULUPINAR.API.Fis.RfFisIstek.KdvDahil true ise KDV DAHİL, değilse KDV hariç\nkabul edilir.",
            "format": "double"
          },
          "kdvOrani": {
            "type": "number",
            "description": "KDV oranı (yüzde; ör. 20). 0 ile 100 arasında olmalıdır.",
            "format": "double"
          },
          "iskontoYuzdeleri": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "double"
            },
            "description": "Kalem iskonto yüzdeleri; en fazla beş adet ve ZİNCİRLEME uygulanır (ikinci yüzde,\nbirincisi düşüldükten sonra kalan tutara işler). RF_FISHAREKET.HARISKYUZ1..5 ve\nhesaplanan tutarlar HARISKYTUT1..5 kolonlarına yazılır; ayrıca RF_FISTOPLAM'a\nTKONU 1..5 iskonto satırları üretilir.",
            "nullable": true
          },
          "aciklama": {
            "type": "string",
            "description": "Satır açıklaması.",
            "nullable": true
          },
          "partiNo": {
            "type": "string",
            "description": "Parti / lot numarası.",
            "nullable": true
          },
          "satirReferansi": {
            "type": "integer",
            "description": "Çağıran sistemdeki satır kimliği (RF_FISHAREKET.HARRB1). ETA belgesine aynen taşınır;\nsatır bazlı mutabakat için kullanılabilir.",
            "format": "int32",
            "nullable": true
          },
          "hamAlanlar": {
            "type": "object",
            "additionalProperties": {
              "nullable": true
            },
            "description": "Bu satırın RF_FISHAREKET kolonlarını doğrudan yazmak için ad/değer sözlüğü.\nKurallar JOI_ULUPINAR.API.Fis.RfFisIstek.HamAlanlar ile aynıdır.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Fişin tek bir kalemi."
      },
      "RfFisToplamlari": {
        "type": "object",
        "properties": {
          "malToplam": {
            "type": "number",
            "description": "İskonto sonrası, KDV hariç satır tutarları toplamı (FISMALTOP).",
            "format": "double"
          },
          "kdvMatrahi": {
            "type": "number",
            "description": "KDV matrahı toplamı (FISKDVMATRAHI).",
            "format": "double"
          },
          "kdvTutari": {
            "type": "number",
            "description": "KDV tutarı toplamı (FISKDVTUTARI).",
            "format": "double"
          },
          "genelToplam": {
            "type": "number",
            "description": "KDV dahil genel toplam (FISGENTOPLAM).",
            "format": "double"
          },
          "toplamIskonto": {
            "type": "number",
            "description": "Kalem iskontolarının toplamı (FISKALINDYTOP).",
            "format": "double"
          }
        },
        "additionalProperties": false,
        "description": "Yazılan fişin hesaplanmış toplamları. İstemci kendi hesabıyla karşılaştırabilir."
      },
      "RfFisYanit": {
        "type": "object",
        "properties": {
          "masterSatirId": {
            "type": "integer",
            "description": "RF_FISMASTER.MASTERSATIRID. Durum sorgusunda ve aktarım çağrısında kullanılır.",
            "format": "int32"
          },
          "belgeTuru": {
            "type": "string",
            "description": "fatura veya irsaliye."
          },
          "modulId": {
            "type": "integer",
            "description": "ETA modül numarası (fatura 3, irsaliye 6).",
            "format": "int32"
          },
          "disReferans": {
            "type": "string",
            "description": "İstekte verilen dış referans (FISEVRAKNO2)."
          },
          "belgeNo": {
            "type": "string",
            "description": "Yazılan belge numarası (FISEVRAKNO1); fatura için boş olabilir."
          },
          "hareketSatirSayisi": {
            "type": "integer",
            "description": "RF_FISHAREKET'e yazılan satır sayısı.",
            "format": "int32"
          },
          "toplamSatirSayisi": {
            "type": "integer",
            "description": "RF_FISTOPLAM'a yazılan satır sayısı (KDV kırılımı + iskonto + ek satırlar).",
            "format": "int32"
          },
          "toplamlar": {
            "$ref": "#/components/schemas/RfFisToplamlari"
          },
          "aktarimDurumu": {
            "$ref": "#/components/schemas/RfAktarimDurumu"
          }
        },
        "additionalProperties": false,
        "description": "POST sonucunda dönen özet."
      },
      "RfToplamSatirIstek": {
        "type": "object",
        "properties": {
          "konu": {
            "type": "integer",
            "description": "Satır konusu (RF_FISTOPLAM.TKONU). ⛔ API'nin kendi ürettiği aralıklar KULLANILAMAZ:\n1..5 kalem iskontoları, 101 ve sonrası KDV kırılımı. e-belge alanlarının aralığı\n(6401 ve sonrası) ETA'nın kendi yordamları tarafından üretilir, buraya yazılmamalıdır.",
            "format": "int32"
          },
          "baslik": {
            "type": "string",
            "description": "Satır başlığı (RF_FISTOPLAM.TBASLIK).",
            "nullable": true
          },
          "tutar": {
            "type": "number",
            "description": "Tutar.",
            "format": "double"
          },
          "matrah": {
            "type": "number",
            "description": "Matrah.",
            "format": "double"
          },
          "oncelik": {
            "type": "integer",
            "description": "Öncelik (RF_FISTOPLAM.TONCELIK).",
            "format": "int32"
          },
          "hamAlanlar": {
            "type": "object",
            "additionalProperties": {
              "nullable": true
            },
            "description": "Bu satırın RF_FISTOPLAM kolonlarını doğrudan yazmak için ad/değer sözlüğü.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "RF_FISTOPLAM'a eklenecek serbest bir toplam/başlık satırı."
      },
      "SatirVergi": {
        "type": "object",
        "properties": {
          "kod": {
            "type": "string",
            "nullable": true
          },
          "ad": {
            "type": "string",
            "nullable": true
          },
          "oran": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "tutar": {
            "type": "number",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SayfaliSonucCariFisTipiKayit": {
        "type": "object",
        "properties": {
          "toplam": {
            "type": "integer",
            "description": "Filtreyle eşleşen toplam kayıt sayısı; `null` ise kaynak gerçek bir toplam veremiyor\ndemektir (bu durumda sayfalamanın bittiği `kayitlar` uzunluğunun `take`'ten küçük\nolmasıyla anlaşılır).",
            "format": "int32",
            "nullable": true
          },
          "skip": {
            "type": "integer",
            "description": "Uygulanan atlama sayısı.",
            "format": "int32"
          },
          "take": {
            "type": "integer",
            "description": "Uygulanan sayfa boyutu (normalize edilmiş hali; 0 gönderilirse 100 olur).",
            "format": "int32"
          },
          "kayitlar": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CariFisTipiKayit"
            },
            "description": "Bu sayfadaki kayıtlar."
          }
        },
        "additionalProperties": false,
        "description": "Sayfalı liste sonucu. Toplam`null` ise kaynak gerçek bir \"toplam\neşleşen kayıt\" sayısı VEREMEMİŞTİR (ör. EDM'nin LIMIT/OFFSET tabanlı GetInvoice'u toplam\ndöndürmez) — bu durumda sayfalamanın bittiğini anlamak için `Kayitlar.Count < Take`\nkontrol edilmelidir. Toplam `null` DEĞİLSE gerçek eşleşen kayıt sayısıdır (ör. cari kart\nucu CARKART üzerinde `COUNT(*)` çalıştırır) ve istemci bunu kaç sayfa çekmesi gerektiğini\nhesaplamak için doğrudan kullanabilir."
      },
      "SayfaliSonucCariKayit": {
        "type": "object",
        "properties": {
          "toplam": {
            "type": "integer",
            "description": "Filtreyle eşleşen toplam kayıt sayısı; `null` ise kaynak gerçek bir toplam veremiyor\ndemektir (bu durumda sayfalamanın bittiği `kayitlar` uzunluğunun `take`'ten küçük\nolmasıyla anlaşılır).",
            "format": "int32",
            "nullable": true
          },
          "skip": {
            "type": "integer",
            "description": "Uygulanan atlama sayısı.",
            "format": "int32"
          },
          "take": {
            "type": "integer",
            "description": "Uygulanan sayfa boyutu (normalize edilmiş hali; 0 gönderilirse 100 olur).",
            "format": "int32"
          },
          "kayitlar": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CariKayit"
            },
            "description": "Bu sayfadaki kayıtlar."
          }
        },
        "additionalProperties": false,
        "description": "Sayfalı liste sonucu. Toplam`null` ise kaynak gerçek bir \"toplam\neşleşen kayıt\" sayısı VEREMEMİŞTİR (ör. EDM'nin LIMIT/OFFSET tabanlı GetInvoice'u toplam\ndöndürmez) — bu durumda sayfalamanın bittiğini anlamak için `Kayitlar.Count < Take`\nkontrol edilmelidir. Toplam `null` DEĞİLSE gerçek eşleşen kayıt sayısıdır (ör. cari kart\nucu CARKART üzerinde `COUNT(*)` çalıştırır) ve istemci bunu kaç sayfa çekmesi gerektiğini\nhesaplamak için doğrudan kullanabilir."
      },
      "SayfaliSonucDovizKuruKayit": {
        "type": "object",
        "properties": {
          "toplam": {
            "type": "integer",
            "description": "Filtreyle eşleşen toplam kayıt sayısı; `null` ise kaynak gerçek bir toplam veremiyor\ndemektir (bu durumda sayfalamanın bittiği `kayitlar` uzunluğunun `take`'ten küçük\nolmasıyla anlaşılır).",
            "format": "int32",
            "nullable": true
          },
          "skip": {
            "type": "integer",
            "description": "Uygulanan atlama sayısı.",
            "format": "int32"
          },
          "take": {
            "type": "integer",
            "description": "Uygulanan sayfa boyutu (normalize edilmiş hali; 0 gönderilirse 100 olur).",
            "format": "int32"
          },
          "kayitlar": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DovizKuruKayit"
            },
            "description": "Bu sayfadaki kayıtlar."
          }
        },
        "additionalProperties": false,
        "description": "Sayfalı liste sonucu. Toplam`null` ise kaynak gerçek bir \"toplam\neşleşen kayıt\" sayısı VEREMEMİŞTİR (ör. EDM'nin LIMIT/OFFSET tabanlı GetInvoice'u toplam\ndöndürmez) — bu durumda sayfalamanın bittiğini anlamak için `Kayitlar.Count < Take`\nkontrol edilmelidir. Toplam `null` DEĞİLSE gerçek eşleşen kayıt sayısıdır (ör. cari kart\nucu CARKART üzerinde `COUNT(*)` çalıştırır) ve istemci bunu kaç sayfa çekmesi gerektiğini\nhesaplamak için doğrudan kullanabilir."
      },
      "SayfaliSonucDovizTanimiKayit": {
        "type": "object",
        "properties": {
          "toplam": {
            "type": "integer",
            "description": "Filtreyle eşleşen toplam kayıt sayısı; `null` ise kaynak gerçek bir toplam veremiyor\ndemektir (bu durumda sayfalamanın bittiği `kayitlar` uzunluğunun `take`'ten küçük\nolmasıyla anlaşılır).",
            "format": "int32",
            "nullable": true
          },
          "skip": {
            "type": "integer",
            "description": "Uygulanan atlama sayısı.",
            "format": "int32"
          },
          "take": {
            "type": "integer",
            "description": "Uygulanan sayfa boyutu (normalize edilmiş hali; 0 gönderilirse 100 olur).",
            "format": "int32"
          },
          "kayitlar": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DovizTanimiKayit"
            },
            "description": "Bu sayfadaki kayıtlar."
          }
        },
        "additionalProperties": false,
        "description": "Sayfalı liste sonucu. Toplam`null` ise kaynak gerçek bir \"toplam\neşleşen kayıt\" sayısı VEREMEMİŞTİR (ör. EDM'nin LIMIT/OFFSET tabanlı GetInvoice'u toplam\ndöndürmez) — bu durumda sayfalamanın bittiğini anlamak için `Kayitlar.Count < Take`\nkontrol edilmelidir. Toplam `null` DEĞİLSE gerçek eşleşen kayıt sayısıdır (ör. cari kart\nucu CARKART üzerinde `COUNT(*)` çalıştırır) ve istemci bunu kaç sayfa çekmesi gerektiğini\nhesaplamak için doğrudan kullanabilir."
      },
      "SayfaliSonucFaturaFisTipiKayit": {
        "type": "object",
        "properties": {
          "toplam": {
            "type": "integer",
            "description": "Filtreyle eşleşen toplam kayıt sayısı; `null` ise kaynak gerçek bir toplam veremiyor\ndemektir (bu durumda sayfalamanın bittiği `kayitlar` uzunluğunun `take`'ten küçük\nolmasıyla anlaşılır).",
            "format": "int32",
            "nullable": true
          },
          "skip": {
            "type": "integer",
            "description": "Uygulanan atlama sayısı.",
            "format": "int32"
          },
          "take": {
            "type": "integer",
            "description": "Uygulanan sayfa boyutu (normalize edilmiş hali; 0 gönderilirse 100 olur).",
            "format": "int32"
          },
          "kayitlar": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FaturaFisTipiKayit"
            },
            "description": "Bu sayfadaki kayıtlar."
          }
        },
        "additionalProperties": false,
        "description": "Sayfalı liste sonucu. Toplam`null` ise kaynak gerçek bir \"toplam\neşleşen kayıt\" sayısı VEREMEMİŞTİR (ör. EDM'nin LIMIT/OFFSET tabanlı GetInvoice'u toplam\ndöndürmez) — bu durumda sayfalamanın bittiğini anlamak için `Kayitlar.Count < Take`\nkontrol edilmelidir. Toplam `null` DEĞİLSE gerçek eşleşen kayıt sayısıdır (ör. cari kart\nucu CARKART üzerinde `COUNT(*)` çalıştırır) ve istemci bunu kaç sayfa çekmesi gerektiğini\nhesaplamak için doğrudan kullanabilir."
      },
      "SayfaliSonucGelenFaturaOzet": {
        "type": "object",
        "properties": {
          "toplam": {
            "type": "integer",
            "description": "Filtreyle eşleşen toplam kayıt sayısı; `null` ise kaynak gerçek bir toplam veremiyor\ndemektir (bu durumda sayfalamanın bittiği `kayitlar` uzunluğunun `take`'ten küçük\nolmasıyla anlaşılır).",
            "format": "int32",
            "nullable": true
          },
          "skip": {
            "type": "integer",
            "description": "Uygulanan atlama sayısı.",
            "format": "int32"
          },
          "take": {
            "type": "integer",
            "description": "Uygulanan sayfa boyutu (normalize edilmiş hali; 0 gönderilirse 100 olur).",
            "format": "int32"
          },
          "kayitlar": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/GelenFaturaOzet"
            },
            "description": "Bu sayfadaki kayıtlar."
          }
        },
        "additionalProperties": false,
        "description": "Sayfalı liste sonucu. Toplam`null` ise kaynak gerçek bir \"toplam\neşleşen kayıt\" sayısı VEREMEMİŞTİR (ör. EDM'nin LIMIT/OFFSET tabanlı GetInvoice'u toplam\ndöndürmez) — bu durumda sayfalamanın bittiğini anlamak için `Kayitlar.Count < Take`\nkontrol edilmelidir. Toplam `null` DEĞİLSE gerçek eşleşen kayıt sayısıdır (ör. cari kart\nucu CARKART üzerinde `COUNT(*)` çalıştırır) ve istemci bunu kaç sayfa çekmesi gerektiğini\nhesaplamak için doğrudan kullanabilir."
      },
      "SayfaliSonucGelenIrsaliyeOzet": {
        "type": "object",
        "properties": {
          "toplam": {
            "type": "integer",
            "description": "Filtreyle eşleşen toplam kayıt sayısı; `null` ise kaynak gerçek bir toplam veremiyor\ndemektir (bu durumda sayfalamanın bittiği `kayitlar` uzunluğunun `take`'ten küçük\nolmasıyla anlaşılır).",
            "format": "int32",
            "nullable": true
          },
          "skip": {
            "type": "integer",
            "description": "Uygulanan atlama sayısı.",
            "format": "int32"
          },
          "take": {
            "type": "integer",
            "description": "Uygulanan sayfa boyutu (normalize edilmiş hali; 0 gönderilirse 100 olur).",
            "format": "int32"
          },
          "kayitlar": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/GelenIrsaliyeOzet"
            },
            "description": "Bu sayfadaki kayıtlar."
          }
        },
        "additionalProperties": false,
        "description": "Sayfalı liste sonucu. Toplam`null` ise kaynak gerçek bir \"toplam\neşleşen kayıt\" sayısı VEREMEMİŞTİR (ör. EDM'nin LIMIT/OFFSET tabanlı GetInvoice'u toplam\ndöndürmez) — bu durumda sayfalamanın bittiğini anlamak için `Kayitlar.Count < Take`\nkontrol edilmelidir. Toplam `null` DEĞİLSE gerçek eşleşen kayıt sayısıdır (ör. cari kart\nucu CARKART üzerinde `COUNT(*)` çalıştırır) ve istemci bunu kaç sayfa çekmesi gerektiğini\nhesaplamak için doğrudan kullanabilir."
      },
      "SayfaliSonucHizmetKayit": {
        "type": "object",
        "properties": {
          "toplam": {
            "type": "integer",
            "description": "Filtreyle eşleşen toplam kayıt sayısı; `null` ise kaynak gerçek bir toplam veremiyor\ndemektir (bu durumda sayfalamanın bittiği `kayitlar` uzunluğunun `take`'ten küçük\nolmasıyla anlaşılır).",
            "format": "int32",
            "nullable": true
          },
          "skip": {
            "type": "integer",
            "description": "Uygulanan atlama sayısı.",
            "format": "int32"
          },
          "take": {
            "type": "integer",
            "description": "Uygulanan sayfa boyutu (normalize edilmiş hali; 0 gönderilirse 100 olur).",
            "format": "int32"
          },
          "kayitlar": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HizmetKayit"
            },
            "description": "Bu sayfadaki kayıtlar."
          }
        },
        "additionalProperties": false,
        "description": "Sayfalı liste sonucu. Toplam`null` ise kaynak gerçek bir \"toplam\neşleşen kayıt\" sayısı VEREMEMİŞTİR (ör. EDM'nin LIMIT/OFFSET tabanlı GetInvoice'u toplam\ndöndürmez) — bu durumda sayfalamanın bittiğini anlamak için `Kayitlar.Count < Take`\nkontrol edilmelidir. Toplam `null` DEĞİLSE gerçek eşleşen kayıt sayısıdır (ör. cari kart\nucu CARKART üzerinde `COUNT(*)` çalıştırır) ve istemci bunu kaç sayfa çekmesi gerektiğini\nhesaplamak için doğrudan kullanabilir."
      },
      "SayfaliSonucIrsaliyeFisTipiKayit": {
        "type": "object",
        "properties": {
          "toplam": {
            "type": "integer",
            "description": "Filtreyle eşleşen toplam kayıt sayısı; `null` ise kaynak gerçek bir toplam veremiyor\ndemektir (bu durumda sayfalamanın bittiği `kayitlar` uzunluğunun `take`'ten küçük\nolmasıyla anlaşılır).",
            "format": "int32",
            "nullable": true
          },
          "skip": {
            "type": "integer",
            "description": "Uygulanan atlama sayısı.",
            "format": "int32"
          },
          "take": {
            "type": "integer",
            "description": "Uygulanan sayfa boyutu (normalize edilmiş hali; 0 gönderilirse 100 olur).",
            "format": "int32"
          },
          "kayitlar": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/IrsaliyeFisTipiKayit"
            },
            "description": "Bu sayfadaki kayıtlar."
          }
        },
        "additionalProperties": false,
        "description": "Sayfalı liste sonucu. Toplam`null` ise kaynak gerçek bir \"toplam\neşleşen kayıt\" sayısı VEREMEMİŞTİR (ör. EDM'nin LIMIT/OFFSET tabanlı GetInvoice'u toplam\ndöndürmez) — bu durumda sayfalamanın bittiğini anlamak için `Kayitlar.Count < Take`\nkontrol edilmelidir. Toplam `null` DEĞİLSE gerçek eşleşen kayıt sayısıdır (ör. cari kart\nucu CARKART üzerinde `COUNT(*)` çalıştırır) ve istemci bunu kaç sayfa çekmesi gerektiğini\nhesaplamak için doğrudan kullanabilir."
      },
      "SayfaliSonucKdvKisimKayit": {
        "type": "object",
        "properties": {
          "toplam": {
            "type": "integer",
            "description": "Filtreyle eşleşen toplam kayıt sayısı; `null` ise kaynak gerçek bir toplam veremiyor\ndemektir (bu durumda sayfalamanın bittiği `kayitlar` uzunluğunun `take`'ten küçük\nolmasıyla anlaşılır).",
            "format": "int32",
            "nullable": true
          },
          "skip": {
            "type": "integer",
            "description": "Uygulanan atlama sayısı.",
            "format": "int32"
          },
          "take": {
            "type": "integer",
            "description": "Uygulanan sayfa boyutu (normalize edilmiş hali; 0 gönderilirse 100 olur).",
            "format": "int32"
          },
          "kayitlar": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/KdvKisimKayit"
            },
            "description": "Bu sayfadaki kayıtlar."
          }
        },
        "additionalProperties": false,
        "description": "Sayfalı liste sonucu. Toplam`null` ise kaynak gerçek bir \"toplam\neşleşen kayıt\" sayısı VEREMEMİŞTİR (ör. EDM'nin LIMIT/OFFSET tabanlı GetInvoice'u toplam\ndöndürmez) — bu durumda sayfalamanın bittiğini anlamak için `Kayitlar.Count < Take`\nkontrol edilmelidir. Toplam `null` DEĞİLSE gerçek eşleşen kayıt sayısıdır (ör. cari kart\nucu CARKART üzerinde `COUNT(*)` çalıştırır) ve istemci bunu kaç sayfa çekmesi gerektiğini\nhesaplamak için doğrudan kullanabilir."
      },
      "SayfaliSonucKurTuruKayit": {
        "type": "object",
        "properties": {
          "toplam": {
            "type": "integer",
            "description": "Filtreyle eşleşen toplam kayıt sayısı; `null` ise kaynak gerçek bir toplam veremiyor\ndemektir (bu durumda sayfalamanın bittiği `kayitlar` uzunluğunun `take`'ten küçük\nolmasıyla anlaşılır).",
            "format": "int32",
            "nullable": true
          },
          "skip": {
            "type": "integer",
            "description": "Uygulanan atlama sayısı.",
            "format": "int32"
          },
          "take": {
            "type": "integer",
            "description": "Uygulanan sayfa boyutu (normalize edilmiş hali; 0 gönderilirse 100 olur).",
            "format": "int32"
          },
          "kayitlar": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/KurTuruKayit"
            },
            "description": "Bu sayfadaki kayıtlar."
          }
        },
        "additionalProperties": false,
        "description": "Sayfalı liste sonucu. Toplam`null` ise kaynak gerçek bir \"toplam\neşleşen kayıt\" sayısı VEREMEMİŞTİR (ör. EDM'nin LIMIT/OFFSET tabanlı GetInvoice'u toplam\ndöndürmez) — bu durumda sayfalamanın bittiğini anlamak için `Kayitlar.Count < Take`\nkontrol edilmelidir. Toplam `null` DEĞİLSE gerçek eşleşen kayıt sayısıdır (ör. cari kart\nucu CARKART üzerinde `COUNT(*)` çalıştırır) ve istemci bunu kaç sayfa çekmesi gerektiğini\nhesaplamak için doğrudan kullanabilir."
      },
      "SayfaliSonucMuhasebeFisTipiKayit": {
        "type": "object",
        "properties": {
          "toplam": {
            "type": "integer",
            "description": "Filtreyle eşleşen toplam kayıt sayısı; `null` ise kaynak gerçek bir toplam veremiyor\ndemektir (bu durumda sayfalamanın bittiği `kayitlar` uzunluğunun `take`'ten küçük\nolmasıyla anlaşılır).",
            "format": "int32",
            "nullable": true
          },
          "skip": {
            "type": "integer",
            "description": "Uygulanan atlama sayısı.",
            "format": "int32"
          },
          "take": {
            "type": "integer",
            "description": "Uygulanan sayfa boyutu (normalize edilmiş hali; 0 gönderilirse 100 olur).",
            "format": "int32"
          },
          "kayitlar": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MuhasebeFisTipiKayit"
            },
            "description": "Bu sayfadaki kayıtlar."
          }
        },
        "additionalProperties": false,
        "description": "Sayfalı liste sonucu. Toplam`null` ise kaynak gerçek bir \"toplam\neşleşen kayıt\" sayısı VEREMEMİŞTİR (ör. EDM'nin LIMIT/OFFSET tabanlı GetInvoice'u toplam\ndöndürmez) — bu durumda sayfalamanın bittiğini anlamak için `Kayitlar.Count < Take`\nkontrol edilmelidir. Toplam `null` DEĞİLSE gerçek eşleşen kayıt sayısıdır (ör. cari kart\nucu CARKART üzerinde `COUNT(*)` çalıştırır) ve istemci bunu kaç sayfa çekmesi gerektiğini\nhesaplamak için doğrudan kullanabilir."
      },
      "SayfaliSonucStokBirimKayit": {
        "type": "object",
        "properties": {
          "toplam": {
            "type": "integer",
            "description": "Filtreyle eşleşen toplam kayıt sayısı; `null` ise kaynak gerçek bir toplam veremiyor\ndemektir (bu durumda sayfalamanın bittiği `kayitlar` uzunluğunun `take`'ten küçük\nolmasıyla anlaşılır).",
            "format": "int32",
            "nullable": true
          },
          "skip": {
            "type": "integer",
            "description": "Uygulanan atlama sayısı.",
            "format": "int32"
          },
          "take": {
            "type": "integer",
            "description": "Uygulanan sayfa boyutu (normalize edilmiş hali; 0 gönderilirse 100 olur).",
            "format": "int32"
          },
          "kayitlar": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StokBirimKayit"
            },
            "description": "Bu sayfadaki kayıtlar."
          }
        },
        "additionalProperties": false,
        "description": "Sayfalı liste sonucu. Toplam`null` ise kaynak gerçek bir \"toplam\neşleşen kayıt\" sayısı VEREMEMİŞTİR (ör. EDM'nin LIMIT/OFFSET tabanlı GetInvoice'u toplam\ndöndürmez) — bu durumda sayfalamanın bittiğini anlamak için `Kayitlar.Count < Take`\nkontrol edilmelidir. Toplam `null` DEĞİLSE gerçek eşleşen kayıt sayısıdır (ör. cari kart\nucu CARKART üzerinde `COUNT(*)` çalıştırır) ve istemci bunu kaç sayfa çekmesi gerektiğini\nhesaplamak için doğrudan kullanabilir."
      },
      "SayfaliSonucStokFisTipiKayit": {
        "type": "object",
        "properties": {
          "toplam": {
            "type": "integer",
            "description": "Filtreyle eşleşen toplam kayıt sayısı; `null` ise kaynak gerçek bir toplam veremiyor\ndemektir (bu durumda sayfalamanın bittiği `kayitlar` uzunluğunun `take`'ten küçük\nolmasıyla anlaşılır).",
            "format": "int32",
            "nullable": true
          },
          "skip": {
            "type": "integer",
            "description": "Uygulanan atlama sayısı.",
            "format": "int32"
          },
          "take": {
            "type": "integer",
            "description": "Uygulanan sayfa boyutu (normalize edilmiş hali; 0 gönderilirse 100 olur).",
            "format": "int32"
          },
          "kayitlar": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StokFisTipiKayit"
            },
            "description": "Bu sayfadaki kayıtlar."
          }
        },
        "additionalProperties": false,
        "description": "Sayfalı liste sonucu. Toplam`null` ise kaynak gerçek bir \"toplam\neşleşen kayıt\" sayısı VEREMEMİŞTİR (ör. EDM'nin LIMIT/OFFSET tabanlı GetInvoice'u toplam\ndöndürmez) — bu durumda sayfalamanın bittiğini anlamak için `Kayitlar.Count < Take`\nkontrol edilmelidir. Toplam `null` DEĞİLSE gerçek eşleşen kayıt sayısıdır (ör. cari kart\nucu CARKART üzerinde `COUNT(*)` çalıştırır) ve istemci bunu kaç sayfa çekmesi gerektiğini\nhesaplamak için doğrudan kullanabilir."
      },
      "SayfaliSonucStokFiyatKayit": {
        "type": "object",
        "properties": {
          "toplam": {
            "type": "integer",
            "description": "Filtreyle eşleşen toplam kayıt sayısı; `null` ise kaynak gerçek bir toplam veremiyor\ndemektir (bu durumda sayfalamanın bittiği `kayitlar` uzunluğunun `take`'ten küçük\nolmasıyla anlaşılır).",
            "format": "int32",
            "nullable": true
          },
          "skip": {
            "type": "integer",
            "description": "Uygulanan atlama sayısı.",
            "format": "int32"
          },
          "take": {
            "type": "integer",
            "description": "Uygulanan sayfa boyutu (normalize edilmiş hali; 0 gönderilirse 100 olur).",
            "format": "int32"
          },
          "kayitlar": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StokFiyatKayit"
            },
            "description": "Bu sayfadaki kayıtlar."
          }
        },
        "additionalProperties": false,
        "description": "Sayfalı liste sonucu. Toplam`null` ise kaynak gerçek bir \"toplam\neşleşen kayıt\" sayısı VEREMEMİŞTİR (ör. EDM'nin LIMIT/OFFSET tabanlı GetInvoice'u toplam\ndöndürmez) — bu durumda sayfalamanın bittiğini anlamak için `Kayitlar.Count < Take`\nkontrol edilmelidir. Toplam `null` DEĞİLSE gerçek eşleşen kayıt sayısıdır (ör. cari kart\nucu CARKART üzerinde `COUNT(*)` çalıştırır) ve istemci bunu kaç sayfa çekmesi gerektiğini\nhesaplamak için doğrudan kullanabilir."
      },
      "SayfaliSonucStokKayit": {
        "type": "object",
        "properties": {
          "toplam": {
            "type": "integer",
            "description": "Filtreyle eşleşen toplam kayıt sayısı; `null` ise kaynak gerçek bir toplam veremiyor\ndemektir (bu durumda sayfalamanın bittiği `kayitlar` uzunluğunun `take`'ten küçük\nolmasıyla anlaşılır).",
            "format": "int32",
            "nullable": true
          },
          "skip": {
            "type": "integer",
            "description": "Uygulanan atlama sayısı.",
            "format": "int32"
          },
          "take": {
            "type": "integer",
            "description": "Uygulanan sayfa boyutu (normalize edilmiş hali; 0 gönderilirse 100 olur).",
            "format": "int32"
          },
          "kayitlar": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StokKayit"
            },
            "description": "Bu sayfadaki kayıtlar."
          }
        },
        "additionalProperties": false,
        "description": "Sayfalı liste sonucu. Toplam`null` ise kaynak gerçek bir \"toplam\neşleşen kayıt\" sayısı VEREMEMİŞTİR (ör. EDM'nin LIMIT/OFFSET tabanlı GetInvoice'u toplam\ndöndürmez) — bu durumda sayfalamanın bittiğini anlamak için `Kayitlar.Count < Take`\nkontrol edilmelidir. Toplam `null` DEĞİLSE gerçek eşleşen kayıt sayısıdır (ör. cari kart\nucu CARKART üzerinde `COUNT(*)` çalıştırır) ve istemci bunu kaç sayfa çekmesi gerektiğini\nhesaplamak için doğrudan kullanabilir."
      },
      "StokBirimKayit": {
        "required": [
          "stkbirimkod"
        ],
        "type": "object",
        "properties": {
          "stkbirimkod": {
            "type": "string",
            "description": "Birim kodu (`STKBIRIMKOD`). Sayfalama sıralaması bu alan ve ad üzerindedir."
          },
          "stkbirimad": {
            "type": "string",
            "description": "Birim adı (`STKBIRIMAD`).",
            "nullable": true
          },
          "stkbirimcarpan": {
            "type": "number",
            "description": "Çarpan (`STKBIRIMCARPAN`). ⚠ Ölçülen kurulumların TAMAMINDA 0'dır; birim\ndönüşümünde doğrudan kullanılamaz.",
            "format": "double",
            "nullable": true
          },
          "stkbirimbolen": {
            "type": "number",
            "description": "Bölen (`STKBIRIMBOLEN`). Çarpan ile aynı uyarı geçerlidir.",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": { },
        "description": "Stok birim tanımı (`STKBIRIM` satırı). Tablo yalnız dört kolondur; hepsi burada\nadlandırılmıştır, yine de `additionalProperties` korunur — farklı bir ETA sürümü\nkolon eklerse belge yalan söylemesin."
      },
      "StokFisTipiKayit": {
        "required": [
          "stkgenftno"
        ],
        "type": "object",
        "properties": {
          "stkgenftno": {
            "type": "integer",
            "description": "Fiş tipi numarası (`STKGENFTNO`). Sayfalama sıralaması bu alan üzerindedir.",
            "format": "int32"
          },
          "stkgenftkod": {
            "type": "string",
            "description": "Kısa kod (`STKGENFTKOD`), ör. \"DEPO-A\". `kodOnek` filtresi bu alana uygulanır.",
            "nullable": true
          },
          "stkgenftaciklama": {
            "type": "string",
            "description": "Açıklama (`STKGENFTACIKLAMA`), ör. \"DEPO FİŞİ (ALIŞ)\".",
            "nullable": true
          },
          "stkgenfttip": {
            "type": "integer",
            "description": "Fiş tipi ayrımı (`STKGENFTTIP`).",
            "format": "int32",
            "nullable": true
          },
          "stkgenftdepo": {
            "type": "integer",
            "description": "Depo fişi mi (`STKGENFTDEPO`).",
            "format": "int32",
            "nullable": true
          },
          "stkgenftiade": {
            "type": "integer",
            "description": "İade fişi mi (`STKGENFTIADE`): 1 iade, 0 normal.",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": { },
        "description": "Stok fiş tipi (`STKGENFISTIP` satırı)."
      },
      "StokFiyatKayit": {
        "required": [
          "stkfiystkkod"
        ],
        "type": "object",
        "properties": {
          "stkfiystkkod": {
            "type": "string",
            "description": "Stok kodu (`STKFIYSTKKOD`). `STKKART.STKKOD` ile eşleşir."
          },
          "stkfiydepkod": {
            "type": "string",
            "description": "Depo kodu (`STKFIYDEPKOD`). ⚠ Bazı kurulumlarda tüm satırlarda boştur.",
            "nullable": true
          },
          "stkfiyno": {
            "type": "integer",
            "description": "Fiyat listesi numarası (`STKFIYNO`). Ölçülen kurulumda 1..5.",
            "format": "int32",
            "nullable": true
          },
          "stkfiyitemno": {
            "type": "integer",
            "description": "Liste içindeki satır numarası (`STKFIYITEMNO`).",
            "format": "int32",
            "nullable": true
          },
          "stkfiytutar": {
            "type": "number",
            "description": "Fiyat (`STKFIYTUTAR`).",
            "format": "double",
            "nullable": true
          },
          "stkfiydovkod": {
            "type": "string",
            "description": "Döviz kodu (`STKFIYDOVKOD`); TL fiyatlarda boştur.",
            "nullable": true
          }
        },
        "additionalProperties": { },
        "description": "Stok fiyat satırı (`STKFIYAT` satırı).\n\n⛔ Bu tabloda hiçbir kolon bileşimi TEKİL DEĞİLDİR: ölçülen kurulumlarda 26 kolonun\ntamamı aynı olan TAM KOPYA satırlar bulundu. Sayfalama sırası bu kopyalar arasında\nbelirsizdir (bkz. ucun açıklaması)."
      },
      "StokKayit": {
        "required": [
          "stkkod"
        ],
        "type": "object",
        "properties": {
          "stkkod": {
            "type": "string",
            "description": "Stok kodu (`STKKOD`). Sayfalama sıralaması bu alan üzerindedir."
          },
          "stkcinsi": {
            "type": "string",
            "description": "Stok cinsi/adı (`STKCINSI`).",
            "nullable": true
          },
          "stkcalflag": {
            "type": "integer",
            "description": "Aktiflik (`STKCALFLAG`): 1 aktif, 0 pasif.",
            "format": "int32",
            "nullable": true
          },
          "fiyatlar": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HamSatir"
            },
            "description": "`STKFIYAT` satırları. YALNIZ `fiyatlar=true` istendiğinde bulunur;\nistenmediğinde bu anahtar yanıtta HİÇ yer almaz (boş dizi de dönmez) — böylece\n\"fiyat istenmedi\" ile \"fiyatı yok\" birbirine karışmaz.",
            "nullable": true
          }
        },
        "additionalProperties": { },
        "description": "Stok kartı (`STKKART` satırı) ve istenirse fiyat satırları."
      },
      "Taraf": {
        "type": "object",
        "properties": {
          "vkn": {
            "type": "string",
            "nullable": true
          },
          "unvan": {
            "type": "string",
            "nullable": true
          },
          "vergiDairesi": {
            "type": "string",
            "nullable": true
          },
          "adres": {
            "type": "string",
            "nullable": true
          },
          "ilce": {
            "type": "string",
            "nullable": true
          },
          "il": {
            "type": "string",
            "nullable": true
          },
          "ulke": {
            "type": "string",
            "nullable": true
          },
          "telefon": {
            "type": "string",
            "nullable": true
          },
          "eposta": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Fatura/irsaliye üzerindeki gönderen veya alıcı taraf."
      },
      "Tasiyici": {
        "type": "object",
        "properties": {
          "vkn": {
            "type": "string",
            "nullable": true
          },
          "unvan": {
            "type": "string",
            "nullable": true
          },
          "plaka": {
            "type": "string",
            "nullable": true
          },
          "soforAdSoyad": {
            "type": "string",
            "nullable": true
          },
          "soforTckn": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "TokenIstek": {
        "required": [
          "apiKey",
          "kullaniciAdi",
          "sifre"
        ],
        "type": "object",
        "properties": {
          "kullaniciAdi": {
            "type": "string",
            "description": "Panelden tanımlanan kiracı kullanıcı adı."
          },
          "sifre": {
            "type": "string",
            "description": "Kiracı şifresi."
          },
          "apiKey": {
            "type": "string",
            "description": "Kiracıya özel API anahtarı; kullanıcı adı ve şifreyle birlikte üçü de doğru olmalıdır."
          }
        },
        "additionalProperties": false
      },
      "TokenYanit": {
        "type": "object",
        "properties": {
          "token": {
            "type": "string",
            "description": "JWT. Sonraki isteklerde `Authorization: Bearer <token>` olarak gönderilir."
          },
          "gecerlilikBitis": {
            "type": "string",
            "description": "Token'ın geçerlilik bitişi (UTC).",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "VergiToplami": {
        "type": "object",
        "properties": {
          "vergiKodu": {
            "type": "string",
            "nullable": true
          },
          "vergiAdi": {
            "type": "string",
            "nullable": true
          },
          "matrah": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "oran": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "tutar": {
            "type": "number",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false
      }
    },
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "description": "POST /api/auth/token ile alınan JWT. Öntanımlı geçerlilik süresi 8 saattir (kurulumda değiştirilebilir); süre dolunca yeniden token alınır.",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      }
    }
  },
  "tags": [
    {
      "name": "Servis",
      "description": "Kimlik doğrulama istemeyen servis uçları."
    },
    {
      "name": "Kimlik",
      "description": "Token üretimi."
    },
    {
      "name": "Firmalar",
      "description": "Token sahibinin erişebildiği ETA veritabanları."
    },
    {
      "name": "Kartlar",
      "description": "Cari, stok ve hizmet kartı listeleri. Hepsi sayfalıdır ve etaDb ister."
    },
    {
      "name": "Belgeler",
      "description": "Entegratörden (EDM / Digital Planet) GELEN e-Fatura ve e-İrsaliyeler. Kart ve master uçlarından farklı olarak veri ETA SQL'de değil müşterinin entegratör hesabındadır; hangi entegratörle konuşulacağı ETA'daki SABITLER tablosundan okunur, yani aynı uç kiracıdan kiracıya farklı bir servise gider. Yalnız GELEN belgeler listelenir ve entegratördeki okundu işareti DEĞİŞTİRİLMEZ."
    },
    {
      "name": "Master Tanımları",
      "description": "ETA MASTER veritabanındaki (ETA_MASTER / ETA_MASTERV8) kurulum geneli tanımlar: fiş tipleri, KDV kısımları, döviz ve kur türü tanımları ile döviz kuru geçmişi. Bu veriler bir firmaya değil kurulumun tamamına aittir; bu yüzden etaDb değil masterDb parametresi alırlar ve /api/v1/firmalar listesindeki değerler burada KULLANILAMAZ."
    },
    {
      "name": "Fişler",
      "description": "ETA'ya fatura ve irsaliye YAZMA uçları. Diğer grupların tersine bu uçlar veri okumaz, müşterinin ETA veritabanına kayıt ekler: fiş, ETA'nın aktarım (RF) tablolarına tek bir veritabanı işlemi içinde yazılır — ya üç tablonun hepsi ya da hiçbiri. Gerçek ETA belgesi (FATFIS / IRSFIS) bu uçlarda OLUŞMAZ; onu üreten saklı yordamı ETA tarafındaki kendi işiniz çağırır ve sonuç durum ucundan izlenir. Aynı dış referansla ikinci bir yazım veritabanı düzeyinde engellenir, yani yeniden denenen bir istek mükerrer fiş oluşturamaz."
    }
  ]
}