# Düzce Gurme Platform Güvenlik Planı

Bu ürün binlerce kullanıcı, işletme hesabı, admin paneli, QR menü, ödeme/sponsorluk ve AI trafiği taşıyabileceği için güvenlik baştan ürünün parçası olmalıdır.

## Ana prensip

Kullanıcı tarafı kolay, işletme tarafı kontrollü, admin tarafı kilitli olmalıdır.

Hiçbir kritik işlem sadece frontend kontrolüne güvenmemelidir. Yetki, doğrulama ve yayın kararı backend tarafında uygulanmalıdır.

## Kimlik doğrulama

- Google, Apple, Facebook ve Instagram girişleri OAuth/OIDC veya Meta'nın resmi Instagram Platform standardıyla yapılmalıdır.
- OAuth token doğrulaması sadece backend tarafında yapılmalıdır.
- Sadece Instagram profil linki göstermek için access token saklanmamalıdır; token yalnızca resmi API özelliği gerekiyorsa şifreli saklanmalıdır.
- Telefonla giriş varsa OTP rate limit uygulanmalıdır.
- Şifreli giriş eklenirse parola hash için Argon2id veya bcrypt kullanılmalıdır.
- Admin ve işletme hesaplarında güçlü parola ve mümkünse 2FA zorunlu olmalıdır.
- Oturum tokenları kısa ömürlü, refresh tokenlar güvenli ve iptal edilebilir olmalıdır.

## Yetki modeli

Roller:

- `super_admin`: Tüm sistem ve güvenlik ayarları
- `content_admin`: Mekan, menü, liste ve içerik onayı
- `sales_admin`: Sponsorlu alan ve işletme paketleri
- `venue_owner`: Kendi mekanını yönetir
- `venue_menu_editor`: Menü ve fiyat yönetir
- `venue_campaign_editor`: Kampanya yönetir
- `user`: Normal kullanıcı

Her API isteğinde şu kontrol yapılmalıdır:

1. Kullanıcı kim?
2. Hangi role sahip?
3. Hangi kaynağa erişmek istiyor?
4. Bu işlem için yetkisi var mı?
5. İşlem audit log'a yazılmalı mı?

## Admin panel güvenliği

- Admin panel public arama motorlarına kapalı olmalıdır.
- Admin girişinde 2FA kullanılmalıdır.
- Kritik işlemlerde tekrar doğrulama istenmelidir.
- Admin işlemleri audit log'a yazılmalıdır.
- Audit log menü, kampanya, mekan bilgisi, yetki ve yayın kararlarında zorunludur; kayıtlar silinemez biçimde saklanmalı ve alarm sistemine bağlanmalıdır.
- Başarısız giriş denemeleri rate limit ve alarm üretmelidir.
- Rol ayrımı net olmalıdır; her admin her şeyi yapamamalıdır.
- Yetki değişikliği, mekan onayı, sponsorlu içerik ve kullanıcı silme gibi işlemler ayrıca loglanmalıdır.

### Mekan yönetim paneli (admin-venues) notları

- Çok sayfalı mekan yönetim paneli (`admin-venues`, `admin-venue-new`, `admin-venue-edit`, `admin-venue-menu`, kategori ve ürün ekranları) tüm yazma isteklerinde `x-dga-admin-key` gönderir. Şu an panel JS dosyalarında geçici olarak `dev-admin-key` gömülüdür; bu **sadece local geliştirme** içindir.
  - **Yapılacak (canlı):** Statik anahtar yerine kısa ömürlü oturum tokenı / httpOnly cookie + CSRF tokenı kullan. Panel JS içine gömülü anahtar tamamen kaldırılmalı; anahtar asla tarayıcıya inmemeli. Bunun yerine login sonrası server-side session claim'i ile yetki verilmelidir.
- Mekan, kategori ve ürün **silme** işlemleri kalıcıdır ve kullanıcıdan tarayıcı onayı (`confirm`) ister; her silme `admin_venue_deleted` / `admin_menu_item_deleted` olarak audit log'a yazılır. Mekan silinince ilgili rota `stopVenueIds` referansları da temizlenir.
  - **Yapılacak (canlı):** Hard delete yerine `archivedAt` ile soft delete + geri alma penceresi ve günlük yedek önerilir; yanlışlıkla veri kaybı riskini azaltır.
- Toplu işlemler (onayla / onayı kaldır) yalnızca `verified` alanını değiştirir; toplu silme kasıtlı olarak panelde yoktur, çünkü tek tıkla geniş veri kaybı riskini büyütür.
- Görseller (mekan galerisi, kategori ve ürün görselleri) şu an base64 **data URL** olarak `venues.json` içinde tutulur. İstek gövdesi 1 MB ile, görsel başına ~900 KB ve mekan başına 24 görsel ile sınırlıdır.
  - **Yapılacak (canlı):** Görseller object storage'a (S3 / R2 / GCS benzeri) taşınmalı; JSON yalnızca güvenli URL referansı tutmalı. Yükleme akışında dosya tipi/boyut doğrulaması, yeniden boyutlandırma, içerik (magic-byte) kontrolü ve gerekirse virüs taraması yapılmalı. Bu, `venues.json` dosyasının şişmesini ve okuma/yazma maliyetini de engeller.
- Veri kalıcılığı tek süreçlik promise tabanlı yazma kilidi (`withWriteLock`) ile korunur; bu yalnızca aynı Node süreci içindeki eşzamanlı yazmaları sıraya alır. Çok süreçli/çok sunuculu canlı ortamda gerçek veritabanı (transaction + satır kilidi) veya atomik dosya yazımı gerekir.

## Mekan ve işletme güvenliği

- İşletme mekan oluşturabilir ama doğrudan yayına alamaz.
- Mevcut mekan sahiplenme başvurusu Düzce Gurme onayından geçmelidir.
- Bizim eklediğimiz mekana yönetici atanabilir; bu atama admin onaylı olmalıdır.
- Kritik alanlar onay gerektirir: mekan adı, konum, telefon, fiyat aralığı, sponsorlu durum, onaylı mekan rozeti.
- Menü ürünleri paket/güven seviyesine göre direkt veya onaylı yayınlanabilir.
- Menü yönetim stüdyosunda yapılan ürün, fiyat, stok ve öne çıkan lezzet değişiklikleri audit log'a yazılmalı; kritik değişiklikler onay kuyruğuna düşmelidir.
- İşletme hesabı ele geçirilirse hızlıca yetki iptali yapılabilmelidir.

## QR menü güvenliği

- QR menü herkese açık olabilir, ama sadece yayınlanmış veriyi göstermelidir.
- Taslak, reddedilmiş veya onay bekleyen ürünler QR menüde görünmemelidir.
- QR menü slug çakışmaları engellenmelidir.
- QR menü düzenleme sadece yetkili işletme rolü veya Düzce Gurme adminleri tarafından yapılmalıdır.
- QR menü görüntülenmeleri ayrı event olarak ölçülmelidir, ama kişisel veri gereksiz yere toplanmamalıdır.

## API güvenliği

- Tüm write endpointleri auth gerektirmelidir.
- Input validation zorunludur.
- SQL injection için parameterized query veya ORM kullanılmalıdır.
- Rate limit uygulanmalıdır.
- CORS sadece gerekli Düzce Gurmesi domainleriyle sınırlandırılmalıdır: `duzcegurmesi.com`, gerekli olursa `api.duzcegurmesi.com`. Geliştirme ortamında yalnızca `127.0.0.1:4288` ve `localhost:4288` allowlist'e alınır.
- CSRF koruması admin ve işletme panelinde uygulanmalıdır.
- Güvenli HTTP headerları kullanılmalıdır.
- Error mesajları sistem detayı sızdırmamalıdır.
- Dosya/görsel upload varsa dosya tipi, boyutu, virüs taraması ve güvenli storage zorunludur.

Prototip sunucusunda uygulanan temel korumalar:

- `x-content-type-options: nosniff`
- `x-frame-options: SAMEORIGIN`
- `referrer-policy: strict-origin-when-cross-origin`
- `permissions-policy`
- `content-security-policy-report-only`: prototipte inline ekranlari kirmadan CSP kapsamını izlemek icin aktiftir; canlida nonce/hash tabanli enforcement'a gecilmelidir.
- Write ve delete endpointleri için IP + path + risk scope bazlı rate limit; auth, AI chat, public form, hesap güvenliği, admin ve işletme trafiği ayrı kotalarla korunur.
- Rate limit aşımında `429 rate_limited`, `retry-after`, `x-ratelimit-limit`, `x-ratelimit-remaining` ve `x-ratelimit-scope` döner.
- Admin API istekleri için `x-dga-admin-key` yönetim anahtarı ve rol kapsamı; `DGA_ADMIN_API_KEY` süper admin, `DGA_CONTENT_ADMIN_API_KEY` içerik/onay, `DGA_PRIVACY_ADMIN_API_KEY` KVKK, `DGA_OPS_ADMIN_API_KEY` metrik/audit/bildirim operasyonları içindir.
- Yetkili ama yanlış rollü admin isteği `403 admin_role_forbidden` ile reddedilir.
- İşletme paneli API istekleri için `x-dga-business-key` yönetim anahtarı ve rol kapsamı; `DGA_BUSINESS_API_KEY` mekan sahibi, `DGA_BUSINESS_MENU_API_KEY` menü editörü, `DGA_BUSINESS_CAMPAIGN_API_KEY` kampanya editörü, `DGA_BUSINESS_RESERVATION_API_KEY` rezervasyon yöneticisi içindir.
- Yetkili ama yanlış rollü işletme isteği `403 business_role_forbidden` ile reddedilir.
- İşletme isteği `x-dga-business-venue-id` ile mekan kapsamına bağlanmışsa path içindeki mekan id'si eşleşmelidir; aksi halde `403 business_venue_forbidden` döner. Canlı üründe bu header client güvenine bırakılmamalı, işletme session claim'i veya gateway tarafından üretilmelidir.
- Reddedilen admin/işletme auth, rol ve mekan kapsam denemeleri `security_event` olarak audit log'a yazılır ve admin metriklerindeki `securityEvents` alanında izlenir.
- Public form, rapor, rezervasyon ve deneyim akışları `abuseSignals` erken uyarı metrikleriyle izlenmeli; bu metrikler otomatik ceza değil, admin inceleme kuyruğu sinyali olarak kullanılmalıdır.
- Admin güvenlik panelindeki `productionSecurity` risk matrisi launch readiness, audit, rate limit, security event, abuse, KVKK ve bildirim kuyruğu sinyallerini tek üretim kararı ekranında toplar; kritik risk varsa canlıya çıkış durdurulmalıdır.
- Admin güvenlik panelindeki `securityThreatRadar` günlük tehdit görünümüdür; erişim kontrolü, trafik baskısı, public abuse, audit bütünlüğü, KVKK kuyruğu ve bildirim teslimatını eksen bazlı skorlayarak ilk aksiyon listesini üretir.
- Admin güvenlik panelindeki `scaleReadiness` matrisi binlerce kullanıcı öncesi veri derinliği, sosyal liste grafiği, moderasyon kapasitesi, bildirim kuyruğu, şehir modülü kapsamı ve trafik korumalarını birlikte izler; skor düşükse pazarlama/indirilebilir uygulama yönlendirmesi büyütülmeden kapasite aksiyonları kapatılmalıdır.
- Mobil kullanıcı sessionları için HMAC imzalı demo bearer token; token gönderildiğinde yazma işlemlerinde kullanıcı adı token içinden alınır ve sahte username payload'u yok sayılır.
- Canlı ortamda demo giriş endpointi varsayılan kapalıdır; `DGA_ENABLE_DEMO_AUTH=true` sadece kontrollü staging/demo ortamında kullanılmalıdır.
- Kullanıcı bildirimlerinde konu ve kanal tercihleri backend tarafında uygulanır; admin broadcast, uygulama içi bildirim ve push teslimat kuyruğu kapalı tercihleri atlamalıdır.
- Liste ekleme, sıralama ve mekan notu işlemlerinde liste sahibi doğrulanır. Bearer token varsa token kullanıcısı, token yoksa `ownerUsername`/`username` alanı liste sahibiyle eşleşmelidir; başka kullanıcıya ait listeyi değiştirme denemesi `list_owner_required` ile reddedilir.
- Üretimde `DGA_ADMIN_API_KEY` ve `DGA_BUSINESS_API_KEY` environment secret olarak verilmelidir; local geliştirmede sadece test amaçlı `dev-admin-key` ve `dev-business-key` kullanılır.
- Production modunda sunucu `assertProductionSecrets()` guard'ı ile tüm admin, işletme ve bearer token secretlarını kontrol eder; eksik, `dev-` ile başlayan, 32 karakterden kısa veya tekrar kullanılan secret varsa servis ayağa kalkmaz.

Bu anahtar ve demo bearer katmanı canlı ürünün nihai auth sistemi değildir. Canlıya çıkarken Google/Apple/Facebook/Instagram OAuth, admin 2FA, işletme rol kontrolü, CSRF koruması ve kısa ömürlü oturum tokenlarıyla değiştirilmelidir. Yine de bu prototipte admin/işletme JSON API'lerinin tamamen açık kalmasını ve mobil payload spoofing'in sessizce kabul edilmesini engeller.

## XSS ve içerik güvenliği

- Kullanıcı, işletme ve admin tarafından girilen tüm metinler escape edilmelidir.
- HTML içerik gerekiyorsa allowlist sanitizer kullanılmalıdır.
- Markdown veya zengin metin desteklenirse script, iframe ve tehlikeli attribute'lar engellenmelidir.
- Content Security Policy uygulanmalıdır.
- Harici görseller proxy veya güvenli allowlist üzerinden yönetilmelidir.

Prototipte admin, işletme ve public QR menü ekranlarında dinamik `innerHTML` çıktıları `escapeHtml` helper'ı ile basılır. Canlı üründe buna ek olarak backend validation ve merkezi sanitizer uygulanmalıdır.

Mekan "Hakkında" alanı TinyMCE zengin metin editörü ile HTML üretir. QR menü sayfasında (`menu.html`) bu HTML, allowlist tabanlı `sanitizeRichText` ile temizlenir: yalnızca güvenli etiketler (p, br, strong/b, em/i, ul/ol/li, a) korunur, tüm attribute'lar silinir ve link `href` değerleri yalnızca `http(s)`, `mailto`, `tel`, göreli (`/`, `./`, `#`) şemalarına izin verilerek `javascript:`/`data:` enjeksiyonu engellenir. Canlıda aynı sanitizasyon backend'de de tekrar uygulanmalı (defense-in-depth), çünkü `about` alanı sunucuda ham HTML olarak saklanır.

## Topluluk ve sosyal liste güvenliği

- Kullanıcı listeleri public/private görünürlük modeliyle yönetilmelidir.
- Raporlanan veya marka güvenini riske atan public listeler admin tarafından geçici olarak yayından kaldırılabilmelidir.
- Liste gizleme/yayına alma kararları audit log'a yazılmalı; karar notu ve karar zamanı üretim veritabanında saklanmalıdır.
- Public discovery, profil ve paylaşım sayfaları `private` listeleri göstermemelidir.
- Kopyalama, paylaşım ve rapor sayıları kötüye kullanım sinyali olarak admin operasyon panelinde izlenmelidir.
- Aynı kullanıcının aynı hedefi aynı sebeple tekrar raporlaması admin kuyruğunu şişirmemelidir; açık rapor varsa API mevcut kaydı `repeated: true` ile döndürmelidir.
- Aynı aktif mekan başvurusu aynı başvuru sahibi tarafından tekrar gönderildiğinde admin kuyruğu şişmemeli; mevcut başvuru `repeated: true` ile dönmelidir.
- Ayni kullanici veya telefon ayni mekan icin acik rezervasyon talebini tekrar gonderdiginde isletme paneli ve bildirim kuyrugu sismemeli; mevcut talep `repeated: true` ile donmelidir.
- Liste `save_list` ve `like_list` aksiyonları kullanıcı/liste bazında tekil olmalıdır; tekrarlar sosyal skoru ikinci kez artırmamalıdır.

## Veri güvenliği ve KVKK

- Gereksiz kişisel veri toplanmamalıdır.
- Kullanıcıya hangi verinin neden toplandığı açıkça gösterilmelidir.
- Hesap silme ve veri silme talebi desteklenmelidir.
- Prototipte kullanıcı veri özeti ve hesap silme/dışa aktarma talepleri bearer token ile korunur; talepler doğrudan silme yapmaz, admin onay kuyruğuna düşer ve audit log'a yazılır.
- Hassas veri loglara yazılmamalıdır.
- Yedekler şifreli saklanmalıdır.
- Üretim veritabanına erişim sınırlı olmalıdır.
- Adminlerin kullanıcı verisi görme yetkisi rol bazlı olmalıdır.

## AI güvenliği

- LLM tüm veritabanına serbest erişmemelidir.
- Önce backend aday mekanları seçmeli, sonra LLM sadece bu adayları açıklamalıdır.
- Kullanıcı prompt'u sistem talimatı gibi kabul edilmemelidir.
- Sponsorlu içerik organik öneri gibi gösterilmemelidir.
- AI cevapları kaynak ve veri sınırlarıyla üretilmelidir.
- Prompt injection, sahte yönlendirme ve zararlı içerik riskleri için test senaryoları yazılmalıdır.
- AI maliyetleri kullanıcı, oturum ve endpoint bazında limitlenmelidir.

## İzleme ve alarm

Şu olaylar izlenmelidir:

- Başarısız giriş denemeleri
- Admin yetki değişiklikleri
- Mekan sahiplenme başvuruları
- Menü/fiyat değişiklikleri
- Sponsorlu içerik değişiklikleri
- Çok hızlı API istekleri
- Şüpheli QR menü trafiği
- AI maliyet patlaması
- Hata oranı yükselmesi

## Yedek ve kurtarma

- Günlük veritabanı yedeği alınmalıdır.
- Yedek geri yükleme düzenli test edilmelidir.
- Kritik tablolarda soft delete veya audit trail olmalıdır.
- Yanlış yayınlanan menü, mekan veya sponsorlu içerik hızlı geri alınabilmelidir.
- Üretim deployment için rollback planı olmalıdır.

## Canlıya çıkmadan önce zorunlu kontrol listesi

- Auth ve rol kontrolleri backend tarafında test edildi.
- Admin panel 2FA ve audit log ile korunuyor.
- Audit log kayitlari hash zinciriyle (`prevHash`/`hash`) dogrulanmali; zincir bozulmasi merkezi alarm ve operasyon incelemesi uretmelidir.
- Rate limit aktif.
- Input validation aktif.
- SQL injection ve XSS testleri yapıldı.
- QR menü sadece yayınlanmış ürünleri gösteriyor.
- İşletme değişiklikleri onay akışından geçiyor.
- Yedek ve geri yükleme testi yapıldı.
- KVKK metinleri ve veri silme akışı hazır.
- Güvenlik headerları ve HTTPS aktif.
- Üretim secretları repoda yok.
