Update: django-sentiment-project-arch
Open markdown file
Update
Edit Content
# 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:** ```python 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
Save
Remove: django-sentiment-project-arch
Delete Note