WingerApp Gizlilik Politikası (v0 — kod-doğrulamalı taslak)
Son güncelleme: 2026-09-17 · Durum: Taslak, hukuki onay bekliyor (bu belge bir avukatın nihai onayının yerine geçmez).
Bu politika, WingerApp'in gerçekte hangi veriyi nerede işlediğini, kodun bugünkü hâline bakılarak yazılmıştır. Doğrulanamayan veya backend-engineer/security-privacy-reviewer teyidi gereken her madde [VERIFY: ...] ile işaretlenmiştir — bunlar yayından önce kapatılmalıdır.
Veri sorumlusu: Winger App (bkz. kvkk-aydinlatma-metni.md — tüzel kimlik [VERIFY: şirket unvanı/adresi]).
2026-09-18 güncelleme notu (web ekibi): S96/S98 (
docs/security/backend-router-inventory-2026-09-17.md, commit0044e1fb) kodda 2026-09-17'de düzeltildi ve bu belge o değişikliği yansıtacak şekilde güncellendi (aşağıda §1 madde 2, §3 ve §5'tekilocation_snapshotssatırları).compliance-docs-writerbu güncellemeyi nihai hukuki incelemede doğrulamalıdır.
1. Özet — mimari ilke ve bilinen istisnalar
WingerApp'in tasarım ilkesi "kişisel veri cihazdan çıkmaz, sunucuya yalnızca geri döndürülemez SHA256 hash gider"dir (CLAUDE.md, memory-bank/Architecture.md). Ancak kod incelemesi bu ilkenin bilinen istisnalarını ortaya koymaktadır ve bu politika bunları gizlemez:
- Kayıt sırasında cinsiyet, ilgi cinsiyeti, şehir ve yaş bandı düz metin olarak sunucuya gönderilir ve saklanır (hash değil) — eşleştirme adayı filtrelemesi için gereklidir (
backend/app/models/__init__.py,Usertablosu;backend/app/api/auth.py::RegisterRequest). "İlgi cinsiyeti" alanı, kiminle flört etmek istediğinizi (dolayısıyla dolaylı olarak cinsel yönelimi) ifade edebilir — bkz. §9 veacik-riza-metni.md. Kayıt formu ayrıca ilçe ve ülke bilgisini de düz metin olarak sunucuya gönderir veuserstablosunda saklar, ancak eşleştirme motoru bu iki alanı hiç okumaz ve bunlar artıkGET /auth/meüzerinden de geri döndürülmez (S96, 2026-09-17) — bu iki kolon, gelecekte tamamen kaldırılması planlanan bir "drop-candidate" olarak işaretlenmiştir (bkz.docs/security/backend-router-inventory-2026-09-17.md). - (S98, 2026-09-17'de düzeltildi) Konum güncellemesi artık yalnızca şehrinizi sunucuya gönderir — ham enlem/boylam artık kalıcı olarak saklanmaz. Önceden
POST /api/location/updategerçek GPS koordinatınızı dalocation_snapshotstablosuna yazıyordu; bu davranış kaldırıldı (backend/app/api/location.py::update_location, commit0044e1fb) çünkü kodda bu alanları okuyan hiçbir tüketici yoktu (eşleştirme motoru yalnızcausers.city'yi kullanır) ve mobil uygulama zaten bu uç noktayı hiç çağırmıyordu. Uç nokta lat/lng/accuracy alanlarını kabul etmeye devam edebilir ama artık hiçbir yere yazmaz.location_snapshotstablosunun kendisi henüz silinmedi (bkz. §3, §5) — bu, izleyen bir temizlik migration'ına bırakılmıştır. - Satın alma makbuzları (App Store/Google Play) doğrulama için Apple/Google'a gider — bu, platformların kendi zorunlu satın alma altyapısıdır.
Bunların dışında: profiliniz (isim, biyografi, fotoğraflar), tercih cevaplarınız, sohbetleriniz, yüz doğrulama verisi ve eşleştirme hesaplaması cihazınızda kalır.
2. Cihazınızda kalan, sunucuya hiç gitmeyen veriler
| Veri | Nerede tutulur | Kanıt |
|---|---|---|
| Profil adı, biyografi, fotoğraflar | Cihaz (AsyncStorage), ProfileService.ts | Mobil kod tabanında bu alanları backend'e gönderen hiçbir çağrı yok (grep "/profiles/me" → 0 sonuç); bkz. §2.1 aşağıdaki önemli not |
| Tercih soru-cevap cevaplarınız (ilişki hedefi, sigara/alkol, vb.) | Cihaz, PreferenceProfileService | agents/agent-represented-matching.md |
| Sohbet mesajları (insan-insan) | Cihazlar arası, uçtan uca şifreli (E2EE) P2P kanal; sunucu içeriği hiç görmez | backend/app/models/__init__.py::Conversation — yalnızca participant_1_id, participant_2_id, zaman damgaları; mesaj metni kolonu yok |
| Yüz doğrulama görüntüsü/embedding'i | Tamamen cihaz (Apple Vision / Google ML Kit) | memory-bank/Features/Face-Verification.md; backend'e fotoğraf/embedding yükleyen hiçbir çağrı bulunamadı |
| Eşleştirme skoru, tercih ağırlıkları, gece-ajan-müzakeresi transkripti | Cihaz | agents/agent-represented-matching.md §"Backend'e giden outcome yalnızca no_match | match" |
| Gece ajan müzakeresinde paylaşmayı seçtiğiniz kategori cevapları | Karşı tarafın cihazına, uçtan uca şifreli (E2EE) — sunucuya değil | Aşağıdaki §7 |
2.1 Kullanılmayan ama var olan bir uç nokta — şeffaflık notu
Backend'de PUT /api/profiles/me adlı, profil adı/biyografi/fotoğraf URL'lerini kabul edip user_profiles tablosuna yazabilen bir uç nokta mevcuttur (backend/app/api/profiles.py). Ancak mobil uygulamanın hiçbir ekranı bu uç noktayı çağırmamaktadır (kod tabanında sıfır çağrı doğrulandı) — profil verisi bugün fiilen yalnızca cihazda tutulmaktadır. [VERIFY: backend-engineer] — bu uç noktanın amacı/geleceği netleştirilmeli; kullanılmayan PII-kabul edebilen uç noktalar bu projede daha önce (S15/S16, GET /api/profiles/{user_id}) güvenlik açığına dönüşmüştür ve kaldırılmıştır. Aynı sınıf risk burada da mevcuttur, kaldırılması veya en azından launch öncesi netleştirilmesi önerilir.
3. Sunucuya (backend) giden veriler — tablo tablo
| Tablo/uç nokta | İçerik | Amaç | Kanıt |
|---|---|---|---|
users | DID (kendi kendini sertifikleyen ortak kimlik — gizli değil), DID'in SHA256 hash'i, plan, cinsiyet, ilgi cinsiyeti, şehir, yaş bandı (düz metin, eşleştirme tarafından fiilen kullanılır) + ilçe, ülke (düz metin, saklanır ama eşleştirme tarafından okunmaz — drop-candidate, S96), negotiation_consent_enabled bayrağı | Kayıt, eşleştirme aday filtrelemesi | backend/app/models/__init__.py:33-84 |
location_snapshots | (S98, 2026-09-17 sonrası) artık yeni satır almıyor — tablo/kolonlar kodda duruyor ama POST /api/location/update lat/lng/accuracy'yi artık hiçbir yere yazmıyor | Yok (kullanılmayan, kaldırılması planlanan tablo) | backend/app/api/location.py::update_location (yorum: "lat/lng/accuracy are accepted but no longer persisted anywhere") |
match_outcomes | İki hash'lenmiş kimlik arası tek yönlü match bildirimi | Karşılıklı eşleşme tespiti | backend/app/models/__init__.py:460-481 |
mutual_matches | Karşılıklı onaylanmış eşleşme (iki hash + zaman damgaları) | Sohbet yetkilendirmesi | backend/app/models/__init__.py:483-542 |
pair_cooldowns | Yönsüz çift hash'i + tekrar deneme bekleme süresi | Kötüye kullanımı/ısrarı önleme | backend/app/models/__init__.py:433-458 |
push_tokens | Expo push token + platform | Bildirim gönderimi | backend/app/models/__init__.py:274-293 |
payments, iap_transactions | Plan/ürün, tutar, durum, makbuzun SHA256 hash'i (ham makbuz saklanmaz) | Satın alma doğrulama, muhasebe | backend/app/models/__init__.py:111-138, 372-415 |
abuse_reports | Bildiren/bildirilen DID, kategori (taciz/dolandırıcılık/sahte profil/spam/uygunsuz içerik/diğer), serbest metin açıklama (kullanıcı yazımı), kanıt hash'i | Moderasyon | backend/app/models/__init__.py:168-197; kategoriler mobile-app/src/screens/ReportBlockScreen.tsx:39-47 |
| Sinyalleşme (WebRTC offer/answer/ICE) | Hangi hash'lenmiş kimliğin hangisine, hangi amaçla (negotiation/chat) bağlanmaya çalıştığı | P2P bağlantı kurulumu | backend/app/api/signaling.py |
| TURN röle sunucusu | Bağlantı kurulamadığında medya/veri trafiğini röleler; röle sırasında IP adresinizi görür (TURN'ün doğası gereği, mesaj içeriğini görmez — trafik E2EE) | Bağlanabilirlik | memory-bank/Features/P2P-Chat.md; kendi barındırılan (self-hosted) coturn |
telemetry tablosu / TelemetryService | Cihaz id, oturum id, metrik adı/değeri, uygulama/İS sürümü | Ürün analitiği | backend/app/models/__init__.py:141-165 — bkz. §8, dürüst DP uyarısı |
device_attributions, revenue_shares | Cihaz kimliğinin SHA256 hash'i (IDFV/Android ID), influencer kodu, gelir payı | Influencer atıf sistemi | backend/app/models/__init__.py:299-366 |
Backend'in ASLA görmediği (mimari kısıt, kod doğrulandı): ham profil, tercih ağırlıkları/eşikleri, hangi kategorilerin sorulduğu, gece müzakeresinin transkripti, fotoğraf tercihi/kararı, fotoğrafın kendisi, eşleşme skoru/bandı (agents/agent-represented-matching.md — "Backend hiçbir zaman öğrenmez" listesi).
4. Üçüncü taraflar
- Apple App Store / Google Play — uygulama içi satın alma makbuzu doğrulaması (
IAPTransaction). - Apple Push Notification Service (APNs) / Expo push altyapısı — bildirim iletimi.
- Kendi barındırdığımız (self-hosted) TURN sunucusu — üçüncü taraf bir SDK değil, ama bağlantı sırasında IP adresinizi görebilir.
- Reklam veya analitik SDK'sı KULLANILMAMAKTADIR.
mobile-app/package.jsonbağımlılıkları doğrulandı — Facebook SDK, Adjust, AppsFlyer, Firebase, Sentry, Mixpanel, Amplitude, Crashlytics gibi hiçbir üçüncü taraf takip/analitik kütüphanesi kurulu değildir (grep sonucu: 0 eşleşme). - Verileriniz hiçbir reklam ağıyla, veri komisyoncusuyla paylaşılmaz, satılmaz.
5. Saklama süreleri
| Veri | Süre | Kanıt / durum |
|---|---|---|
match_outcomes (karşılıksız) | 30 gün sonra otomatik silinir | _sweep_expired_outcome_tables(), backend/app/models/__init__.py:466 |
mutual_matches | Son aktiviteden (sohbet) itibaren 90 gün hareketsizlik sonrası silinir | backend/app/models/__init__.py:501-515 |
pair_cooldowns | no_match: 30 gün, incomplete: 7 gün, 90 günde en fazla 3 tekrar | agent-represented-matching.md |
location_snapshots | S98 (2026-09-17) sonrası yeni satır yazılmıyor; hesap silindiğinde mevcut satırlar (varsa) silinir. [VERIFY: backend-engineer] — S98 öncesinden kalan eski satırlar için bir tek seferlik temizlik (backfill) yapılıp yapılmayacağı launch öncesi netleştirilmeli. | |
telemetry tablosu | [VERIFY: backend-engineer] — otomatik TTL bulunamadı. | |
payments, iap_transactions, abuse_reports | Hesap silindiğinde silinmez; DID bağı geri döndürülemez şekilde anonimleştirilir (bkz. §6). Finansal/moderasyon amaçlı süresiz saklanabilir. | |
| Diğer tüm hesap verisi | Hesap silme talebiyle birlikte anında ve kalıcı olarak silinir (bkz. §6) |
6. Hesap silme ve veri taşınabilirliği
Hesabınızı Ayarlar ekranından silebilirsiniz. Bu işlem DELETE /api/users/me uç noktasını çağırır (backend/app/api/users.py::delete_me) ve şu adımları eşzamanlı, tek bir istekte uygular:
- Kalıcı olarak silinenler: hesap kaydınız, profiliniz, engelleme kayıtlarınız, push token'ınız, ham konum anlık görüntüleriniz (
location_snapshots), konum tercihiniz, kullanım defteri (usage_ledger), sohbet metadata'nız (conversations), tek yönlü eşleşme bildirimleriniz (match_outcomes), karşılıklı eşleşmeleriniz (mutual_matches), yeniden-deneme bekleme kayıtlarınız (pair_cooldowns). - Kimlik bağı geri döndürülemez şekilde koparılan, ama kayıt tutulanlar: ödeme/satın alma kayıtlarınız (finansal denetim amaçlı) ve hakkınızda açılmış/sizin açtığınız kötüye kullanım bildirimleri (moderasyon geçmişi bütünlüğü amaçlı) — DID'iniz
HMAC-SHA256(secret, did)ile geri döndürülemez bir sözde-kimliğe (deleted:<hash>) dönüştürülür; kayıt artık sizinle ilişkilendirilemez. - İptal edilen: o anki oturum jetonu (JWT) anında kara listeye alınır; açık bir sinyalleşme WebSocket'iniz varsa kapatılır.
Bu işlem geri alınamaz.
Veri taşınabilirliği (KVKK m.11 / GDPR Art. 20): [VERIFY: backend-engineer] — bu görev kapsamında, kullanıcının kendi verisinin makine-okunur bir kopyasını uçtan uca otomatik olarak indirebileceği bir "veri dışa aktarma" uç noktası koda bulunamadı. legal_compliance_rolling_audit_v2.py/data_minimization.py gibi bazı backend modülleri isimlerinden "yasal denetim/dışa aktarma" çağrıştırsa da incelenen örnekler (data_minimization.py) sabit/mock veri döndüren saplama (stub) kod olduğu görüldü — gerçek bir kullanıcı-veri-dışa-aktarma akışı olarak güvenilemez. Öneri: launch öncesi ya gerçek bir öz-servis export uç noktası inşa edilmeli ya da bu hak destek talebi (support@…) üzerinden manuel karşılanmalı ve bu politika buna göre güncellenmeli.
7. Gece ajan müzakeresi (opsiyonel özellik)
Ayarlar'daki "Gece ajan müzakeresi" anahtarı varsayılan olarak kapalıdır ve istediğiniz an kapatılabilir (kapatınca devam eden bir görüşme varsa hemen iptal edilir). Açıkken:
- Cihazınız, siz uykudayken/şarj olurken, eşleşme adaylarının cihazlarındaki temsilcilerle uçtan uca şifreli bir bağlantı üzerinden özel bir görüşme yapar.
- Yalnızca paylaşmayı seçtiğiniz kategori cevaplarınız karşı tarafın cihazına gider — sunucuya değil. Profiliniz, önem sıralamanız, eşiğiniz, fotoğraflarınız, sohbetleriniz bu görüşmeye hiç girmez.
- Sunucu yalnızca şunları görür: hash'lenmiş (geri döndürülemez) kimliğiniz, görüşmenin sonucu ("eşleşme yok" / "eşleşme" — başka hiçbir değer yok), bu izin bayrağı, ve bağlantı kurulumu için gerekli sinyalleşme meta verisi (kiminle bağlanmaya çalıştığınız, ne zaman).
Bu paragraf, mobile-app/src/screens/SettingsScreen.tsx'teki güncel (2026-09-16, S91 düzeltmesi sonrası) anahtar açıklamasıyla birebir tutarlı olacak şekilde yazılmıştır.
8. Telemetri — dürüst durum
Uygulama genel kullanım telemetrisi toplar (çökme/hata, özellik kullanım sayaçları). Mimari doküman "tüm telemetri Differential Privacy (DP, ε≤1.0) ile korunur" der, ancak bu iddia bugün genel telemetri hattı için DOĞRU DEĞİLDİR: TelemetryService.trackEvent() hattı gürültü eklemez, milisaniye hassasiyetli zaman damgası ve cihaz kimliği taşır, DID ile imzalanmış toplu (batch) gönderim yapar (memory-bank/Security-Privacy.md, "Kural #2 düzeltmesi", S87). Bu yüzden gece-ajan-müzakeresi özelindeki olay-bazlı telemetri şu an tamamen KAPALIDIR (NEGOTIATION_TELEMETRY_DP_READY = false, koşulsuz no-op) — gerçek DP korumalı bir telemetri hattı inşa edilene kadar hiçbir müzakere olayı sunucuya gitmez. Bu durum düzeldiğinde bu politika güncellenecektir.
9. Özel nitelikli (hassas) veri
- Cinsel yönelim göstergesi: Kayıt sırasında zorunlu olan "ilgi cinsiyeti" alanı backend'e düz metin gider (bkz. §1, §3). Bu, KVKK m.6 anlamında özel nitelikli veri sayılabilir. Açık rızanız için bkz.
acik-riza-metni.md. - İnanç pratiği, siyasi görüş, yakınlık/mahremiyet tercihleri: Yalnızca ayrı, varsayılan kapalı bir rıza ("Hassas Tercihler") açıkça verildiğinde, gece ajan müzakeresi sırasında karşı tarafın cihazına E2EE ile paylaşılabilir hale gelir — backend'e hiçbir zaman gitmez. Kanıt:
mobile-app/src/services/ConsentManagementV7Service.ts(SENSITIVE_PREFERENCES_CONSENT_ID). - Biyometrik (yüz) veri: Yüz doğrulama tamamen cihazda işlenir, hiçbir görüntü/embedding sunucuya yüklenmez (bkz. §2). Dürüst sınır: gerçek bir derin öğrenme yüz-tanıma modeli değildir; geometrik landmark eşleştirmesi + kalibre edilmemiş bir doku-analizi (anti-sahtecilik) heuristiğidir — bkz.
safety-policy.mdvememory-bank/Features/Face-Verification.md.
10. Güvenlik
- Kimlik doğrulama: kendi kendini sertifikleyen Ed25519 DID, şifre yok.
- P2P mesajlaşma: X25519 anahtar değişimi + XSalsa20-Poly1305 (
nacl.secretbox) uçtan uca şifreleme. - Backend'e giden her kimlik göstergesi SHA256 hash'lidir (yukarıda belirtilen bilinçli istisnalar hariç).
- Taşıma güvenliği:
[VERIFY: infra-devops]— prod ortamda HTTPS/TLS ve TURN dağıtımının fiilen tamamlanıp tamamlanmadığı bu görev kapsamında doğrulanamadı;memory-bank/Progress.md'de bu bir launch-blocker olarak listeleniyor.
11. Çocukların gizliliği
WingerApp 18 yaş altı kullanıcılara yönelik değildir. Kayıt akışındaki en düşük yaş bandı seçeneği 18-25'tir (mobile-app/src/screens/OnboardingScreen.tsx:302, ageBandMinAge['18-25'] = 18). 18 yaşından küçük olduğu tespit edilen hesaplar kapatılır.
12. İletişim ve değişiklikler
Bu politika hakkında sorularınız için support@wingerapp.com (bkz. mobile-app/src/config/support.ts::SUPPORT_EMAIL). Önemli değişiklikler uygulama içi bildirimle duyurulur.
Ekler
kvkk-aydinlatma-metni.md— KVKK madde 10 aydınlatma metniacik-riza-metni.md— özel nitelikli veriler için açık rıza metinleriterms-of-service.tr.md— kullanım koşullarısafety-policy.md— güvenlik ve moderasyon politikasıapp-privacy-nutrition-label.md— Apple App Privacy formu cevapları