{"openapi":"3.0.0","paths":{"/api/v1/healthz":{"get":{"operationId":"HealthController_liveness","parameters":[],"responses":{"200":{"description":""}},"summary":"Liveness probe","tags":["health"]}},"/api/v1/readyz":{"get":{"operationId":"HealthController_readiness","parameters":[],"responses":{"200":{"description":""}},"summary":"Readiness probe — DB/Valkey bağımlılıkları (R2/Zitadel sonraki görevde)","tags":["health"]}},"/api/v1/status":{"get":{"operationId":"StatusController_getSummary","parameters":[],"responses":{"200":{"description":""}},"summary":"[Public] Bileşen durumları (son check) + son 90 günün günlük uptime yüzdesi","tags":["status"]}},"/api/v1/tenants/{id}/billing-profile":{"get":{"operationId":"BillingProfileController_getProfile","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Fatura profili (owner/admin) — kayıtlı değilse 404","tags":["billing"]},"post":{"operationId":"BillingProfileController_saveProfile","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaveBillingProfileDto"}}}},"responses":{"201":{"description":""}},"summary":"Fatura profilini kaydet/güncelle (upsert, owner/admin) — audit_log üretir","tags":["billing"]}},"/api/v1/tenants/{id}/checkout":{"post":{"operationId":"CheckoutController_createCheckout","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCheckoutDto"}}}},"responses":{"201":{"description":""}},"summary":"Whop checkout başlat (owner/admin) — fatura profili kayıtlı olmalı (yoksa 409)","tags":["billing"]}},"/api/v1/webhooks/whop":{"post":{"operationId":"WhopWebhookController_receive","parameters":[],"responses":{"200":{"description":""}},"summary":"Whop webhook alıcısı (Standard Webhooks imza doğrulaması + idempotent işleme)","tags":["webhooks"]}},"/api/v1/billing/plans":{"get":{"operationId":"PlansController_getPlans","parameters":[],"responses":{"200":{"description":""}},"summary":"Plan kataloğu (planKey/cycle/currency/amountMinor/KDV) — public","tags":["billing"]}},"/api/v1/tenants/{id}/refund-requests":{"post":{"operationId":"RefundRequestsController_create","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRefundRequestDto"}}}},"responses":{"201":{"description":""}},"summary":"İade talebi aç (owner/admin) — abonelik verilmezse mevcut abonelik kullanılır","tags":["billing"]},"get":{"operationId":"RefundRequestsController_list","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"İade taleplerini listele (owner/admin, cursor sayfalama + durum filtresi)","tags":["billing"]}},"/api/v1/tenants/{id}/refund-requests/{refundRequestId}/approve":{"post":{"operationId":"RefundRequestsController_approve","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"refundRequestId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"summary":"İade talebini onayla — Whop POST /payments/{id}/refund çağrılır (owner/admin)","tags":["billing"]}},"/api/v1/tenants/{id}/refund-requests/{refundRequestId}/reject":{"post":{"operationId":"RefundRequestsController_reject","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"refundRequestId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RejectRefundRequestDto"}}}},"responses":{"201":{"description":""}},"summary":"İade talebini reddet (owner/admin) — Whop’a dokunulmaz","tags":["billing"]}},"/api/v1/tenants/{id}/invoices":{"get":{"operationId":"InvoicesController_list","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Fatura listesi (cursor sayfalama + tarih aralığı/durum filtresi)","tags":["billing"]}},"/api/v1/tenants/{id}/invoices/{invoiceId}/download":{"get":{"operationId":"InvoicesController_download","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"invoiceId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Presigned GET URL üret ({ downloadUrl }) — draft (PDF yok) faturalarda 404","tags":["billing"]}},"/api/v1/tenants/{id}/entitlements":{"get":{"operationId":"TenantEntitlementsController_getEntitlements","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Plan yetenekleri — kaynak `EntitlementsService.getEntitlements` (remote-config override’a tabi).","content":{"application/json":{"schema":{"type":"object","required":["planKey","maxTeams","maxMembers","maxIssues","allowGuests","attachmentMaxSizeMb","whiteLabel","sso","apiAccess","insights","sla"],"properties":{"planKey":{"type":"string","enum":["free","team","business","enterprise"]},"maxTeams":{"type":"integer","nullable":true},"maxMembers":{"type":"integer","nullable":true},"maxIssues":{"type":"integer","nullable":true},"allowGuests":{"type":"boolean"},"attachmentMaxSizeMb":{"type":"integer","nullable":true},"whiteLabel":{"type":"boolean"},"sso":{"type":"boolean"},"apiAccess":{"type":"boolean"},"insights":{"type":"boolean"},"sla":{"type":"boolean"}}}}}}},"summary":"Tenant’ın KENDİ planının yetenek/kota tablosu ({ planKey, whiteLabel, sso, apiAccess, insights, sla, maxTeams, maxMembers, maxIssues, allowGuests, attachmentMaxSizeMb }) — TÜM üyeler okuyabilir; kotalarda null = SINIRSIZ","tags":["billing"]}},"/api/v1/me":{"patch":{"operationId":"MeController_updateMe","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMeDto"}}}},"responses":{"200":{"description":""}},"summary":"Görünen adı ayarla/temizle (kimlik sağlayıcı senkronu bu alanı EZMEZ)","tags":["me"]},"get":{"operationId":"MeController_me","parameters":[],"responses":{"200":{"description":""}},"summary":"Oturum sahibi kullanıcı + üye olduğu tenant listesi (davet aktivasyonunu da tetikler)","tags":["me"]}},"/api/v1/me/avatar/presign":{"post":{"operationId":"MeController_presignAvatar","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PresignAvatarDto"}}}},"responses":{"201":{"description":""}},"summary":"Avatar yüklemesi için imzalı PUT üret (dosya doğrudan R2’ye gider)","tags":["me"]}},"/api/v1/tenants":{"post":{"operationId":"TenantsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTenantDto"}}}},"responses":{"201":{"description":""}},"summary":"Yeni tenant oluştur (çağıran owner olur)","tags":["tenants"]}},"/api/v1/tenants/{id}":{"get":{"operationId":"TenantsController_getById","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Tenant detayı (x-tenant-id header ile üyelik doğrulanır)","tags":["tenants"]},"patch":{"operationId":"TenantsController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTenantDto"}}}},"responses":{"200":{"description":""}},"summary":"Tenant adını güncelle (owner/admin) — audit_log kaydı üretir","tags":["tenants"]}},"/api/v1/tenants/{id}/theme":{"get":{"operationId":"TenantThemeController_getTheme","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"White-label tema (productName/primaryColor/logoUrl) — tüm tenant üyeleri okuyabilir","tags":["tenant-theme"]},"post":{"operationId":"TenantThemeController_saveTheme","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaveTenantThemeDto"}}}},"responses":{"201":{"description":""}},"summary":"Temayı kaydet (owner/admin) — alan gönderilmezse dokunulmaz, null gönderilirse temizlenir","tags":["tenant-theme"]}},"/api/v1/tenants/{id}/theme/logo/presign":{"post":{"operationId":"TenantThemeController_presignLogo","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PresignTenantLogoDto"}}}},"responses":{"201":{"description":""}},"summary":"Logo için presigned PUT URL üret (R2’ye doğrudan yükleme) — { uploadUrl, r2Key }","tags":["tenant-theme"]}},"/api/v1/tenants/{id}/custom-domains":{"get":{"operationId":"CustomDomainsController_listDomains","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Kayıtlı alan adları","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","required":["id","domain","status","txtRecordName","txtRecordValue","verifiedAt","lastCheckedAt","lastFailureReason"],"properties":{"id":{"type":"string","format":"uuid"},"domain":{"type":"string"},"status":{"type":"string","enum":["pending","active","failed"]},"txtRecordName":{"type":"string"},"txtRecordValue":{"type":"string"},"verifiedAt":{"type":"string","format":"date-time","nullable":true},"lastCheckedAt":{"type":"string","format":"date-time","nullable":true},"lastFailureReason":{"type":"string","enum":["txt-record-not-found","txt-record-mismatch","dns-lookup-failed"],"nullable":true}}}}}}}},"summary":"Özel alan adları + DNS TXT doğrulama talimatı (tüm tenant üyeleri okuyabilir). ⚠️ Doğrulanmış bir alan adına BUGÜN trafik YÖNLENDİRİLMEZ — kayıt yalnız saklanır.","tags":["custom-domains"]},"post":{"operationId":"CustomDomainsController_addDomain","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomDomainDto"}}}},"responses":{"201":{"description":"Eklendi (pending)","content":{"application/json":{"schema":{"type":"object","required":["id","domain","status","txtRecordName","txtRecordValue","verifiedAt","lastCheckedAt","lastFailureReason"],"properties":{"id":{"type":"string","format":"uuid"},"domain":{"type":"string"},"status":{"type":"string","enum":["pending","active","failed"]},"txtRecordName":{"type":"string"},"txtRecordValue":{"type":"string"},"verifiedAt":{"type":"string","format":"date-time","nullable":true},"lastCheckedAt":{"type":"string","format":"date-time","nullable":true},"lastFailureReason":{"type":"string","enum":["txt-record-not-found","txt-record-mismatch","dns-lookup-failed"],"nullable":true}}}}}},"400":{"description":"Geçersiz hostname, IP adresi, ASCII olmayan girdi, public olmayan son ek VEYA platforma ayrılmış (rezerve) alan adı"},"403":{"description":"White-label yetkisi yok (Business+ gerekir) ya da rol yetersiz"},"409":{"description":"Alan adı zaten kayıtlı (GLOBAL benzersiz) ya da tenant başına üst sınıra ulaşıldı"}},"summary":"Özel alan adı ekle (owner/admin, Business+). Yanıt, tenant’ın yayınlaması gereken TXT kaydının adını ve değerini taşır; kayıt `pending` olarak başlar.","tags":["custom-domains"]}},"/api/v1/tenants/{id}/custom-domains/{domainId}/verify":{"post":{"operationId":"CustomDomainsController_verifyDomain","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"domainId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":"Doğrulama çalıştı — `status` ve `lastFailureReason` sonucu taşır","content":{"application/json":{"schema":{"type":"object","required":["id","domain","status","txtRecordName","txtRecordValue","verifiedAt","lastCheckedAt","lastFailureReason"],"properties":{"id":{"type":"string","format":"uuid"},"domain":{"type":"string"},"status":{"type":"string","enum":["pending","active","failed"]},"txtRecordName":{"type":"string"},"txtRecordValue":{"type":"string"},"verifiedAt":{"type":"string","format":"date-time","nullable":true},"lastCheckedAt":{"type":"string","format":"date-time","nullable":true},"lastFailureReason":{"type":"string","enum":["txt-record-not-found","txt-record-mismatch","dns-lookup-failed"],"nullable":true}}}}}}},"summary":"DNS TXT sahiplik doğrulamasını ÇALIŞTIR (owner/admin, Business+). BAŞARISIZLIK 4xx DEĞİLDİR: uç 200 döner, satır `failed` + `lastFailureReason` taşır.","tags":["custom-domains"]}},"/api/v1/tenants/{id}/custom-domains/{domainId}":{"delete":{"operationId":"CustomDomainsController_removeDomain","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"domainId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":"Silindi"}},"summary":"Özel alan adını sil (owner/admin). Entitlement GEREKTİRMEZ — plan düşen bir tenant kaydını kaldırabilmeli, aksi hâlde GLOBAL benzersiz alan adı süresiz işgal edilirdi.","tags":["custom-domains"]}},"/api/v1/domain-check":{"get":{"operationId":"PublicDomainCheckController_check","parameters":[{"name":"domain","required":false,"in":"query","schema":{"type":"string"},"description":"Kontrol edilecek hostname (Caddy `on_demand_tls ask` bunu otomatik ekler)"}],"responses":{"204":{"description":"İzin var — hostname `active` ve doğrulaması taze"},"404":{"description":"İzin yok. Sebep AYRIŞTIRILAMAZ (bilerek): bilinmeyen/pending/failed/bayat/geçersiz girdi hepsi AYNI yanıttır"}},"summary":"[Public] Bir hostname’in servis edilmeye yetkili olup olmadığı. 204 = izin var; DİĞER HER DURUM (bilinmeyen/pending/failed/bayat/geçersiz/eksik parametre) AYNI 404’tür. Gövde YOKTUR — tenant kimliği DÖNMEZ. ⚠️ Bu ucu bugün hiçbir istemci çağırmaz.","tags":["custom-domains"]}},"/api/v1/tenants/{id}/session-handoff":{"post":{"operationId":"SessionHandoffController_issue","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssueSessionHandoffDto"}}}},"responses":{"201":{"description":"Devir jetonu üretildi","content":{"application/json":{"schema":{"type":"object","required":["token","expiresAt"],"properties":{"token":{"type":"string","description":"`base64url(payload).base64url(HMAC-SHA256)` — `POST /session-handoff/redeem` gövdesine konur"},"expiresAt":{"type":"string","format":"date-time","description":"Jetonun son geçerlilik anı (UTC, ISO-8601)"}}}}}},"403":{"description":"White-label yetkisi yok (Business+ gerekir)"},"404":{"description":"Alan adı bu tenant’a ait değil, `active` değil ya da doğrulaması bayat. Sebep AYRIŞTIRILAMAZ (bilerek)"},"503":{"description":"Oturum devri bu kurulumda yapılandırılmamış (`SESSION_HANDOFF_SECRET` yok) — özellik KAPALI"}},"summary":"Özel alan adına OTURUM DEVRİ jetonu üret (tenant üyesi, Business+). Jeton TEK KULLANIMLIK ve 30 saniyeliktir. ⚠️ Bu ucu bugün hiçbir istemci çağırmaz; jeton bir OTURUM değil, doğrulanmış bir KİMLİK İDDİASI üretir.","tags":["custom-domains"]}},"/api/v1/session-handoff/redeem":{"post":{"operationId":"PublicSessionHandoffController_redeem","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedeemSessionHandoffDto"}}}},"responses":{"200":{"description":"Jeton tüketildi — doğrulanmış kimlik iddiası","content":{"application/json":{"schema":{"type":"object","required":["userId","tenantId","domain"],"properties":{"userId":{"type":"string","format":"uuid"},"tenantId":{"type":"string","format":"uuid"},"domain":{"type":"string","description":"`Host` ile eşleşmesi DOĞRULANMIŞ kanonik hostname"}}}}}},"401":{"description":"Jeton reddedildi. Sebep AYRIŞTIRILAMAZ (bilerek) — oracle olmasın diye tek tip yanıt"},"503":{"description":"Oturum devri bu kurulumda yapılandırılmamış (`SESSION_HANDOFF_SECRET` yok) — özellik KAPALI"}},"summary":"[Public] Oturum devri jetonunu TÜKET (tek kullanımlık). 200 = doğrulanmış kimlik iddiası; DİĞER HER DURUM (süresi geçmiş/imzası bozuk/zaten kullanılmış/`Host` uyuşmuyor/üyelik yok) AYNI 401’dir. ⚠️ Çerez YAZILMAZ, oturum KURULMAZ. Bu ucu bugün hiçbir istemci çağırmaz.","tags":["custom-domains"]}},"/api/v1/tenants/{id}/invites":{"post":{"operationId":"InvitesController_create","parameters":[{"name":"id","required":true,"in":"path","description":"Tenant id (x-tenant-id header ile eşleşmeli)","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInviteDto"}}}},"responses":{"201":{"description":""}},"summary":"Tenant’a e-posta ile üye davet et (owner/admin)","tags":["invites"]},"get":{"operationId":"InvitesController_list","parameters":[{"name":"id","required":true,"in":"path","description":"Tenant id (x-tenant-id header ile eşleşmeli)","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Bekleyen/kabul edilmiş davetleri listele (owner/admin, cursor sayfalama + status filtresi)","tags":["invites"]}},"/api/v1/tenants/{id}/invites/{inviteId}":{"delete":{"operationId":"InvitesController_cancel","parameters":[{"name":"id","required":true,"in":"path","description":"Tenant id (x-tenant-id header ile eşleşmeli)","schema":{"type":"string"}},{"name":"inviteId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"summary":"Bekleyen bir daveti iptal et (owner/admin)","tags":["invites"]}},"/api/v1/tenants/{id}/invites/{inviteId}/resend":{"post":{"operationId":"InvitesController_resend","parameters":[{"name":"id","required":true,"in":"path","description":"Tenant id (x-tenant-id header ile eşleşmeli)","schema":{"type":"string"}},{"name":"inviteId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"summary":"Bekleyen davetin Zitadel e-postasını yeniden gönder (owner/admin) — F4i","tags":["invites"]}},"/api/v1/tenants/{id}/invite-link":{"get":{"operationId":"InviteLinkController_get","parameters":[{"name":"id","required":true,"in":"path","description":"Tenant id (x-tenant-id header ile eşleşmeli)","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Davet bağlantısını ve onaylı alan adlarını getir (owner/admin)","tags":["invites"]},"post":{"operationId":"InviteLinkController_rotate","parameters":[{"name":"id","required":true,"in":"path","description":"Tenant id (x-tenant-id header ile eşleşmeli)","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RotateInviteLinkDto"}}}},"responses":{"201":{"description":""}},"summary":"Davet bağlantısını aç ya da döndür (owner/admin) — önceki bağlantı geçersizleşir","tags":["invites"]},"delete":{"operationId":"InviteLinkController_disable","parameters":[{"name":"id","required":true,"in":"path","description":"Tenant id (x-tenant-id header ile eşleşmeli)","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"summary":"Davet bağlantısını kapat (owner/admin) — ANINDA geçersiz olur","tags":["invites"]}},"/api/v1/tenants/{id}/invite-link/approved-domains":{"patch":{"operationId":"InviteLinkController_setApprovedDomains","parameters":[{"name":"id","required":true,"in":"path","description":"Tenant id (x-tenant-id header ile eşleşmeli)","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetApprovedDomainsDto"}}}},"responses":{"200":{"description":""}},"summary":"Onaylı e-posta alan adlarını AYARLA (owner/admin) — boş dizi kısıtı kaldırır","tags":["invites"]}},"/api/v1/invite-links/{token}/join":{"post":{"operationId":"InviteLinkJoinController_join","parameters":[{"name":"token","required":true,"in":"path","description":"Davet bağlantısındaki token","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"summary":"Davet bağlantısıyla çalışma alanına katıl (giriş yapmış kullanıcı)","tags":["invites"]}},"/api/v1/tenants/{id}/members":{"get":{"operationId":"MembersController_list","parameters":[{"name":"id","required":true,"in":"path","description":"Tenant id (x-tenant-id header ile eşleşmeli)","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Üye listesi (cursor sayfalama + rol/status filtresi, TÜM üyelere açık)","tags":["members"]}},"/api/v1/tenants/{id}/members/export":{"get":{"operationId":"MembersController_exportCsv","parameters":[{"name":"id","required":true,"in":"path","description":"Tenant id (x-tenant-id header ile eşleşmeli)","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Üye listesi CSV export’u (text/csv, attachment). Sayfalama YOK; sonuç 10.000 satırı aşarsa 400 döner — YARIM DOSYA ÜRETİLMEZ.","tags":["members"]}},"/api/v1/tenants/{id}/members/{memberId}":{"patch":{"operationId":"MembersController_updateRole","parameters":[{"name":"id","required":true,"in":"path","description":"Tenant id (x-tenant-id header ile eşleşmeli)","schema":{"type":"string"}},{"name":"memberId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMemberDto"}}}},"responses":{"200":{"description":""}},"summary":"Üyenin rolünü değiştir (owner/admin; son owner’ın rolü düşürülemez)","tags":["members"]},"delete":{"operationId":"MembersController_remove","parameters":[{"name":"id","required":true,"in":"path","description":"Tenant id (x-tenant-id header ile eşleşmeli)","schema":{"type":"string"}},{"name":"memberId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"summary":"Üyeyi tenant’tan çıkar (owner/admin; son owner çıkarılamaz)","tags":["members"]}},"/api/v1/auth/urls":{"get":{"operationId":"AuthUrlsController_getUrls","parameters":[{"name":"email","required":false,"in":"query","description":"Opsiyonel — verilirse domaini eşleşen tenant SSO org’una yönlendirilir (yoksa paylaşılan org).","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Web’in kullanacağı Zitadel hosted login URL kalıpları (login/register/password-reset)","tags":["auth"]}},"/api/v1/teams":{"post":{"operationId":"TeamsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTeamDto"}}}},"responses":{"201":{"description":""}},"summary":"Yeni takım oluştur (varsayılan workflow state seti seed edilir, yaratan owner olur)","tags":["teams"]},"get":{"operationId":"TeamsController_list","parameters":[],"responses":{"200":{"description":""}},"summary":"Takım listesi (cursor sayfalama + arama; varsayılan arşivlenmişleri gizler)","tags":["teams"]}},"/api/v1/teams/{teamId}":{"get":{"operationId":"TeamsController_getById","parameters":[{"name":"teamId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Takım detayı","tags":["teams"]},"patch":{"operationId":"TeamsController_update","parameters":[{"name":"teamId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTeamDto"}}}},"responses":{"200":{"description":""}},"summary":"Takım adı/key’i değiştir (key değişimi mevcut issue identifier’larını ETKİLEMEZ)","tags":["teams"]},"delete":{"operationId":"TeamsController_archive","parameters":[{"name":"teamId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"summary":"Takımı arşivle (soft — archived_at)","tags":["teams"]}},"/api/v1/teams/{teamId}/members":{"get":{"operationId":"TeamMembersController_list","parameters":[{"name":"teamId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Takım üyelerini listele (cursor sayfalama)","tags":["team-members"]},"post":{"operationId":"TeamMembersController_add","parameters":[{"name":"teamId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddTeamMemberDto"}}}},"responses":{"201":{"description":""}},"summary":"Takıma üye ekle (kullanıcı zaten tenant üyesi olmalı)","tags":["team-members"]}},"/api/v1/teams/{teamId}/members/{memberId}":{"delete":{"operationId":"TeamMembersController_remove","parameters":[{"name":"teamId","required":true,"in":"path","schema":{"type":"string"}},{"name":"memberId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"summary":"Takım üyeliğini kaldır","tags":["team-members"]}},"/api/v1/teams/{teamId}/workflow-states":{"get":{"operationId":"WorkflowStatesController_list","parameters":[{"name":"teamId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Takımın workflow state’lerini (board sütunları) position sırasına göre listele","tags":["workflow-states"]},"post":{"operationId":"WorkflowStatesController_create","parameters":[{"name":"teamId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWorkflowStateDto"}}}},"responses":{"201":{"description":""}},"summary":"Yeni bir workflow state ekle (listenin sonuna yerleşir)","tags":["workflow-states"]}},"/api/v1/teams/{teamId}/workflow-states/{stateId}":{"patch":{"operationId":"WorkflowStatesController_update","parameters":[{"name":"teamId","required":true,"in":"path","schema":{"type":"string"}},{"name":"stateId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWorkflowStateDto"}}}},"responses":{"200":{"description":""}},"summary":"Workflow state adı/kategorisi/rengini güncelle","tags":["workflow-states"]},"delete":{"operationId":"WorkflowStatesController_remove","parameters":[{"name":"teamId","required":true,"in":"path","schema":{"type":"string"}},{"name":"stateId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"summary":"Workflow state’i sil (bağlı issue’lar moveIssuesTo’ya taşınır; kategori başına en az 1 state korunur)","tags":["workflow-states"]}},"/api/v1/teams/{teamId}/workflow-states/{stateId}/reorder":{"patch":{"operationId":"WorkflowStatesController_reorder","parameters":[{"name":"teamId","required":true,"in":"path","schema":{"type":"string"}},{"name":"stateId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReorderWorkflowStateDto"}}}},"responses":{"200":{"description":""}},"summary":"Workflow state’i yeniden sırala (fractional position — beforeId/afterId komşuları)","tags":["workflow-states"]}},"/api/v1/webhooks":{"post":{"operationId":"WebhooksController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookEndpointDto"}}}},"responses":{"201":{"description":""}},"summary":"Yeni webhook endpoint’i oluştur (owner/admin, Business+) — imza sırrı SADECE bu yanıtta bir kez döner","tags":["webhooks"]},"get":{"operationId":"WebhooksController_list","parameters":[],"responses":{"200":{"description":""}},"summary":"Webhook endpoint listesi (owner/admin) — imza sırrı ASLA dönmez","tags":["webhooks"]}},"/api/v1/webhooks/{webhookId}":{"get":{"operationId":"WebhooksController_getById","parameters":[{"name":"webhookId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Webhook endpoint detayı (owner/admin)","tags":["webhooks"]},"patch":{"operationId":"WebhooksController_update","parameters":[{"name":"webhookId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWebhookEndpointDto"}}}},"responses":{"200":{"description":""}},"summary":"Webhook endpoint güncelle (owner/admin, Business+) — status=active hata sayacını SIFIRLAR","tags":["webhooks"]},"delete":{"operationId":"WebhooksController_remove","parameters":[{"name":"webhookId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"summary":"Webhook endpoint’i sil (owner/admin, Business+) — teslimat geçmişi de silinir","tags":["webhooks"]}},"/api/v1/webhooks/{webhookId}/rotate-secret":{"post":{"operationId":"WebhooksController_rotateSecret","parameters":[{"name":"webhookId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"summary":"İmza sırrını döndür (owner/admin, Business+) — yeni sır SADECE bu yanıtta bir kez döner","tags":["webhooks"]}},"/api/v1/webhooks/{webhookId}/test":{"post":{"operationId":"WebhooksController_sendTest","parameters":[{"name":"webhookId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"summary":"Test teslimatı gönder (owner/admin, Business+, 5/dk) — `webhook.test` olayı, event filtresine BAKILMAZ","tags":["webhooks"]}},"/api/v1/webhooks/{webhookId}/deliveries":{"get":{"operationId":"WebhooksController_listDeliveries","parameters":[{"name":"webhookId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Teslimat geçmişi (owner/admin) — en yeni önce, cursor sayfalama, ?status ile filtre","tags":["webhooks"]}},"/api/v1/notifications":{"get":{"operationId":"NotificationsController_list","parameters":[],"responses":{"200":{"description":""}},"summary":"Bildirim inbox’ı (en yeni önce; ?unreadOnly ile yalnız okunmamışlar; cursor sayfalama)","tags":["notifications"]}},"/api/v1/notifications/unread-count":{"get":{"operationId":"NotificationsController_unreadCount","parameters":[],"responses":{"200":{"description":""}},"summary":"Okunmamış bildirim sayısı (zil rozeti)","tags":["notifications"]}},"/api/v1/notifications/preferences":{"get":{"operationId":"NotificationsController_getPreferences","parameters":[],"responses":{"200":{"description":""}},"summary":"Bildirim tercihleri (çağıranın KENDİ üyeliği) — e-posta kapısı","tags":["notifications"]},"patch":{"operationId":"NotificationsController_updatePreferences","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateNotificationPreferencesDto"}}}},"responses":{"200":{"description":""}},"summary":"E-posta bildirim tercihini güncelle (yalnız kendi üyeliği; in-app bildirimler etkilenmez)","tags":["notifications"]}},"/api/v1/notifications/{notificationId}/read":{"patch":{"operationId":"NotificationsController_markRead","parameters":[{"name":"notificationId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Bildirimi okundu işaretle (SADECE kendi bildirimi — aksi halde 404)","tags":["notifications"]}},"/api/v1/notifications/read-all":{"post":{"operationId":"NotificationsController_markAllRead","parameters":[],"responses":{"200":{"description":""}},"summary":"Tüm okunmamış bildirimleri okundu işaretle","tags":["notifications"]}},"/api/v1/notifications/{notificationId}/snooze":{"patch":{"operationId":"NotificationsController_snooze","parameters":[{"name":"notificationId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SnoozeNotificationDto"}}}},"responses":{"200":{"description":""}},"summary":"Bildirimi ertele ya da ertelemeyi kaldır (yalnız çağıranın kendi bildirimi)","tags":["notifications"]}},"/api/v1/issues":{"post":{"operationId":"IssuesController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIssueDto"}}}},"responses":{"201":{"description":""}},"summary":"Yeni issue oluştur (identifier atomik artan next_issue_number’dan türetilir)","tags":["issues"]},"get":{"operationId":"IssuesController_list","parameters":[],"responses":{"200":{"description":""}},"summary":"Issue listesi (cursor sayfalama + filtreler: team/state/stateType/assignee/priority/label/project/parent/q/subscribedByMe)","tags":["issues"]}},"/api/v1/issues/{issueId}":{"get":{"operationId":"IssuesController_getById","parameters":[{"name":"issueId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Issue detayı (identifier + labelIds + alt-issue roll-up + isSubscribed)","tags":["issues"]},"patch":{"operationId":"IssuesController_update","parameters":[{"name":"issueId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateIssueDto"}}}},"responses":{"200":{"description":""}},"summary":"Issue güncelle (state/assignee/priority değişimi otomatik activity kaydı üretir)","tags":["issues"]},"delete":{"operationId":"IssuesController_archive","parameters":[{"name":"issueId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"summary":"Issue’ı arşivle (soft — archived_at) + activity kaydı","tags":["issues"]}},"/api/v1/issues/{issueId}/reminder":{"post":{"operationId":"IssuesController_setReminder","parameters":[{"name":"issueId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetIssueReminderDto"}}}},"responses":{"201":{"description":""}},"summary":"Issue hatırlatıcısı kur/ötele (çağıranın kendisi için)","tags":["issues"]},"get":{"operationId":"IssuesController_getReminder","parameters":[{"name":"issueId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Bu issue’daki BEKLEYEN hatırlatıcım (yoksa `remindAt: null`)","tags":["issues"]},"delete":{"operationId":"IssuesController_clearReminder","parameters":[{"name":"issueId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"summary":"Bekleyen hatırlatıcıyı kaldır","tags":["issues"]}},"/api/v1/issues/{issueId}/subscription":{"post":{"operationId":"IssuesController_setSubscription","parameters":[{"name":"issueId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetIssueSubscriptionDto"}}}},"responses":{"201":{"description":""}},"summary":"Issue aboneliğini aç/kapat (çağıranın kendisi için)","tags":["issues"]}},"/api/v1/issues/{issueId}/children":{"get":{"operationId":"IssuesController_listChildren","parameters":[{"name":"issueId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Bir issue’ın alt-issue’ları (sub-issues) — cursor sayfalı","tags":["issues"]}},"/api/v1/issues/bulk":{"post":{"operationId":"IssuesController_bulk","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkIssuesDto"}}}},"responses":{"201":{"description":""}},"summary":"Toplu issue güncelleme/etiket/arşiv — issue BAŞINA sonuç döner (kısmi başarı normaldir)","tags":["issues"]}},"/api/v1/issues/{issueId}/move":{"patch":{"operationId":"IssuesController_move","parameters":[{"name":"issueId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MoveIssueDto"}}}},"responses":{"200":{"description":""}},"summary":"Board sürükle-bırak: hedef state + komşu issue id’leri (beforeId/afterId) ile fractional sort_order","tags":["issues"]}},"/api/v1/issues/{issueId}/unarchive":{"post":{"operationId":"IssuesController_unarchive","parameters":[{"name":"issueId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"summary":"Issue’ı arşivden çıkar (archived_at = null) + activity kaydı","tags":["issues"]}},"/api/v1/issues/{issueId}/triage/accept":{"post":{"operationId":"IssuesController_acceptTriage","parameters":[{"name":"issueId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Triage kabul: issue’yu ilk non-triage unstarted (fallback backlog) state’ine taşır + triage.accepted activity","tags":["issues"]}},"/api/v1/issues/{issueId}/triage/decline":{"post":{"operationId":"IssuesController_declineTriage","parameters":[{"name":"issueId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Triage reddet: issue’yu ilk canceled state’ine taşır + triage.declined activity","tags":["issues"]}},"/api/v1/issues/{issueId}/relations":{"get":{"operationId":"IssueRelationsController_list","parameters":[{"name":"issueId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Issue ilişkileri gruplu: blocking/blockedBy/related/duplicates/duplicatedBy","tags":["issues"]},"post":{"operationId":"IssueRelationsController_create","parameters":[{"name":"issueId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIssueRelationDto"}}}},"responses":{"201":{"description":""}},"summary":"Issue ilişkisi ekle (blocks/related/duplicate) — döngü/tekrar/self doğrulaması sunucuda","tags":["issues"]}},"/api/v1/issues/{issueId}/relations/{relationId}":{"delete":{"operationId":"IssueRelationsController_remove","parameters":[{"name":"issueId","required":true,"in":"path","schema":{"type":"string"}},{"name":"relationId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"summary":"Issue ilişkisini kaldır (204 — bulunamazsa 404)","tags":["issues"]}},"/api/v1/teams/{teamId}/board":{"get":{"operationId":"BoardController_getBoard","parameters":[{"name":"teamId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Board: her workflow state için ilk N issue + toplam sayı","tags":["board"]}},"/api/v1/teams/{teamId}/cycles":{"get":{"operationId":"CyclesController_list","parameters":[{"name":"teamId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Takımın cycle’larını listele (cursor sayfalama + status filtresi)","tags":["cycles"]},"post":{"operationId":"CyclesController_create","parameters":[{"name":"teamId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCycleDto"}}}},"responses":{"201":{"description":""}},"summary":"Yeni cycle oluştur (number takımın max+1’i olarak otomatik atanır)","tags":["cycles"]}},"/api/v1/teams/{teamId}/cycles/{cycleId}":{"patch":{"operationId":"CyclesController_update","parameters":[{"name":"teamId","required":true,"in":"path","schema":{"type":"string"}},{"name":"cycleId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCycleDto"}}}},"responses":{"200":{"description":""}},"summary":"Cycle güncelle (name/description/tarih/status)","tags":["cycles"]},"delete":{"operationId":"CyclesController_remove","parameters":[{"name":"teamId","required":true,"in":"path","schema":{"type":"string"}},{"name":"cycleId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"summary":"Cycle’ı sil (bağlı issue’ların cycleId’si NULL’a düşer, issue’lar SİLİNMEZ)","tags":["cycles"]}},"/api/v1/cycles/{cycleId}":{"get":{"operationId":"CyclesDetailController_getById","parameters":[{"name":"cycleId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Cycle detayı + scope istatistikleri (total/completed issue sayısı ve estimate toplamı)","tags":["cycles"]}},"/api/v1/cycles/{cycleId}/board":{"get":{"operationId":"CyclesDetailController_getBoard","parameters":[{"name":"cycleId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Cycle board: cycle’a atanmış issue’lar workflow state’lere (sütun) gruplu + toplam sayı","tags":["cycles"]}},"/api/v1/teams/{teamId}/recurring-templates":{"get":{"operationId":"RecurringTemplatesController_list","parameters":[{"name":"teamId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Takımın yinelenen issue şablonları (sıradaki çalışmaya göre sıralı)","tags":["recurring-templates"]},"post":{"operationId":"RecurringTemplatesController_create","parameters":[{"name":"teamId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRecurringTemplateDto"}}}},"responses":{"201":{"description":""}},"summary":"Yinelenen issue şablonu oluştur (owner/admin)","tags":["recurring-templates"]}},"/api/v1/teams/{teamId}/recurring-templates/{templateId}":{"patch":{"operationId":"RecurringTemplatesController_update","parameters":[{"name":"teamId","required":true,"in":"path","schema":{"type":"string"}},{"name":"templateId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRecurringTemplateDto"}}}},"responses":{"200":{"description":""}},"summary":"Şablonu güncelle — kural değişirse sıradaki çalışma YENİDEN hesaplanır (owner/admin)","tags":["recurring-templates"]},"delete":{"operationId":"RecurringTemplatesController_remove","parameters":[{"name":"teamId","required":true,"in":"path","schema":{"type":"string"}},{"name":"templateId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"summary":"Şablonu sil (owner/admin) — üretilmiş issue’lar KALIR","tags":["recurring-templates"]}},"/api/v1/teams/{teamId}/insights":{"get":{"operationId":"InsightsController_get","parameters":[{"name":"teamId","required":true,"in":"path","schema":{"type":"string"}},{"name":"interval","required":false,"in":"query","schema":{"type":"string","enum":["day","week"]},"description":"Kova genişliği. Kesme UTC’de yapılır (tenant zaman dilimi YOKTUR). Varsayılan: day."},{"name":"to","required":false,"in":"query","schema":{"type":"string","format":"date-time"},"description":"Pencerenin HARİÇ üst sınırı (ISO 8601). Verilmezse yarının UTC başlangıcı. Pencere 366 günü AŞAMAZ (aşarsa 400)."},{"name":"from","required":false,"in":"query","schema":{"type":"string","format":"date-time"},"description":"Pencerenin DAHİL alt sınırı (ISO 8601, offset zorunlu). Verilmezse `to` − 90 gün."}],"responses":{"200":{"description":""}},"summary":"Takım analitiği: throughput + cycle time (p50/p90) + cycle velocity (pencere zorunlu — varsayılan 90 gün, üst sınır 1 yıl, kovalar UTC)","tags":["insights"]}},"/api/v1/labels":{"post":{"operationId":"LabelsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLabelDto"}}}},"responses":{"201":{"description":""}},"summary":"Yeni label oluştur (teamId verilirse takım-scope, verilmezse tenant genelinde)","tags":["labels"]},"get":{"operationId":"LabelsController_list","parameters":[],"responses":{"200":{"description":""}},"summary":"Label listesi (teamId verilirse tenant-wide + o takıma özel label’lar)","tags":["labels"]}},"/api/v1/labels/{labelId}":{"get":{"operationId":"LabelsController_getById","parameters":[{"name":"labelId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Label detayı","tags":["labels"]},"patch":{"operationId":"LabelsController_update","parameters":[{"name":"labelId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateLabelDto"}}}},"responses":{"200":{"description":""}},"summary":"Label adı/rengini güncelle","tags":["labels"]},"delete":{"operationId":"LabelsController_remove","parameters":[{"name":"labelId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"summary":"Label’ı sil (issue_labels bağlantıları CASCADE ile temizlenir)","tags":["labels"]}},"/api/v1/issues/{issueId}/labels":{"post":{"operationId":"IssueLabelsController_add","parameters":[{"name":"issueId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddIssueLabelDto"}}}},"responses":{"201":{"description":""}},"summary":"Issue’a label ekle (label tenant-wide OLMALI veya issue’un takımına ait OLMALI)","tags":["labels"]}},"/api/v1/issues/{issueId}/labels/{labelId}":{"delete":{"operationId":"IssueLabelsController_remove","parameters":[{"name":"issueId","required":true,"in":"path","schema":{"type":"string"}},{"name":"labelId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"summary":"Issue’dan label’ı çıkar","tags":["labels"]}},"/api/v1/issues/{issueId}/comments":{"get":{"operationId":"CommentsController_list","parameters":[{"name":"issueId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Issue yorumlarını listele (cursor sayfalama)","tags":["comments"]},"post":{"operationId":"CommentsController_create","parameters":[{"name":"issueId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommentDto"}}}},"responses":{"201":{"description":""}},"summary":"Yorum ekle (activity kaydı üretir)","tags":["comments"]}},"/api/v1/issues/{issueId}/comments/{commentId}/reactions":{"post":{"operationId":"CommentsController_react","parameters":[{"name":"commentId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReactionBodyDto"}}}},"responses":{"204":{"description":""}},"summary":"Yoruma emoji tepkisi ver (idempotent)","tags":["comments"]},"delete":{"operationId":"CommentsController_unreact","parameters":[{"name":"commentId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"summary":"Emoji tepkisini geri al (yoksa NO-OP)","tags":["comments"]}},"/api/v1/issues/{issueId}/comments/{commentId}":{"patch":{"operationId":"CommentsController_update","parameters":[{"name":"commentId","required":true,"in":"path","schema":{"type":"string"}},{"name":"issueId","required":true,"in":"path","schema":{}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCommentDto"}}}},"responses":{"200":{"description":""}},"summary":"Yorumu düzenle (SADECE yazar — 403)","tags":["comments"]},"delete":{"operationId":"CommentsController_remove","parameters":[{"name":"commentId","required":true,"in":"path","schema":{"type":"string"}},{"name":"issueId","required":true,"in":"path","schema":{}}],"responses":{"204":{"description":""}},"summary":"Yorumu sil (yazar VEYA owner/admin)","tags":["comments"]}},"/api/v1/projects":{"post":{"operationId":"ProjectsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectDto"}}}},"responses":{"201":{"description":""}},"summary":"Yeni proje oluştur","tags":["projects"]},"get":{"operationId":"ProjectsController_list","parameters":[],"responses":{"200":{"description":""}},"summary":"Proje listesi (arama + cursor sayfalama)","tags":["projects"]}},"/api/v1/projects/{projectId}":{"get":{"operationId":"ProjectsController_getById","parameters":[{"name":"projectId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Proje detayı","tags":["projects"]},"patch":{"operationId":"ProjectsController_update","parameters":[{"name":"projectId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProjectDto"}}}},"responses":{"200":{"description":""}},"summary":"Proje güncelle","tags":["projects"]},"delete":{"operationId":"ProjectsController_remove","parameters":[{"name":"projectId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"summary":"Projeyi sil (bağlı issue’ların projectId’si NULL’a düşer, issue’lar SİLİNMEZ)","tags":["projects"]}},"/api/v1/projects/{projectId}/progress":{"get":{"operationId":"ProjectsController_getProgress","parameters":[{"name":"projectId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Proje ilerleme özeti (state type bazlı sayım + completed/started/unstarted yüzdesi)","tags":["projects"]}},"/api/v1/projects/{projectId}/milestones":{"get":{"operationId":"ProjectMilestonesController_list","parameters":[{"name":"projectId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Projenin milestone’ları + tamamlanma roll-up’ı (issue sayımı)","tags":["projects"]},"post":{"operationId":"ProjectMilestonesController_create","parameters":[{"name":"projectId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMilestoneDto"}}}},"responses":{"201":{"description":""}},"summary":"Yeni milestone oluştur (aynı projede ad tekrarı 409)","tags":["projects"]}},"/api/v1/projects/{projectId}/milestones/{milestoneId}":{"patch":{"operationId":"ProjectMilestonesController_update","parameters":[{"name":"projectId","required":true,"in":"path","schema":{"type":"string"}},{"name":"milestoneId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMilestoneDto"}}}},"responses":{"200":{"description":""}},"summary":"Milestone güncelle","tags":["projects"]},"delete":{"operationId":"ProjectMilestonesController_remove","parameters":[{"name":"projectId","required":true,"in":"path","schema":{"type":"string"}},{"name":"milestoneId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"summary":"Milestone’ı sil (bağlı issue’ların milestoneId’si NULL’a düşer, issue’lar SİLİNMEZ)","tags":["projects"]}},"/api/v1/initiatives":{"post":{"operationId":"InitiativesController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInitiativeDto"}}}},"responses":{"201":{"description":""}},"summary":"Yeni initiative oluştur","tags":["initiatives"]},"get":{"operationId":"InitiativesController_list","parameters":[],"responses":{"200":{"description":""}},"summary":"Initiative listesi (arama + status filtresi + cursor sayfalama)","tags":["initiatives"]}},"/api/v1/initiatives/{initiativeId}":{"get":{"operationId":"InitiativesController_getById","parameters":[{"name":"initiativeId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Initiative detayı","tags":["initiatives"]},"patch":{"operationId":"InitiativesController_update","parameters":[{"name":"initiativeId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateInitiativeDto"}}}},"responses":{"200":{"description":""}},"summary":"Initiative güncelle","tags":["initiatives"]},"delete":{"operationId":"InitiativesController_remove","parameters":[{"name":"initiativeId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"summary":"Initiative’i sil (bağlı projelerin initiativeId’si NULL’a düşer, projeler SİLİNMEZ)","tags":["initiatives"]}},"/api/v1/roadmap":{"get":{"operationId":"RoadmapController_getRoadmap","parameters":[],"responses":{"200":{"description":""}},"summary":"Roadmap: initiatives + bağlı projeler (sort_order/id ile sıralı)","tags":["roadmap"]}},"/api/v1/favorites":{"get":{"operationId":"FavoritesController_list","parameters":[],"responses":{"200":{"description":""}},"summary":"Oturum sahibinin favorileri (kenar çubuğu)","tags":["favorites"]},"post":{"operationId":"FavoritesController_add","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FavoriteBodyDto"}}}},"responses":{"201":{"description":""}},"summary":"Favoriye ekle (idempotent — ikinci çağrı 409 DEĞİL, mevcut satırı döner)","tags":["favorites"]},"delete":{"operationId":"FavoritesController_remove","parameters":[],"responses":{"204":{"description":""}},"summary":"Favoriden çıkar (yoksa NO-OP)","tags":["favorites"]}},"/api/v1/favorites/{favoriteId}/reorder":{"patch":{"operationId":"FavoritesController_reorder","parameters":[{"name":"favoriteId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReorderFavoriteDto"}}}},"responses":{"200":{"description":""}},"summary":"Favoriyi elle yeniden sırala (komşu id’leriyle kesirli sıra)","tags":["favorites"]}},"/api/v1/saved-views":{"post":{"operationId":"SavedViewsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSavedViewDto"}}}},"responses":{"201":{"description":""}},"summary":"Yeni kaydedilmiş view oluştur (ownerId = mevcut kullanıcı)","tags":["saved-views"]},"get":{"operationId":"SavedViewsController_list","parameters":[],"responses":{"200":{"description":""}},"summary":"View listesi (kendi view’larım + ?teamId ile o takımın team-scope view’ları; cursor sayfalama)","tags":["saved-views"]}},"/api/v1/saved-views/{savedViewId}":{"get":{"operationId":"SavedViewsController_getById","parameters":[{"name":"savedViewId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"View detayı","tags":["saved-views"]},"patch":{"operationId":"SavedViewsController_update","parameters":[{"name":"savedViewId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSavedViewDto"}}}},"responses":{"200":{"description":""}},"summary":"View güncelle (SADECE sahibi — 403)","tags":["saved-views"]},"delete":{"operationId":"SavedViewsController_remove","parameters":[{"name":"savedViewId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"summary":"View sil (SADECE sahibi — 403)","tags":["saved-views"]}},"/api/v1/issues/{issueId}/attachments/presign":{"post":{"operationId":"AttachmentsController_presign","parameters":[{"name":"issueId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PresignUploadDto"}}}},"responses":{"201":{"description":""}},"summary":"Presigned PUT URL üret (R2’ye doğrudan yükleme için) — { uploadUrl, r2Key }","tags":["attachments"]}},"/api/v1/issues/{issueId}/attachments":{"post":{"operationId":"AttachmentsController_create","parameters":[{"name":"issueId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAttachmentDto"}}}},"responses":{"201":{"description":""}},"summary":"R2’ye yüklendikten SONRA DB kaydı oluştur (filename/size/mime/r2Key)","tags":["attachments"]},"get":{"operationId":"AttachmentsController_list","parameters":[{"name":"issueId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Issue’a bağlı ekleri listele","tags":["attachments"]}},"/api/v1/issues/{issueId}/attachments/{attachmentId}/download":{"get":{"operationId":"AttachmentsController_download","parameters":[{"name":"issueId","required":true,"in":"path","schema":{"type":"string"}},{"name":"attachmentId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Presigned GET URL üret ({ downloadUrl })","tags":["attachments"]}},"/api/v1/issues/{issueId}/attachments/{attachmentId}":{"delete":{"operationId":"AttachmentsController_remove","parameters":[{"name":"issueId","required":true,"in":"path","schema":{"type":"string"}},{"name":"attachmentId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"summary":"DB kaydını sil — R2 objesi ASLA silinmez (kural)","tags":["attachments"]}},"/api/v1/export":{"post":{"operationId":"ExportController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExportJobDto"}}}},"responses":{"201":{"description":""}},"summary":"Yeni CSV export job’ı oluştur (owner/admin, 3/dk) — çalışma alanı veya tek takım; tenant başına TEK aktif job (409)","tags":["export"]},"get":{"operationId":"ExportController_list","parameters":[],"responses":{"200":{"description":""}},"summary":"Export job listesi (owner/admin) — en yeni önce, cursor sayfalama","tags":["export"]}},"/api/v1/export/{exportJobId}":{"get":{"operationId":"ExportController_getById","parameters":[{"name":"exportJobId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Export job durumu (owner/admin) — `succeeded` ise issues.csv + comments.csv için 15 dakikalık presigned indirme URL’leri","tags":["export"]}},"/api/v1/import":{"post":{"operationId":"ImportController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateImportJobDto"}}}},"responses":{"201":{"description":""}},"summary":"Yeni CSV import job’ı oluştur (owner/admin, 3/dk) — 15 dakikalık presigned PUT URL’i döner; tenant başına TEK aktif job (409), plan issue limiti dolu ise 403","tags":["import"]},"get":{"operationId":"ImportController_list","parameters":[],"responses":{"200":{"description":""}},"summary":"Import job listesi (owner/admin) — en yeni önce, cursor sayfalama","tags":["import"]}},"/api/v1/import/{importJobId}":{"get":{"operationId":"ImportController_getById","parameters":[{"name":"importJobId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Import job durumu (owner/admin) — dosya henüz yüklenmemişse TAZE 15 dakikalık presigned yükleme URL’i","tags":["import"]}},"/api/v1/import/{importJobId}/start":{"post":{"operationId":"ImportController_start","parameters":[{"name":"importJobId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Yüklemenin tamamlandığını bildir ve import’u kuyruğa al (owner/admin) — ikinci çağrı 409","tags":["import"]}},"/api/v1/import/{importJobId}/errors":{"get":{"operationId":"ImportController_listErrors","parameters":[{"name":"importJobId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Import satır hata raporu (owner/admin) — dosya sırasında (EN ESKİ önce), cursor sayfalama","tags":["import"]}},"/api/v1/issues/{issueId}/activities":{"get":{"operationId":"ActivitiesController_list","parameters":[{"name":"issueId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Issue aktivite akışı (en yeni önce). Gövde düz bir dizidir (web sözleşmesi); cursor sayfalama meta’sı X-Has-Next-Page/X-End-Cursor header’larında taşınır.","tags":["activities"]}},"/api/v1/me/activities":{"get":{"operationId":"MyActivitiesController_list","parameters":[],"responses":{"200":{"description":""}},"summary":"Kendi etkinlik akışım (çalışma alanı geneli, en yeni önce, cursor sayfalı)","tags":["activities"]}},"/api/v1/tenants/{id}/api-keys":{"post":{"operationId":"ApiKeysController_create","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApiKeyDto"}}}},"responses":{"201":{"description":""}},"summary":"Yeni API key oluştur (owner/admin, Business+) — plaintext anahtar SADECE bu yanıtta bir kez döner","tags":["api-keys"]},"get":{"operationId":"ApiKeysController_list","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"API key listesi (owner/admin) — prefix + ad + son kullanım; hash/plaintext ASLA dönmez","tags":["api-keys"]}},"/api/v1/tenants/{id}/api-keys/{keyId}":{"delete":{"operationId":"ApiKeysController_revoke","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"keyId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"summary":"API key’i iptal et (owner/admin) — soft-revoke, iptal sonrası bu anahtarla yapılan istekler 401 alır","tags":["api-keys"]}},"/api/v1/tenants/{id}/sso":{"get":{"operationId":"TenantSsoController_getSettings","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"SSO durumu + IdP listesi (owner/admin) — clientId MASKELİ, clientSecret ASLA dönmez","tags":["tenant-sso"]}},"/api/v1/tenants/{id}/sso/provision":{"post":{"operationId":"TenantSsoController_provision","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"summary":"Tenant için per-org Zitadel provision et (owner/admin, Business+) — idempotent","tags":["tenant-sso"]}},"/api/v1/tenants/{id}/sso/idps":{"post":{"operationId":"TenantSsoController_addIdp","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIdpDto"}}}},"responses":{"201":{"description":""}},"summary":"Tenant org’una IdP (OIDC/SAML) ekle (owner/admin, Business+) — clientSecret ŞİFRELİ saklanır","tags":["tenant-sso"]}},"/api/v1/tenants/{id}/sso/idps/{idpId}":{"delete":{"operationId":"TenantSsoController_removeIdp","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"idpId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"summary":"IdP yapılandırmasını sil (owner/admin) — Zitadel’den + DB’den","tags":["tenant-sso"]}},"/api/v1/admin/tenants":{"get":{"operationId":"AdminTenantsController_list","parameters":[],"responses":{"200":{"description":""}},"summary":"[Platform admin] Cross-tenant tenant listesi — plan/durum/arama filtresi + cursor sayfalama","tags":["admin"]}},"/api/v1/admin/tenants/{id}":{"get":{"operationId":"AdminTenantsController_detail","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"[Platform admin] Tenant detayı — abonelik geçmişi + üyeler","tags":["admin"]}},"/api/v1/admin/invoices":{"get":{"operationId":"AdminInvoicesController_list","parameters":[],"responses":{"200":{"description":""}},"summary":"[Platform admin] Cross-tenant fatura listesi — durum/tarih filtresi + cursor sayfalama","tags":["admin"]}},"/api/v1/admin/refund-requests":{"get":{"operationId":"AdminRefundsController_list","parameters":[],"responses":{"200":{"description":""}},"summary":"[Platform admin] Cross-tenant iade talebi listesi — durum filtresi + cursor sayfalama","tags":["admin"]}},"/api/v1/admin/tenants/{tenantId}/refund-requests/{refundRequestId}/approve":{"post":{"operationId":"AdminRefundsController_approve","parameters":[{"name":"tenantId","required":true,"in":"path","schema":{"type":"string"}},{"name":"refundRequestId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"summary":"[Platform admin] İade talebini onayla — Whop refund tetiklenir (period_end_only ise dokunulmaz)","tags":["admin"]}},"/api/v1/admin/config":{"get":{"operationId":"AdminConfigController_listKnown","parameters":[],"responses":{"200":{"description":""}},"summary":"[Platform admin] Bilinen TÜM remote-config anahtarlarının GÜNCEL değerlerini listele","tags":["admin"]}},"/api/v1/admin/config/{key}":{"get":{"operationId":"AdminConfigController_get","parameters":[{"name":"key","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"[Platform admin] Bir remote-config anahtarının güncel değerini oku","tags":["admin"]},"put":{"operationId":"AdminConfigController_set","parameters":[{"name":"key","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WriteConfigDto"}}}},"responses":{"200":{"description":""}},"summary":"[Platform admin] Bir remote-config anahtarını yaz (örn. billing.formalizeInvoices) — HER YAZMA audit’lenir","tags":["admin"]}},"/api/v1/admin/audit-logs":{"get":{"operationId":"AdminAuditLogsController_list","parameters":[{"name":"after","required":false,"in":"query","schema":{"type":"string"},"description":"Cursor — önceki sayfanın `endCursor`’ı (satır `id`’si; uuidv7 olduğu için zaman sıralıdır)."},{"name":"first","required":false,"in":"query","schema":{"type":"integer","minimum":1,"maximum":100},"description":"Sayfa boyutu (varsayılan 20, üst sınır 100)."},{"name":"action","required":false,"in":"query","schema":{"type":"string","minLength":1,"maxLength":200},"description":"TAM eşleşme (örn. `admin.config.write`) — kısmi arama YOK. BOŞ değer (`?action=`) 400’dür; 200 karakterden UZUN değer de 400’dür (değer denetim satırının `meta`’sına ECHO edilir ve bu tabloda retention YOKTUR)."},{"name":"tenantId","required":false,"in":"query","schema":{"type":"string","format":"uuid"},"description":"Tenant’a BAĞLI satırlar. Global (tenant’sız) satırlar bu filtreyle DIŞARIDA kalır."},{"name":"excludeExportEvents","required":false,"in":"query","schema":{"type":"boolean"},"description":"`admin.audit_log.exported` satırlarını (export MAKBUZLARI) DIŞARIDA bırakır. Varsayılan `false` — hiçbir şey varsayılan olarak gizlenmez. Wire biçimi `true`/`false` (başka değer 400). LİSTELEME ve EXPORT’a BİREBİR AYNI uygulanır. Var olma sebebi: export okuduğu tabloya yazar ve satır kapısı EN YENİDEN sayar ⇒ makbuzla dolmuş bir pencere bu filtreyle yine de indirilebilir (KAYIPSIZ çıkış yolu, gizleme değil)."},{"name":"from","required":false,"in":"query","schema":{"type":"string","format":"date-time"},"description":"DAHİL alt sınır (`created_at >=`). ISO 8601, OFSET ZORUNLU (`2026-07-01T00:00:00.000Z`) — ofsetsiz değer 400 verir."},{"name":"to","required":false,"in":"query","schema":{"type":"string","format":"date-time"},"description":"DAHİL üst sınır. ISO 8601, OFSET ZORUNLU. Zaman dilimi UTC’dir (tenant zaman dilimi YOKTUR). GRANÜLERLİK: `created_at` mikrosaniye çözünürlüklü, bu parametre ise en fazla MİLİSANİYE ifade edebilir ⇒ sınır `created_at < to + 1 ms` olarak uygulanır, yani BELİRTTİĞİNİZ MİLİSANİYENİN TAMAMI dahildir (mikrosaniye kuyruğu KAYBOLMAZ). `from` `to`’dan SONRA olamaz — ters aralık 400’dür (boş bir denetim dosyası \"bu pencerede eylem yok\" gibi okunurdu)."}],"responses":{"200":{"description":""}},"summary":"[Platform admin] Platform-admin işlem denetim kaydı — sayfalama + action/tenantId/tarih filtresi","tags":["admin"]}},"/api/v1/admin/audit-logs/export":{"get":{"operationId":"AdminAuditLogsController_exportCsv","parameters":[{"name":"action","required":false,"in":"query","schema":{"type":"string","minLength":1,"maxLength":200},"description":"TAM eşleşme (örn. `admin.config.write`) — kısmi arama YOK. BOŞ değer (`?action=`) 400’dür; 200 karakterden UZUN değer de 400’dür (değer denetim satırının `meta`’sına ECHO edilir ve bu tabloda retention YOKTUR)."},{"name":"tenantId","required":false,"in":"query","schema":{"type":"string","format":"uuid"},"description":"Tenant’a BAĞLI satırlar. Global (tenant’sız) satırlar bu filtreyle DIŞARIDA kalır."},{"name":"excludeExportEvents","required":false,"in":"query","schema":{"type":"boolean"},"description":"`admin.audit_log.exported` satırlarını (export MAKBUZLARI) DIŞARIDA bırakır. Varsayılan `false` — hiçbir şey varsayılan olarak gizlenmez. Wire biçimi `true`/`false` (başka değer 400). LİSTELEME ve EXPORT’a BİREBİR AYNI uygulanır. Var olma sebebi: export okuduğu tabloya yazar ve satır kapısı EN YENİDEN sayar ⇒ makbuzla dolmuş bir pencere bu filtreyle yine de indirilebilir (KAYIPSIZ çıkış yolu, gizleme değil)."},{"name":"from","required":false,"in":"query","schema":{"type":"string","format":"date-time"},"description":"DAHİL alt sınır (`created_at >=`). ISO 8601, OFSET ZORUNLU (`2026-07-01T00:00:00.000Z`) — ofsetsiz değer 400 verir."},{"name":"to","required":false,"in":"query","schema":{"type":"string","format":"date-time"},"description":"DAHİL üst sınır. ISO 8601, OFSET ZORUNLU. Zaman dilimi UTC’dir (tenant zaman dilimi YOKTUR). GRANÜLERLİK: `created_at` mikrosaniye çözünürlüklü, bu parametre ise en fazla MİLİSANİYE ifade edebilir ⇒ sınır `created_at < to + 1 ms` olarak uygulanır, yani BELİRTTİĞİNİZ MİLİSANİYENİN TAMAMI dahildir (mikrosaniye kuyruğu KAYBOLMAZ). `from` `to`’dan SONRA olamaz — ters aralık 400’dür (boş bir denetim dosyası \"bu pencerede eylem yok\" gibi okunurdu)."}],"responses":{"200":{"description":"CSV dosyası (`Content-Disposition: attachment; filename=\"platform-audit-logs-<UTC damgası>.csv\"`). İlk satır BAŞLIK satırıdır ve eşleşme YOKSA da yazılır. Kolonlar: ID, Created At, Action, Actor User ID, Actor Zitadel Sub, Tenant ID, Entity Type, Entity ID, Meta.","content":{"text/csv":{"schema":{"type":"string"}}}},"400":{"description":"Geçersiz filtre (ofsetsiz tarih, ters aralık, BİLİNMEYEN query parametresi) VEYA sonuç kümesi bütçeyi aştı. Bütçe reddinde gövde `reason` (stabil kod) + `maxRows` taşır; istemci bunları LOKALİZE bir mesaja çevirir ve kullanıcıya `from`/`to` ile daraltmasını söyler.","content":{"application/problem+json":{"schema":{"type":"object","required":["type","title","status","reason","maxRows"],"properties":{"type":{"type":"string","example":"https://soliagile.com/problems/audit-log-export-refused"},"title":{"type":"string"},"status":{"type":"integer","example":400},"detail":{"type":"string"},"instance":{"type":"string"},"reason":{"type":"string","enum":["row-cap-exceeded","byte-cap-exceeded"]},"maxRows":{"type":"integer","example":10000}}}}}}},"summary":"[Platform admin] Denetim kaydı CSV export’u (text/csv, attachment). Listeleme İLE AYNI action/tenantId/tarih filtreleri; sayfalama YOK. Sonuç kümesi bütçeyi aşarsa 400 döner — YARIM DOSYA ÜRETİLMEZ.","tags":["admin"]}},"/api/v1/admin/reconciliation/whop":{"get":{"operationId":"AdminReconciliationController_getWhopReport","parameters":[],"responses":{"200":{"description":""}},"summary":"[Platform admin] Whop mutabakat raporu — DB aktif abonelik sayısı (plan/döngü kırılımı) vs Whop aktif membership sayısı","tags":["admin"]}},"/api/v1/admin/health/checks":{"get":{"operationId":"AdminHealthController_getChecks","parameters":[],"responses":{"200":{"description":""}},"summary":"[Platform admin] Bileşen başına EN SON health-check durumu — meta (Paraşüt/Mila hata detayı) DAHİL","tags":["admin"]}},"/api/v1/mcp/consent/tenants":{"get":{"operationId":"McpConsentController_myTenants","parameters":[],"responses":{"200":{"description":""}},"tags":["McpConsent"]}},"/api/v1/mcp/consent":{"post":{"operationId":"McpConsentController_consent","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpConsentDto"}}}},"responses":{"200":{"description":""}},"tags":["McpConsent"]}},"/mcp":{"post":{"operationId":"McpController_handle","parameters":[],"responses":{"201":{"description":""}},"tags":["Mcp"]},"get":{"operationId":"McpController_getNotAllowed","parameters":[],"responses":{"200":{"description":""}},"tags":["Mcp"]},"delete":{"operationId":"McpController_deleteNotAllowed","parameters":[],"responses":{"200":{"description":""}},"tags":["Mcp"]}}},"info":{"title":"SoliAgile API","description":"SoliAgile REST API — çok kiracılı takım & issue yönetimi.\n\n**Kimlik doğrulama:** `Authorization: Bearer <token>`. İki tür token kabul edilir:\n- **API anahtarı** (`sa_...`): tenant kapsamlı kalıcı anahtar. `@vennyx/soliagile-sdk` ve `@vennyx/soliagile-mcp` bunu kullanır. Tenant ayarları → API Keys (Business+ plan).\n- **Zitadel JWT**: interaktif kullanıcı oturumu (web/admin).\n\nTüm kaynak endpoint'leri `x-tenant-id` başlığı ister (API anahtarı zaten tek tenant'a bağlıdır). Sayfalama cursor tabanlıdır.\n\nOpenAPI JSON: [`/api/docs-json`](/api/docs-json) · SDK: `@vennyx/soliagile-sdk` · MCP: `@vennyx/soliagile-mcp`.","version":"1","contact":{"name":"Vennyx","url":"https://soliagile.com","email":"destek@soliagile.com"},"license":{"name":"Proprietary","url":"https://soliagile.com/legal/terms"}},"tags":[],"servers":[{"url":"https://api.soliagile.com","description":"Production"}],"components":{"securitySchemes":{"apiKey":{"scheme":"bearer","bearerFormat":"JWT","type":"http","description":"Tenant kapsamlı API anahtarı (`sa_...`) — SDK/MCP ve sunucu-sunucu entegrasyonlar."},"zitadelJwt":{"scheme":"bearer","bearerFormat":"JWT","type":"http","description":"Zitadel kullanıcı access token (interaktif oturum)."}},"schemas":{"SaveBillingProfileDto":{"type":"object","properties":{}},"CreateCheckoutDto":{"type":"object","properties":{}},"CreateRefundRequestDto":{"type":"object","properties":{}},"RejectRefundRequestDto":{"type":"object","properties":{}},"UpdateMeDto":{"type":"object","properties":{}},"PresignAvatarDto":{"type":"object","properties":{}},"CreateTenantDto":{"type":"object","properties":{}},"UpdateTenantDto":{"type":"object","properties":{}},"SaveTenantThemeDto":{"type":"object","properties":{}},"PresignTenantLogoDto":{"type":"object","properties":{}},"CreateCustomDomainDto":{"type":"object","properties":{}},"IssueSessionHandoffDto":{"type":"object","properties":{}},"RedeemSessionHandoffDto":{"type":"object","properties":{}},"CreateInviteDto":{"type":"object","properties":{}},"RotateInviteLinkDto":{"type":"object","properties":{}},"SetApprovedDomainsDto":{"type":"object","properties":{}},"UpdateMemberDto":{"type":"object","properties":{}},"CreateTeamDto":{"type":"object","properties":{}},"UpdateTeamDto":{"type":"object","properties":{}},"AddTeamMemberDto":{"type":"object","properties":{}},"CreateWorkflowStateDto":{"type":"object","properties":{}},"UpdateWorkflowStateDto":{"type":"object","properties":{}},"ReorderWorkflowStateDto":{"type":"object","properties":{}},"CreateWebhookEndpointDto":{"type":"object","properties":{}},"UpdateWebhookEndpointDto":{"type":"object","properties":{}},"UpdateNotificationPreferencesDto":{"type":"object","properties":{}},"SnoozeNotificationDto":{"type":"object","properties":{}},"CreateIssueDto":{"type":"object","properties":{}},"SetIssueReminderDto":{"type":"object","properties":{}},"SetIssueSubscriptionDto":{"type":"object","properties":{}},"BulkIssuesDto":{"type":"object","properties":{}},"UpdateIssueDto":{"type":"object","properties":{}},"MoveIssueDto":{"type":"object","properties":{}},"CreateIssueRelationDto":{"type":"object","properties":{}},"CreateCycleDto":{"type":"object","properties":{}},"UpdateCycleDto":{"type":"object","properties":{}},"CreateRecurringTemplateDto":{"type":"object","properties":{}},"UpdateRecurringTemplateDto":{"type":"object","properties":{}},"CreateLabelDto":{"type":"object","properties":{}},"UpdateLabelDto":{"type":"object","properties":{}},"AddIssueLabelDto":{"type":"object","properties":{}},"ReactionBodyDto":{"type":"object","properties":{}},"CreateCommentDto":{"type":"object","properties":{}},"UpdateCommentDto":{"type":"object","properties":{}},"CreateProjectDto":{"type":"object","properties":{}},"UpdateProjectDto":{"type":"object","properties":{}},"CreateMilestoneDto":{"type":"object","properties":{}},"UpdateMilestoneDto":{"type":"object","properties":{}},"CreateInitiativeDto":{"type":"object","properties":{}},"UpdateInitiativeDto":{"type":"object","properties":{}},"FavoriteBodyDto":{"type":"object","properties":{}},"ReorderFavoriteDto":{"type":"object","properties":{}},"CreateSavedViewDto":{"type":"object","properties":{}},"UpdateSavedViewDto":{"type":"object","properties":{}},"PresignUploadDto":{"type":"object","properties":{}},"CreateAttachmentDto":{"type":"object","properties":{}},"CreateExportJobDto":{"type":"object","properties":{}},"CreateImportJobDto":{"type":"object","properties":{}},"CreateApiKeyDto":{"type":"object","properties":{}},"CreateIdpDto":{"type":"object","properties":{}},"WriteConfigDto":{"type":"object","properties":{}},"McpConsentDto":{"type":"object","properties":{}}}},"security":[{"apiKey":[]}]}