{"openapi":"3.0.3","info":{"title":"IQV Support API","version":"1.0.0","description":"IQV Support servislerinin API dokümantasyonu.\n\nSupport backend'i Express + MongoDB üzerinde çalışır. Kapsam: oturum açma, kullanıcı yönetimi, firma/talep okuma, destek talebi oluşturma ve çözümleme, konu yönetimi, QR destek talep oturumu, tek birleşik \"Ekler\" dosya yükleme ve Saha Takip kaydı. Korumalı uçlar `Authorization: Bearer <token>` başlığı ister (token: **Auth → POST /api/v1/auth/login**).\n\n## API Summary\n\n- **Total APIs:** 17\n- **Internal APIs:** 13\n- **External APIs:** 1\n- **System APIs:** 3\n\n## Classification\n\n- **INTERNAL APIs** — IQV Support uygulamasının kendi iş süreçlerinde kullandığı dahili business API operasyonları.\n- **EXTERNAL APIs** — IQV Support dashboard'u dışındaki bir istemci tarafından tüketilen uçlar (QR formu bağımsız bir uygulamadır; `resolve` ucunu yalnızca o çağırır, dashboard hiç çağırmaz).\n- **SYSTEM APIs** — Kimlik doğrulama, oturum ve sağlık kontrolü servisleri.\n\nHer operasyon **TOTAL APIs** grubunda VE kendi sınıflandırma grubunda görünür; bu bilinçli bir sunum tekrarıdır, API Summary sayımında operasyon mükerrer sayılmaz. Sınıflandırma tek kaynaktan gelir: her operasyondaki `x-iqv-classification` ve `x-iqv-domain` alanları. Kök seviyede **yalnızca bu 4 grup** vardır; iş alanları (Health, Auth, Users, ...) ayrı bir ana başlık DEĞİLDİR, ilgili grup açıldığında içeride ara başlık olarak görünür (CLASSIFICATION → DOMAIN → ENDPOINT).\n\n## Kimlik doğrulama sınıfları\n\n- **Auth yok:** `GET /health`, `POST /api/v1/auth/login` (token bu uçtan üretilir), `POST /api/v1/support/qr-sessions/resolve` (QR'ı okutan telefonda oturum yoktur).\n- **Zorunlu JWT (dashboard):** `/api/v1/users` uçlarının tamamı, `GET /api/v1/support/organizations`, `GET /api/v1/support/tickets`, `POST /api/v1/support/tickets`, `PUT /api/v1/support/tickets/{id}`, `POST /api/v1/support/qr-sessions` (QR token'ı bu uçta 403 alır), `POST /api/v1/track/records`.\n- **JWT veya QR oturum token'ı:** `GET /api/v1/support/subjects`, `POST /api/v1/support/subjects`, `POST /api/v1/support/files/upload`. QR token'ı dar izinlidir (`support.qr.read`, `ticket.create`, `ticket.upload`) ve MongoDB'deki oturum her istekte yeniden doğrulanır.\n\n## Ortam bağımlılığı\n\n- Tüm veri uçları `MONGODB_URI` / `MONGODB_DATABASE` olmadan çalışmaz (bkz. `GET /health` yanıtındaki `database` alanı).\n- Token üreten/doğrulayan uçlar `JWT_SECRET` olmadan işlev göremez.\n- `POST /api/v1/support/files/upload` MinIO değişkenleri (`MINIO_ENDPOINT`, `MINIO_ACCESS_KEY`, `MINIO_SECRET_KEY`, `SUPPORT_FILE_BUCKET`) olmadan çalışmaz. Yükleme sınırları `SUPPORT_UPLOAD_MAX_*` ile ayarlanır.\n- Telegram bildirimleri `TELEGRAM_BOT_TOKEN` / `TELEGRAM_CHAT_ID` olmadan sessizce atlanır; ana işlemi ASLA fail ettirmez.\n\nGizli değerler (secret, token, connection string) bu dokümanda YER ALMAZ; örnekler sahte değerlerdir."},"servers":[{"url":"http://localhost:3001","description":"Backend (geliştirme) — \"Try it out\" varsayılan hedefi."},{"url":"/","description":"Dokümanı sunan origin (tek domain / ters proxy arkasındaki kurulum)."}],"tags":[{"name":"TOTAL APIs","description":"IQV Support üzerinde tanımlı tüm API operasyonları (17)."},{"name":"INTERNAL APIs","description":"IQV Support uygulamasının kendi iş süreçlerinde kullandığı dahili business API operasyonları (13)."},{"name":"EXTERNAL APIs","description":"IQV Support dashboard'u dışındaki istemciler tarafından kullanılan API operasyonları (1)."},{"name":"SYSTEM APIs","description":"Kimlik doğrulama, oturum ve sağlık kontrolü servisleri (3)."}],"x-iqv-domains":{"Health":"Servis ve veritabani baglanti durumu.","Auth":"Oturum acma ve JWT uretimi.","Users":"Kullanici hesabi yonetimi (iqvizyon-users).","Support Organizations":"Firma listesi + hesaplanmis talep istatistigi.","Support Subjects":"Destek konulari (support-subject).","Support Records":"Destek talepleri (support-record) -- liste, olusturma, guncelleme.","QR Sessions":"QR destek talep oturumu -- olusturma ve cozumleme.","Attachments":"Tek birlesik \"Ekler\" yukleme ucu (MinIO).","Saha Takip":"Saha Talebi / Saha Takip kaydi (track_data)."},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"POST /api/v1/auth/login yanıtındaki `token` değeri. Swagger UI'da **Authorize** düğmesine yalnızca token yapıştırılır (\"Bearer \" öneki otomatik eklenir)."}},"schemas":{"ErrorResponse":{"type":"object","description":"Tum uclarin ortak hata sozlesmesi (middleware/error.middleware.js + controller katmani).","properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"Bu işlem için yetkiniz yok."},"code":{"type":"string","description":"Yalnizca QR uclarinda doner: QR_INVALID | QR_EXPIRED.","example":"QR_INVALID"}},"required":["success"]},"ValidationErrorResponse":{"type":"object","description":"Girdi dogrulama hatasi (validators/*.validator.js) -- 400 ile doner.","properties":{"success":{"type":"boolean","example":false},"errors":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","example":"organization_id"},"message":{"type":"string","example":"Firma seçin."}}}}},"required":["success","errors"]},"Pagination":{"type":"object","description":"GET /api/v1/users yanitinin sayfalama alanlari (utils/pagination.utils.js). Yanit govdesinde `data` ile AYNI seviyededir, ayri bir nesne DEGILDIR.","properties":{"total":{"type":"integer","example":42},"page":{"type":"integer","example":1},"perPage":{"type":"integer","example":10}}},"User":{"type":"object","description":"Parola ICERMEYEN kullanici goruntusu (toSafeUser).","properties":{"id":{"type":"string","description":"Kullanici kimligi (MongoDB ObjectId, 24 haneli hex).","example":"6a316c105e6b529cde389066"},"username":{"type":"string","example":"ornek.kullanici"},"full_name":{"type":"string","example":"Örnek Kullanıcı"},"email":{"type":"string","format":"email","example":"ornek@example.com"},"phone":{"type":"string","example":"5550000000"},"role":{"type":"string","enum":["admin","organizationadmin","user"],"example":"user"},"status":{"type":"string","enum":["active","passive"],"example":"active"},"company_id":{"type":"string","example":"company-1"},"company_name":{"type":"string","example":"Örnek Firma"},"permissions":{"type":"array","description":"Cozumlenmis izin listesi (utils/permissions.utils.js).","items":{"type":"string"},"example":["support.read","ticket.read","ticket.create"]}}},"LoginRequest":{"type":"object","required":["username","password"],"properties":{"username":{"type":"string","example":"ornek.kullanici"},"password":{"type":"string","format":"password","description":"Ornek deger SAHTEDIR; dokumanda gercek parola YER ALMAZ.","example":"ornek-parola"}}},"LoginResponse":{"type":"object","properties":{"success":{"type":"boolean","example":true},"token":{"type":"string","description":"JWT erisim token'i. Diger korumali uclarda `Authorization: Bearer <token>` olarak gonderilir.","example":"eyJhbGciOiJIUzI1NiJ9.<sahte-ornek-token>.<imza>"},"user":{"$ref":"#/components/schemas/User"}}},"CreateUserRequest":{"type":"object","required":["username","password","full_name","role"],"properties":{"username":{"type":"string","example":"yeni.kullanici"},"password":{"type":"string","format":"password","example":"ornek-parola"},"full_name":{"type":"string","example":"Yeni Kullanıcı"},"email":{"type":"string","format":"email","example":"yeni@example.com"},"phone":{"type":"string","example":"5550000000"},"role":{"type":"string","enum":["admin","organizationadmin","user"],"example":"user"},"status":{"type":"string","enum":["active","passive"],"example":"active"},"company_id":{"type":"string","example":"company-1"},"company_name":{"type":"string","example":"Örnek Firma"},"permissions":{"type":"array","items":{"type":"string"},"example":["support.read","ticket.create"]}}},"UpdateUserRequest":{"type":"object","description":"YALNIZCA gonderilen alanlar guncellenir (validators/users.validator.js). Gonderilmeyen alanlara DOKUNULMAZ.","properties":{"username":{"type":"string","example":"ornek.kullanici"},"password":{"type":"string","format":"password","example":"yeni-ornek-parola"},"full_name":{"type":"string","example":"Örnek Kullanıcı"},"email":{"type":"string","format":"email","example":"ornek@example.com"},"phone":{"type":"string","example":"5550000000"},"role":{"type":"string","enum":["admin","organizationadmin","user"]},"status":{"type":"string","enum":["active","passive"]},"company_id":{"type":"string","example":"company-1"},"company_name":{"type":"string","example":"Örnek Firma"},"permissions":{"type":"array","items":{"type":"string"}}}},"Organization":{"type":"object","description":"Firma/organizasyon goruntusu + hesaplanmis talep istatistigi.","properties":{"id":{"type":"string","description":"Organizasyon kimligi (MongoDB ObjectId, 24 haneli hex).","example":"6a316c105e6b529cde389066"},"companyId":{"type":"string","example":"company-1"},"name":{"type":"string","example":"Örnek Firma"},"city":{"type":"string","example":"Bursa"},"stats":{"type":"object","description":"Talep sayilari -- sunucuda hesaplanir.","properties":{"total":{"type":"integer","example":12},"open":{"type":"integer","example":5},"solved":{"type":"integer","example":7}}}}},"Attachment":{"type":"object","description":"TEK birlesik \"Ekler\" ogesi (resim + video + dokuman ayni listede).","properties":{"url":{"type":"string","format":"uri","example":"https://dosya.ornek.local/support-file/support/örnek/1788000000000_0_a1b2c3_makine.png"},"name":{"type":"string","description":"Kullanicinin YUKLEDIGI gercek dosya adi.","example":"makine-ariza.png"},"kind":{"type":"string","enum":["image","video","document"],"example":"image"},"contentType":{"type":"string","example":"image/png"},"size":{"type":"integer","description":"Bayt.","example":245678},"uploadedAt":{"type":"string","format":"date-time","nullable":true,"description":"Yukleme zamani","example":"2026-09-19T06:29:00.000Z"}}},"SupportRecord":{"type":"object","description":"Destek talebi goruntusu (mapTicket).","properties":{"id":{"type":"string","description":"Talep kimligi (MongoDB ObjectId, 24 haneli hex).","example":"6a316c105e6b529cde389066"},"organizationId":{"type":"string","description":"Organizasyon kimligi (MongoDB ObjectId, 24 haneli hex).","example":"6a316c105e6b529cde389066"},"companyId":{"type":"string","example":"company-1"},"subjectId":{"type":"string","description":"Konu kimligi (MongoDB ObjectId, 24 haneli hex).","example":"6a316c105e6b529cde389066"},"companyName":{"type":"string","example":"Örnek Firma"},"title":{"type":"string","description":"Konu metni (`reason`).","example":"Bakım / destek talebi"},"requestText":{"type":"string","description":"Problem tanimi (`request_reason`).","example":"Hat 3 duruyor, basınç düşüyor."},"aiExplanation":{"type":"string","nullable":true},"solutionPath":{"type":"string","nullable":true},"status":{"type":"string","enum":["open","solved"],"example":"open"},"createdAt":{"type":"string","format":"date-time","nullable":true,"description":"Kayit tarihi","example":"2026-09-19T06:29:00.000Z"},"targetDate":{"type":"string","format":"date-time","nullable":true,"description":"Ongoru/hedef tarihi","example":"2026-09-19T06:29:00.000Z"},"endDate":{"type":"string","format":"date-time","nullable":true,"description":"Bitis (cozum) tarihi","example":"2026-09-19T06:29:00.000Z"},"createdByName":{"type":"string","example":"Örnek Kullanıcı"},"updatedByName":{"type":"string","nullable":true},"submittedAt":{"type":"string","format":"date-time","nullable":true,"description":"Baslangic tarihi","example":"2026-09-19T06:29:00.000Z"},"updatedAt":{"type":"string","format":"date-time","nullable":true,"description":"Son guncelleme","example":"2026-09-19T06:29:00.000Z"},"solvedReason":{"type":"string","nullable":true,"example":"Filtre değiştirildi."},"problemImages":{"type":"array","items":{"type":"string","format":"uri"}},"problemVideos":{"type":"array","items":{"type":"string","format":"uri"}},"solutionImages":{"type":"array","items":{"type":"string","format":"uri"}},"solutionVideos":{"type":"array","items":{"type":"string","format":"uri"}},"problemAttachments":{"type":"array","description":"Talep ekleri -- TEK birlesik liste.","items":{"$ref":"#/components/schemas/Attachment"}},"solutionAttachments":{"type":"array","description":"Cozum ekleri -- TEK birlesik liste.","items":{"$ref":"#/components/schemas/Attachment"}}}},"CreateSupportRecordRequest":{"type":"object","required":["start_date","request_reason"],"description":"Dashboard akisinda `company` da ZORUNLUDUR. QR oturumu (scope=qr) ile gelen isteklerde firma/kullanici GOVDEDEN OKUNMAZ -- QR oturumundan yazilir.","properties":{"company":{"type":"string","example":"Örnek Firma"},"company_ref_id":{"type":"string","example":"company-1"},"organization_id":{"type":"string","description":"Organizasyon kimligi (MongoDB ObjectId, 24 haneli hex).","example":"6a316c105e6b529cde389066"},"company_id":{"type":"string","example":"company-1"},"reason":{"type":"string","description":"Konu metni.","example":"Bakım / destek talebi"},"subject_id":{"type":"string","description":"Mevcut konu kimligi (opsiyonel) (MongoDB ObjectId, 24 haneli hex).","example":"6a316c105e6b529cde389066"},"new_subject":{"type":"string","description":"YALNIZCA \"Diğer\" akisinda; backend find-or-create yapar.","example":"Kalibrasyon talebi"},"start_date":{"type":"string","format":"date-time","example":"2026-09-19T06:29:00.000Z"},"predictive_date":{"type":"string","format":"date-time","example":"2026-09-20T06:29:00.000Z"},"request_reason":{"type":"string","example":"Hat 3 duruyor, basınç düşüyor."},"attachments":{"type":"array","description":"POST /support/files/upload yanitindaki kayitlar OLDUGU GIBI geri gonderilir; `file_url` sunucuda YENIDEN URETILIR.","items":{"$ref":"#/components/schemas/UploadedFile"}}}},"UpdateSupportRecordRequest":{"type":"object","required":["request_reason"],"description":"`solved_reason` ve `solution_date` alanlarindan biri doluysa DIGERI DE ZORUNLUDUR (validators/support.validator.js).","properties":{"reason":{"type":"string","example":"Bakım / destek talebi"},"request_reason":{"type":"string","example":"Hat 3 duruyor, basınç düşüyor."},"predictive_date":{"type":"string","format":"date-time","nullable":true},"solved_reason":{"type":"string","example":"Filtre değiştirildi."},"solution_date":{"type":"string","format":"date-time","example":"2026-09-20T12:00:00.000Z"},"solve_image":{"type":"array","description":"Cozum ekleri (resim) -- yukleme ucundan donen kayitlar.","items":{"$ref":"#/components/schemas/UploadedFile"}},"solve_video":{"type":"array","items":{"$ref":"#/components/schemas/UploadedFile"}},"solve_document":{"type":"array","description":"Cozum ekleri (pdf/word/excel/csv).","items":{"$ref":"#/components/schemas/UploadedFile"}}}},"SupportSubject":{"type":"object","description":"Destek konusu (`support-subject` koleksiyonu, mapSubject).","properties":{"id":{"type":"string","description":"Konu kimligi (MongoDB ObjectId, 24 haneli hex).","example":"6a316c105e6b529cde389066"},"reason":{"type":"string","description":"Konu adi -- dokumandaki GERCEK alan adi `reason`.","example":"Yazıcı arızası"},"companyId":{"type":"string","example":"company-1"},"companyName":{"type":"string","example":"Örnek Firma"}}},"CreateSupportSubjectRequest":{"type":"object","required":["reason"],"properties":{"reason":{"type":"string","example":"Kalibrasyon talebi"},"company_id":{"type":"string","example":"company-1"},"company_name":{"type":"string","example":"Örnek Firma"}}},"QrSessionPrefill":{"type":"object","description":"\"Yeni Talep\" formundan QR oturumuna tasinan ORTAK alanlar. QR URL'inde YER ALMAZ; yalnizca oturum kaydinda durur. Kimlik/firma alani ICERMEZ.","properties":{"subject_ids":{"type":"array","items":{"type":"string","description":"Konu kimligi (MongoDB ObjectId, 24 haneli hex).","example":"6a316c105e6b529cde389066"},"example":["6a316c105e6b529cde389066"]},"other_subject":{"type":"string","example":"Kalibrasyon talebi"},"description":{"type":"string","example":"Hat 3 duruyor, basınç düşüyor."},"start_date":{"type":"string","format":"date-time"},"predictive_date":{"type":"string","format":"date-time"}}},"CreateQrSessionRequest":{"type":"object","required":["organization_id"],"properties":{"organization_id":{"type":"string","description":"QR'in kilitlenecegi organizasyon (MongoDB ObjectId, 24 haneli hex).","example":"6a316c105e6b529cde389066"},"prefill":{"$ref":"#/components/schemas/QrSessionPrefill"}}},"QrSession":{"type":"object","description":"Olusturulan QR oturumu. HAM kod YALNIZCA burada, bir kez doner.","properties":{"code":{"type":"string","description":"Opak kod (crypto.randomBytes(32), base64url). Kimlik bilgisi TASIMAZ.","example":"ornek-opak-kod-degeri-43-karakter-uzunlugunda"},"path":{"type":"string","example":"/q/ornek-opak-kod-degeri"},"expires_at":{"type":"string","format":"date-time"},"ttl_minutes":{"type":"integer","example":10},"session_id":{"type":"string","description":"Oturum kimligi (MongoDB ObjectId, 24 haneli hex).","example":"6a316c105e6b529cde389066"},"organization":{"type":"object","properties":{"id":{"type":"string","description":"Organizasyon kimligi (MongoDB ObjectId, 24 haneli hex).","example":"6a316c105e6b529cde389066"},"name":{"type":"string","example":"Örnek Firma"},"companyId":{"type":"string","example":"company-1"}}}}},"ResolveQrSessionRequest":{"type":"object","required":["code"],"properties":{"code":{"type":"string","description":"QR icindeki opak kod. GET path'inde DEGIL, govdede tasinir.","example":"ornek-opak-kod-degeri-43-karakter-uzunlugunda"}}},"QrSessionContext":{"type":"object","description":"QR formunun (telefon) aldigi baglam. Kullanici kimligi ICERMEZ.","properties":{"token":{"type":"string","description":"Kisa omurlu QR JWT'si (scope=qr, DAR izin kumesi).","example":"eyJhbGciOiJIUzI1NiJ9.<sahte-ornek-token>.<imza>"},"expires_at":{"type":"string","format":"date-time"},"organization":{"type":"object","properties":{"id":{"type":"string","description":"Organizasyon kimligi (MongoDB ObjectId, 24 haneli hex).","example":"6a316c105e6b529cde389066"},"name":{"type":"string","example":"Örnek Firma"}}},"prefill":{"$ref":"#/components/schemas/QrSessionPrefill"}}},"FileUploadRequest":{"type":"object","required":["files"],"description":"Dosyalar base64 `data:` URL olarak JSON govdede tasinir (Platform standardi). multipart/form-data KULLANILMAZ.","properties":{"files":{"type":"array","minItems":1,"items":{"type":"object","required":["name","type","content"],"properties":{"name":{"type":"string","example":"makine-ariza.png"},"type":{"type":"string","example":"image/png"},"content":{"type":"string","description":"data:<mime>;base64,<icerik>","example":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=="}}}},"ticket_id":{"type":"string","description":"YALNIZCA dashboard cozum dosyasi akisinda. Object adinin kapsamini belirler; QR akisinda GONDERILMEZ.","example":"6a316c105e6b529cde389066"}}},"UploadedFile":{"type":"object","description":"Yukleme ucunun DONDURDUGU kayit (services/storage.service.js).","properties":{"bucket":{"type":"string","example":"support-file"},"object_name":{"type":"string","example":"support/6a316c105e6b529cde389066/1788000000000_0_a1b2c3_makine-ariza.png"},"original_name":{"type":"string","example":"makine-ariza.png"},"name":{"type":"string","example":"makine-ariza.png"},"type":{"type":"string","example":"image/png"},"kind":{"type":"string","enum":["image","video","document"],"example":"image"},"size":{"type":"integer","example":245678},"etag":{"type":"string","example":"\"9a0364b9e99bb480dd25e1f0284c8555\""},"file_url":{"type":"string","format":"uri"},"url":{"type":"string","format":"uri"},"uploaded_at":{"type":"string","format":"date-time"}}},"CreateTrackRecordRequest":{"type":"object","required":["subject"],"description":"\"Talep Eden\" ve tarihler GOVDEDEN OKUNMAZ -- dogrulanmis JWT ve sunucu saatinden yazilir.","properties":{"subject":{"type":"string","example":"Kalıp değişim süresi"},"product":{"type":"string","example":"Pres hattı"},"requirement":{"type":"string","example":"Otomatik sayaç entegrasyonu"},"expected_benefit":{"type":"string","example":"Duruş süresinde azalma"},"attachments":{"type":"array","items":{"$ref":"#/components/schemas/UploadedFile"}}}},"TrackRecord":{"type":"object","description":"`track_data` koleksiyonuna yazilan Saha Takip kaydi.","properties":{"id":{"type":"string","description":"Kayit kimligi (MongoDB ObjectId, 24 haneli hex).","example":"6a316c105e6b529cde389066"},"ticket_code":{"type":"string","description":"Atomik sayacla uretilen kod.","example":"SHT-8"},"title":{"type":"string","example":"Kalıp değişim süresi"},"type":{"type":"string","example":"Saha Takip"},"category":{"type":"string","example":"Pres hattı"},"status":{"type":"string","example":"YAPILACAKLAR"},"created_name":{"type":"string","example":"Örnek Kullanıcı"},"created_date":{"type":"string","format":"date-time","nullable":true,"description":"Olusturma zamani","example":"2026-09-19T06:29:00.000Z"},"last_update_date":{"type":"string","format":"date-time","nullable":true,"description":"Son guncelleme","example":"2026-09-19T06:29:00.000Z"},"updated_date":{"type":"string","format":"date-time","nullable":true,"description":"Son guncelleme","example":"2026-09-19T06:29:00.000Z"},"attachment_count":{"type":"integer","example":2},"attachments":{"type":"array","items":{"$ref":"#/components/schemas/UploadedFile"}}}},"HealthResponse":{"type":"object","properties":{"status":{"type":"string","enum":["ok","error"],"example":"ok"},"database":{"type":"string","enum":["connected","disconnected"],"example":"connected"}}}}},"paths":{"/health":{"get":{"tags":["TOTAL APIs","SYSTEM APIs"],"summary":"Servis durumu","description":"Servisin ve MongoDB baglantisinin durumu. KIMLIK DOGRULAMASI GEREKMEZ. Baglanti yoksa 503 doner (controllers/health.controller.js).","operationId":"getHealth","x-iqv-classification":"SYSTEM","x-iqv-domain":"Health","security":[],"responses":{"200":{"description":"Servis ve veritabani ayakta.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}},"503":{"description":"Veritabani baglantisi yok.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}}}}},"/api/v1/auth/login":{"post":{"tags":["TOTAL APIs","SYSTEM APIs"],"summary":"Oturum aç (JWT üret)","description":"Kullanici adi + parola ile JWT uretir. KIMLIK DOGRULAMASI GEREKMEZ -- token BU UCTAN alinir. Pasif hesap veya SUPPORT platform erisimi olmayan hesap 403 alir.","operationId":"login","x-iqv-classification":"SYSTEM","x-iqv-domain":"Auth","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}}},"responses":{"200":{"description":"Giris basarili.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginResponse"}}}},"400":{"description":"Girdi dogrulama hatasi.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"}}}},"401":{"description":"Kullanici adi veya parola hatali.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Hesap pasif veya Support erisimi yok.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Beklenmeyen sunucu hatasi.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/users":{"get":{"tags":["TOTAL APIs","INTERNAL APIs"],"summary":"Kullanıcıları listele","description":"Sayfali kullanici listesi. Sayfalama alanlari yanit govdesinde `data` ile AYNI seviyededir (utils/pagination.utils.js).","operationId":"listUsers","x-iqv-classification":"INTERNAL","x-iqv-domain":"Users","security":[{"bearerAuth":[]}],"parameters":[{"name":"page","in":"query","description":"Sayfa (>= 1, varsayilan 1).","schema":{"type":"integer","minimum":1,"default":1}},{"name":"per_page","in":"query","description":"Sayfa basina kayit (1-100, varsayilan 10). `perPage` ve `limit` de kabul edilir.","schema":{"type":"integer","minimum":1,"maximum":100,"default":10}},{"name":"search","in":"query","description":"Serbest metin aramasi (opsiyonel).","schema":{"type":"string"}}],"responses":{"200":{"description":"Kullanici listesi.","content":{"application/json":{"schema":{"allOf":[{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","description":"Kullanicilar.","items":{"$ref":"#/components/schemas/User"}}}},{"$ref":"#/components/schemas/Pagination"}]}}}},"401":{"description":"Token yok veya gecersiz.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Yetki yok (izin kumesi yetersiz).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Beklenmeyen sunucu hatasi.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["TOTAL APIs","INTERNAL APIs"],"summary":"Kullanıcı oluştur","description":"Yeni kullanici olusturur. `users.create` izni gerekir.","operationId":"createUser","x-iqv-classification":"INTERNAL","x-iqv-domain":"Users","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}}},"responses":{"201":{"description":"Kullanici olusturuldu.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/User"}}}}}},"400":{"description":"Girdi dogrulama hatasi.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"}}}},"401":{"description":"Token yok veya gecersiz.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Yetki yok (izin kumesi yetersiz).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Bu kullanici adi zaten kullaniliyor.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Beklenmeyen sunucu hatasi.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/users/{id}":{"get":{"tags":["TOTAL APIs","INTERNAL APIs"],"summary":"Kullanıcı detayı","description":"Tek kullanici kaydi. `users.read` izni gerekir.","operationId":"getUserById","x-iqv-classification":"INTERNAL","x-iqv-domain":"Users","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"MongoDB ObjectId (24 haneli hex).","schema":{"type":"string","example":"6a316c105e6b529cde389066"}}],"responses":{"200":{"description":"Kullanici kaydi.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/User"}}}}}},"400":{"description":"Girdi dogrulama hatasi.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"}}}},"401":{"description":"Token yok veya gecersiz.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Yetki yok (izin kumesi yetersiz).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Kullanici bulunamadi.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Beklenmeyen sunucu hatasi.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"patch":{"tags":["TOTAL APIs","INTERNAL APIs"],"summary":"Kullanıcı güncelle","description":"YALNIZCA gonderilen alanlar guncellenir; gonderilmeyen alanlara ve diger platform gorunurluklerine DOKUNULMAZ. `users.update` izni gerekir.","operationId":"updateUser","x-iqv-classification":"INTERNAL","x-iqv-domain":"Users","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"MongoDB ObjectId (24 haneli hex).","schema":{"type":"string","example":"6a316c105e6b529cde389066"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserRequest"}}}},"responses":{"200":{"description":"Kullanici guncellendi.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/User"}}}}}},"400":{"description":"Girdi dogrulama hatasi.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"}}}},"401":{"description":"Token yok veya gecersiz.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Yetki yok (izin kumesi yetersiz).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Kullanici bulunamadi.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Bu kullanici adi zaten kullaniliyor.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Beklenmeyen sunucu hatasi.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"tags":["TOTAL APIs","INTERNAL APIs"],"summary":"Kullanıcı sil","description":"Kaydi fiziksel olarak siler. `users.delete` izni gerekir.","operationId":"deleteUser","x-iqv-classification":"INTERNAL","x-iqv-domain":"Users","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"MongoDB ObjectId (24 haneli hex).","schema":{"type":"string","example":"6a316c105e6b529cde389066"}}],"responses":{"200":{"description":"Kullanici silindi.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","nullable":true,"example":null}}}}}},"400":{"description":"Girdi dogrulama hatasi.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"}}}},"401":{"description":"Token yok veya gecersiz.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Yetki yok (izin kumesi yetersiz).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Kullanici bulunamadi.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Beklenmeyen sunucu hatasi.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/support/organizations":{"get":{"tags":["TOTAL APIs","INTERNAL APIs"],"summary":"Firma listesi + talep istatistiği","description":"Firma listesini, her firma icin SUNUCUDA HESAPLANMIS talep istatistigiyle (toplam / acik / cozulmus) birlikte doner -- Destek ve Rapor ekranlarinin islenmis cikti kaynagi. `support.read`, `ticket.read` veya `report.read` izinlerinden HERHANGI biri yeterlidir. QR oturumu bu ucu GOREMEZ (403).","operationId":"listOrganizations","x-iqv-classification":"INTERNAL","x-iqv-domain":"Support Organizations","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Firma listesi.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","description":"Firmalar (istatistikleriyle).","items":{"$ref":"#/components/schemas/Organization"}}}}}}},"401":{"description":"Token yok veya gecersiz.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Yetki yok (izin kumesi yetersiz).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Beklenmeyen sunucu hatasi.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/support/subjects":{"get":{"tags":["TOTAL APIs","INTERNAL APIs"],"summary":"Konuları listele","description":"Destek konulari. Dashboard okuma izinlerine EK OLARAK QR oturumunun `support.qr.read` izni de kabul edilir (QR formunun konu listesi bu uctan gelir).","operationId":"listSubjects","x-iqv-classification":"INTERNAL","x-iqv-domain":"Support Subjects","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Konu listesi.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","description":"Konular.","items":{"$ref":"#/components/schemas/SupportSubject"}}}}}}},"401":{"description":"Token yok veya gecersiz.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Yetki yok (izin kumesi yetersiz).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Beklenmeyen sunucu hatasi.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["TOTAL APIs","INTERNAL APIs"],"summary":"Konu oluştur (\"Diğer\" akışı)","description":"Konu adi zaten varsa YENI KAYIT OLUSTURULMAZ, mevcut kayit doner (find-or-create) -- bu durumda 200, yeni olusturulduysa 201. `ticket.create` izni gerekir; QR oturumu da bu ucu kullanabilir.","operationId":"createSubject","x-iqv-classification":"INTERNAL","x-iqv-domain":"Support Subjects","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSupportSubjectRequest"}}}},"responses":{"200":{"description":"Konu zaten vardi, mevcut kayit dondu.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/SupportSubject"}}}}}},"201":{"description":"Konu olusturuldu.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/SupportSubject"}}}}}},"400":{"description":"Girdi dogrulama hatasi.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"}}}},"401":{"description":"Token yok veya gecersiz.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Yetki yok (izin kumesi yetersiz).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Beklenmeyen sunucu hatasi.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/support/tickets":{"get":{"tags":["TOTAL APIs","INTERNAL APIs"],"summary":"Talepleri listele","description":"Destek taleplerini doner. `organizationId` verilirse yalnizca o firmanin talepleri listelenir. Kullanicinin kapsami disindaki bir firma istenirse 403 doner.","operationId":"listTickets","x-iqv-classification":"INTERNAL","x-iqv-domain":"Support Records","security":[{"bearerAuth":[]}],"parameters":[{"name":"organizationId","in":"query","description":"Firma filtresi (ObjectId). STRING olmak zorundadir.","schema":{"type":"string","example":"6a316c105e6b529cde389066"}}],"responses":{"200":{"description":"Talep listesi.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","description":"Talepler.","items":{"$ref":"#/components/schemas/SupportRecord"}}}}}}},"400":{"description":"Girdi dogrulama hatasi.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"}}}},"401":{"description":"Token yok veya gecersiz.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Yetki yok (izin kumesi yetersiz).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Beklenmeyen sunucu hatasi.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["TOTAL APIs","INTERNAL APIs"],"summary":"Talep oluştur","description":"Yeni destek talebi. `ticket.create` izni gerekir. QR oturumu (scope=qr) ile de cagrilabilir; bu durumda firma/kullanici GOVDEDEN OKUNMAZ, QR oturumundan yazilir ve `company` alani ZORUNLU DEGILDIR. Kayit basarili olduktan sonra Telegram bildirimi best-effort gonderilir (basarisiz olsa bile talep OLUSUR).","operationId":"createTicket","x-iqv-classification":"INTERNAL","x-iqv-domain":"Support Records","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSupportRecordRequest"}}}},"responses":{"201":{"description":"Talep olusturuldu.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/SupportRecord"}}}}}},"400":{"description":"Girdi dogrulama hatasi.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"}}}},"401":{"description":"Token yok veya gecersiz.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Yetki yok (izin kumesi yetersiz).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Beklenmeyen sunucu hatasi.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/support/tickets/{id}":{"put":{"tags":["TOTAL APIs","INTERNAL APIs"],"summary":"Talep güncelle / çözümle","description":"Talep detay ekranindaki \"Güncelle\" ucudur. `solved_reason` ve `solution_date` birlikte gonderilmelidir. ZATEN cozulmus bir talep tekrar cozulemez (409). Cozum ekleri mevcut listeye EKLENIR (overwrite edilmez). Acik -> cozulmus GECISINDE Telegram bildirimi best-effort gonderilir.","operationId":"updateTicket","x-iqv-classification":"INTERNAL","x-iqv-domain":"Support Records","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"MongoDB ObjectId (24 haneli hex).","schema":{"type":"string","example":"6a316c105e6b529cde389066"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSupportRecordRequest"}}}},"responses":{"200":{"description":"Talep guncellendi.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/SupportRecord"}}}}}},"400":{"description":"Girdi dogrulama hatasi.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"}}}},"401":{"description":"Token yok veya gecersiz.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Yetki yok (izin kumesi yetersiz).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Talep bulunamadi.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Talep zaten cozulmus.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Beklenmeyen sunucu hatasi.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/support/qr-sessions":{"post":{"tags":["TOTAL APIs","SYSTEM APIs"],"summary":"QR oturumu oluştur","description":"Dashboard JWT'si ile QR oturumu uretir (`ticket.create` izni). QR oturumu token'i (scope=qr) bu ucu KULLANAMAZ (403). MongoDB'ye kodun YALNIZCA SHA-256 ozeti yazilir; HAM kod yalnizca bu yanitta doner. Istege bagli `prefill` alani \"Yeni Talep\" formundaki ortak alanlari oturuma tasir; bu bilgiler QR URL'ine KONMAZ ve icindeki kimlik/firma alanlari YOK SAYILIR.","operationId":"createQrSession","x-iqv-classification":"SYSTEM","x-iqv-domain":"QR Sessions","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateQrSessionRequest"}}}},"responses":{"201":{"description":"QR oturumu olusturuldu.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/QrSession"}}}}}},"400":{"description":"Girdi dogrulama hatasi.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"}}}},"401":{"description":"Token yok veya gecersiz.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Yetki yok (izin kumesi yetersiz).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Firma bulunamadi.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Beklenmeyen sunucu hatasi.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/support/qr-sessions/resolve":{"post":{"tags":["TOTAL APIs","EXTERNAL APIs"],"summary":"QR kodunu çözümle (auth YOK)","description":"QR'i okutan cihazda oturum bulunmaz -- bu uc KIMLIK DOGRULAMASI ISTEMEZ. Kod GET path'inde degil GOVDEDE tasinir (erisim loglarina/Referer'a dusmesin diye). Basarili olursa kisa omurlu, DAR izinli bir QR JWT'si doner. Gecersiz/iptal kod 404 (QR_INVALID), suresi dolmus oturum 410 (QR_EXPIRED) alir.","operationId":"resolveQrSession","x-iqv-classification":"EXTERNAL","x-iqv-domain":"QR Sessions","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResolveQrSessionRequest"}}}},"responses":{"200":{"description":"QR oturumu cozuldu.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/QrSessionContext"}}}}}},"404":{"description":"Bu QR kodu gecersizdir (QR_INVALID).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"410":{"description":"Bu QR kodunun suresi dolmustur (QR_EXPIRED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Beklenmeyen sunucu hatasi.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/support/files/upload":{"post":{"tags":["TOTAL APIs","INTERNAL APIs"],"summary":"Ek dosya yükle (tek birleşik \"Ekler\")","description":"Resim, video ve dokuman (PDF / Word / Excel / CSV / TXT) AYNI uctan yuklenir -- ayri resim/video ucu YOKTUR.\n\nGOVDE BICIMI: multipart/form-data DEGIL, JSON icinde base64 `data:` URL (IQV Platform standardi).\n\nDESTEKLENEN UZANTILAR: .png .jpg .jpeg .webp .gif | .mp4 .webm .mov .m4v .mkv .3gp | .pdf .doc .docx .xls .xlsx .csv .txt\n\nBOYUT SINIRLARI (backend varsayilanlari, .env ile degistirilebilir): resim 20 MB, dokuman 20 MB, video 20 MB (SUPPORT_UPLOAD_MAX_VIDEO_BYTES ile yukseltilebilir), toplam 60 MB. Adet: 5 resim + 1 video + 5 dokuman. Sinir asilirsa 413 doner.\n\nYETKI: dashboard JWT'si (`ticket.create`) VEYA QR oturumu token'i (`ticket.upload`). Bucket ve object adi SUNUCUDA belirlenir; istemci secemez (path traversal engellenir).","operationId":"uploadFiles","x-iqv-classification":"INTERNAL","x-iqv-domain":"Attachments","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileUploadRequest"}}}},"responses":{"200":{"description":"Dosyalar yuklendi.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"files":{"type":"array","items":{"$ref":"#/components/schemas/UploadedFile"}}}}}}},"400":{"description":"Gecersiz govde, izinsiz MIME veya uzanti, adet siniri asimi.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Token yok veya gecersiz.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Yetki yok (izin kumesi yetersiz).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"410":{"description":"QR oturumunun suresi dolmus (QR_EXPIRED).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Dosya boyutu sinirini asiyor.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Beklenmeyen sunucu hatasi.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/track/records":{"post":{"tags":["TOTAL APIs","INTERNAL APIs"],"summary":"Saha Talebi oluştur","description":"Kaydi `track_data` koleksiyonuna yazar; `ticket_code` (SHT-N) ATOMIK sayacla uretilir. \"Talep Eden\" ve tarihler GOVDEDEN OKUNMAZ -- dogrulanmis JWT ve sunucu saatinden yazilir. `ticket.create` izni gerekir; QR oturumu bu ucu KULLANAMAZ. Telegram bildirimi kayit yazildiktan SONRA best-effort gonderilir.","operationId":"createTrackRecord","x-iqv-classification":"INTERNAL","x-iqv-domain":"Saha Takip","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTrackRecordRequest"}}}},"responses":{"201":{"description":"Saha talebi olusturuldu.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/TrackRecord"}}}}}},"400":{"description":"Girdi dogrulama hatasi.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"}}}},"401":{"description":"Token yok veya gecersiz.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Yetki yok (izin kumesi yetersiz).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Beklenmeyen sunucu hatasi.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}