backend django-sentiment-project-arch

Mülakat Duygu Analizi Platformu — Plan Spesifikasyonu


1. Ön Yüz (Frontend)

1.1 User-Login Ekranı (kod ile)

Detay: Django'nun built-in django.contrib.auth sistemi ile username/password login.

Olası Pürüz Açıklama Çözüm Önerisi
Session güvenliği CSRF, session hijacking riski Django {% csrf_token %} + SESSION_COOKIE_HTTPONLY = True + SECURE_SSL_REDIRECT (prod)
Şifre politikası Zayıf şifre kabul edilebilir AUTH_PASSWORD_VALIDATORS ayarlarını aktif et
Başarısız giriş saldırısı Brute-force denemeleri django-axes veya basit rate-limiting middleware ekle

[!TIP] Alternatif: İleride OAuth2 (Google/Microsoft) eklemek isterseniz django-allauth paketini şimdiden entegre etmek kolaydır. Şu an için gerek yok ama DB şemasını buna uyumlu tutmak avantajlı olur.


1.2 Mülakat Başlat / Bitir Butonları

Detay: Tek sayfa üzerinde "Başlat" ve "Bitir" butonları. Başlat → kamerayı aç + WebRTC bağlantısını kur + soruları göster + backend'e session başlat sinyali gönder. Bitir → WebRTC bağlantısını kapat + her şeyi durdur + session'ı kapat.

Olası Pürüz Açıklama Çözüm Önerisi
Kamera izni reddedilirse Kullanıcı tarayıcıda izin vermezse akış kırılır getUserMedia hata yakalama ile kullanıcıya uyarı göster, başlat butonunu devre dışı bırak
Çift tıklama / race condition "Başlat"a iki kez basılırsa birden fazla session açılır Butonu tıklandığında disable et, backend'den cevap gelince tekrar aktif et
Sayfa yenileme / kaza kapanması Mülakat ortasında sekme kapanırsa veri kaybı beforeunload event'i ile uyarı göster + backend tarafında "orphan session" temizleme mekanizması (cron/celery task)
Video akışı kesintisi Internet veya kamera kopması WebRTC oniceconnectionstatechange event'i ile bağlantı durumu takibi, kesilirse kullanıcıya bildirim + otomatik yeniden bağlanma (ICE restart)

[!IMPORTANT] Öneri: Butonların durumları (idle → recording → finished) bir state machine ile yönetilmeli. Basit bir enum + JavaScript state yönetimi karmaşıklığı azaltır.


1.3 TR-ENG Content (Çok dilli destek)

Detay: Arayüz metinleri Türkçe ve İngilizce olarak sunulacak.

Olası Pürüz Açıklama Çözüm Önerisi
Hardcoded stringler Metinler template'lere gömülürse dil ekleme zorlaşır Django i18n framework'ü kullan: {% trans %} tag'leri + .po dosyaları
Dil değiştirme UX Dil değiştiğinde sayfa yenilenmesi gerekir django.middleware.locale.LocaleMiddleware + URL prefix (/tr/, /en/) veya session-based dil tercihi
Mülakat soruları dili Sorular DB'de ise her sorunun iki dil versiyonu lazım Sorular tablosunda question_tr + question_en alanları veya ayrı Translation tablosu

[!TIP] Avantajlı Alternatif: Eğer sadece 2 dil olacaksa (TR/EN), Django i18n yerine basit bir JSON-based dictionary yaklaşımı da yeterli olabilir — daha az overhead, daha hızlı geliştirme. Ama ileride 3+ dil planlıyorsanız i18n tercih edin.


1.4 Dummy Mülakat Soruları

Detay: Geliştirme/demo aşamasında kullanılacak sabit soru seti.

Olası Pürüz Açıklama Çözüm Önerisi
Sorular nerede tutulacak? Kod içinde mi, DB'de mi, JSON dosyasında mı? Öneri: DB'de tutun (Question modeli). Fixture/seed script ile dummy dataları yükleyin (python manage.py loaddata). İleride gerçek sorularla değiştirmek sorunsuz olur
Soru sıralaması Herkese aynı sırada mı, rastgele mi? Şimdilik sıralı, ama modelde order alanı bırakın. İleride random veya adaptive gibi stratejiler eklenebilir
Soru tipi çeşitliliği Sadece metin mi, yoksa seçenekli/video sorular da olacak mı? Şimdilik sadece metin. Ama modele question_type (text, multiple_choice, video) alanı ekleyin — bozmaz, genişletir

1.5 WebRTC — Gerçek Zamanlı Video Akışı

Detay: Kullanıcının kamerasından alınan video akışını WebRTC ile sunucuya (veya doğrudan model servisine) gerçek zamanlı iletmek. Bu sayede frame'ler anlık olarak emotion inference'a gönderilebilir ve video kaydı sunucu tarafında yapılabilir.

Akış:

Browser (getUserMedia) → WebRTC PeerConnection → Signaling (Django Channels) → Media Server → Model Service
Olası Pürüz Açıklama Çözüm Önerisi
Signaling sunucusu WebRTC bağlantısı kurmak için SDP/ICE mesaj alışverişi gerekir Django Channels (WebSocket) ile signaling endpoint'i oluşturun. ws://host/ws/signaling/<session_id>/
NAT traversal Kullanıcı NAT/firewall arkasındaysa doğrudan bağlantı kurulamaz STUN sunucusu (ücretsiz: Google STUN stun:stun.l.google.com:19302) + gerektiğinde TURN sunucusu (self-hosted: coturn)
TURN sunucusu maliyeti TURN relay trafiği bant genişliği tüketir Önce STUN ile dene, sadece STUN başarısız olursa TURN'e düş. Geliştirmede localhost'ta TURN gerekmez
Media server ihtiyacı WebRTC peer-to-peer'dır, sunucunun videoyu alması için bir media endpoint lazım Basit yol: aiortc (Python WebRTC kütüphanesi) ile sunucu tarafında peer oluşturun. Gelişmiş yol: Janus/mediasoup gibi bir SFU kullanın
Tarayıcı uyumluluğu Bazı eski tarayıcılar WebRTC desteklemez adapter.js shim kütüphanesini ekleyin. Modern tarayıcılarda (Chrome, Firefox, Edge, Safari 11+) sorun yok
Ses vs sadece video Mülakatda ses de kaydedilecek mi? getUserMedia({ video: true, audio: true }) ile hem video hem ses alın. WebRTC her ikisini de aynı PeerConnection üzerinden taşır

[!IMPORTANT] WebRTC vs MediaRecorder Karşılaştırması:

WebRTC MediaRecorder (mevcut plan)
Real-time streaming ✅ Sunucuya anlık akış ❌ Sadece client-side kayıt
Sunucu tarafı kayıt ✅ Media server ile ❌ Upload gerekli
Real-time inference ✅ Frame'ler anında sunucuya ⚠️ Batch POST gerekli
Karmaşıklık Yüksek (signaling, ICE, TURN) Düşük
Bant genişliği Sürekli stream Sadece upload anında

Öneri: İkisini birlikte kullanın — WebRTC real-time emotion inference için frame stream'i, MediaRecorder yedek video kaydı (client-side, WebRTC kesilirse kayıp olmaz).

[!TIP] aiortc ile Basit Entegrasyon: Python'da WebRTC peer oluşturmak için aiortc kütüphanesi idealdir. Django Channels ile aynı async event loop üzerinde çalışır. Video frame'lerini doğrudan VideoStreamTrack üzerinden alıp model servisine iletebilirsiniz.


2. Arka Yüz (Backend)

2.1 User-Login (kod ile)

Detay: Frontend ile aynı auth sistemi. Django auth backend, session management.

Olası Pürüz Açıklama Çözüm Önerisi
API vs Template-based auth Kamera erişimi JS gerektirdiğinden, sayfalar ne kadar SPA olacak? İki yol: (A) Klasik Django template + AJAX çağrıları (basit), (B) DRF + JWT ile tam API (esnek ama karmaşık). Öneri: Şu an için (A) yeterli
User modeli genişletme İleride kullanıcıya özel alanlar lazım olabilir (departman, pozisyon vb.) AbstractUser'dan miras alan custom User modeli şimdiden oluşturun — sonradan değiştirmek çok zor
Admin paneli Sorular ve session'lar yönetilmeli Django Admin'e Question, InterviewSession, EmotionRecord modellerini kaydedin

[!CAUTION] Kritik: Django projesi başlarken AUTH_USER_MODEL ayarını custom user modeline yönlendirin. Sonradan değiştirmek migration cehennemine yol açar.


2.2 User + Session Based Duygu Kayıtları

Format: [timestamp, "mutlu":0.2, "üzgün":0.6, ...] + video kaydı

Olası Pürüz Açıklama Çözüm Önerisi
Yüksek frekanslı veri yazma Her frame'de DB'ye yazarsanız performans düşer WebRTC ile gelen frame'leri sunucu tarafında buffer'layın (Redis/in-memory queue) → periyodik DB flush
Video kayıt — çift katman Hem sunucu hem client tarafında kayıt stratejisi WebRTC stream: aiortc ile sunucu tarafında kayıt (birincil). MediaRecorder: Client-side yedek kayıt (fallback). Format: WebM (VP9)
Video saklama Dosya sistemi mi, object storage mı? Geliştirme: MEDIA_ROOT ile local. Prodüksiyon: S3/MinIO. Django FileField her ikisini de destekler
Veri modeli tasarımı Emotion verileri nasıl saklanmalı? Önerilen model yapısı aşağıda
Zaman senkronizasyonu Video timestamp ile emotion timestamp uyuşmazlığı WebRTC RTP timestamp'larını kullanın — frame ve emotion timestamp'ları doğal olarak senkron olur
Django Channels altyapısı WebRTC signaling ve WebSocket için ASGI gerekir daphne veya uvicorn ASGI server kullanın. ASGI_APPLICATION ayarını yapılandırın

Önerilen DB Modeli:

class InterviewSession(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    started_at = models.DateTimeField(auto_now_add=True)
    ended_at = models.DateTimeField(null=True, blank=True)
    video_file = models.FileField(upload_to='interviews/videos/', null=True)
    language = models.CharField(max_length=2, choices=[('tr','TR'),('en','EN')])
    status = models.CharField(max_length=20, default='in_progress')  # in_progress, completed, abandoned

class EmotionRecord(models.Model):
    session = models.ForeignKey(InterviewSession, on_delete=models.CASCADE, related_name='emotions')
    timestamp = models.FloatField()  # saniye cinsinden, session başlangıcına göre
    happy = models.FloatField(default=0)
    sad = models.FloatField(default=0)
    angry = models.FloatField(default=0)
    surprised = models.FloatField(default=0)
    fearful = models.FloatField(default=0)
    disgusted = models.FloatField(default=0)
    neutral = models.FloatField(default=0)
    # Alternatif: emotions = models.JSONField()  → daha esnek ama sorgulaması zor

[!NOTE] Trade-off: JSONField ile emotion'ları tek alanda tutmak esnektir ama SQL ile filtreleme/aggregation zorlaşır. Ayrı float alanları query dostu ama model değişikliği gerektirir. Öneri: Emotion sayısı sabit kalacaksa ayrı alanlar; değişecekse JSONField.


3. Perception (Model Katmanı)

3.1 Model Doğruluğu Artırılması

Olası Pürüz Açıklama Çözüm Önerisi
Model-Django entegrasyonu PyTorch/TF modeli Django process'inde çalıştırmak bellek sorunlarına yol açar Öneri: Modeli ayrı bir microservice olarak çalıştırın (FastAPI + model server). aiortc → frame alır → model servisine iletir
GPU vs CPU inference Sunucuda GPU yoksa inference yavaş olur ONNX Runtime ile CPU optimizasyonu veya TensorRT ile GPU hızlandırma. Client-side inference (TF.js/ONNX.js) alternatif ama model boyutuna bağlı
Model güncelleme Yeni model eğitildiğinde deployment nasıl olacak? Model dosyasını versiyonlayın (model_v1.onnx, model_v2.onnx). Config ile hangi versiyonun aktif olduğunu belirleyin
Real-time vs batch inference Her frame'i anında mı analiz edeceksiniz? WebRTC ile gelen frame'lerden her 2-3 FPS'te birini model'e gönderin. aiortc VideoStreamTrack üzerinde frame skip mantığı uygulayın

[!TIP] Avantajlı Alternatif — Client-Side Inference: Eğer model yeterince küçükse (~5-20MB), TensorFlow.js veya ONNX.js ile emotion detection'ı doğrudan tarayıcıda çalıştırabilirsiniz. Avantajları: - Sunucu yükü sıfır - Latency çok düşük - Video verisi sunucuya gönderilmeden işlenir (gizlilik)

Dezavantaj: Düşük donanımlı client'larda performans sorunu.


3.2 Time-Based Solution'ların Tekrardan Eklenmesi

Olası Pürüz Açıklama Çözüm Önerisi
Temporal smoothing Anlık tahminler gürültülü olur (frame'den frame'e zıplama) Sliding window averaging (son 5-10 frame'in ortalaması) veya exponential moving average (EMA)
Temporal model entegrasyonu LSTM/Transformer gibi modeller session-level state tutar Session başına bir model state tutulmalı — memory management önemli. Her session kapanınca state temizlenmeli
Senkronizasyon Time-based prediction'lar ile soru geçişleri eşleşmeli Her soru geçişinde bir "marker" timestamp kaydedin → analiz aşamasında soru bazlı emotion grafiği çıkarılabilir

4. Genel Mimari Önerileri

┌─────────────────────────────────────────────────────────────┐
│                      BROWSER (Client)                       │
│  ┌──────────┐  ┌──────────┐  ┌─────────────────────────┐   │
│  │  Login   │  │ Mülakat  │  │  getUserMedia            │   │
│  │  Formu   │  │ UI/Sorular│ │  + RTCPeerConnection    │   │
│  └────┬─────┘  └────┬─────┘  │  + MediaRecorder (yedek)│   │
│       │              │        └────────┬────────────────┘   │
│       │              │                 │                    │
│       │              │         WebRTC Media Stream           │
│       │              │         + Signaling (WebSocket)       │
└───────┼──────────────┼─────────────────┼────────────────────┘
        │              │                 │
        ▼              ▼                 ▼
┌─────────────────────────────────────────────────────────────┐
│              DJANGO BACKEND (ASGI — Daphne/Uvicorn)         │
│  ┌─────────┐  ┌────────────┐  ┌──────────────────────────┐  │
│  │  Auth   │  │  Session   │  │  Django Channels         │  │
│  │  Views  │  │  Manager   │  │  (WebSocket Signaling)   │  │
│  └─────────┘  └──────┬─────┘  └────────────┬─────────────┘  │
│                      │                     │                │
│               ┌──────▼──────┐    ┌─────────▼────────────┐   │
│               │  PostgreSQL │    │  aiortc (Python peer) │  │
│               │  (DB)       │    │  Video frame alımı    │  │
│               └─────────────┘    └─────────┬────────────┘   │
│                                            │                │
│                               ┌────────────▼────────────┐   │
│                               │  STUN/TURN (coturn)     │   │
│                               │  NAT traversal          │   │
│                               └─────────────────────────┘   │
└────────────────────────────────────────┬────────────────────┘
                                         │ Frame → HTTP/gRPC
                                         ▼
                               ┌────────────────────┐
                               │  Model Service     │
                               │  (FastAPI)         │
                               │  Emotion Inference │
                               └────────────────────┘

[!WARNING] SQLite vs PostgreSQL: Django varsayılan olarak SQLite kullanır. Geliştirme için yeterli ama concurrent write sorunları yaşatır. Eğer birden fazla kullanıcı aynı anda mülakat yapacaksa PostgreSQL kullanın. Proje başından itibaren PostgreSQL ayarlarsanız migration sorunları yaşamazsınız.


5. Öncelik Sıralaması Önerisi

Sıra İş Neden?
1 Custom User Model + DB setup (PostgreSQL) Sonradan değiştirmek çok zor
2 Login ekranı (frontend + backend) Temel altyapı
3 Django Channels + ASGI kurulumu WebRTC signaling altyapısı, erken kurulmalı
4 Question modeli + dummy data fixture Mülakatın iskeletini oluşturur
5 Mülakat sayfası + başlat/bitir butonları Akışın çekirdeği
6 WebRTC entegrasyonu (signaling + aiortc peer) Real-time video akışı
7 Kamera erişimi + MediaRecorder (yedek kayıt) Fallback video kaydı
8 Session + EmotionRecord modelleri Backend veri katmanı
9 Model servisi entegrasyonu Perception katmanı
10 Time-based smoothing Model kalitesi
11 TR/EN çoklu dil desteği Polish aşaması

6. WebRTC Gerekli Paketler Özeti

Paket Amaç Kurulum
channels Django WebSocket/ASGI desteği pip install channels
channels-redis Channel layer backend (prod) pip install channels-redis
daphne ASGI HTTP/WebSocket server pip install daphne
aiortc Python tarafında WebRTC peer pip install aiortc
adapter.js Tarayıcı WebRTC uyumluluk shim CDN veya npm
coturn TURN/STUN sunucusu (prod) System package / Docker

EK

def add_data_to_session(request, session_id, conf_array):
    session = Session.objects.get(id=session_id)

    # 🔥 kritik kontrol
    if session.user != request.user:
        raise Exception("Bu session sana ait değil")

    data = Data.objects.create(
        session=session,
        timestamp=timezone.now(),
        conf=conf_array
    )
return data