İçerik Moderasyon Sistemi
Statik içerik moderasyonu, küfür ve nefret söylemi kontrolü, API maliyeti olmadan çalışan basit kontrol mekanizması.
Achidemy, kullanıcı tarafından oluşturulan içeriklerde (kurs başlıkları, açıklamalar, mesajlar, yorumlar) küfür ve nefret söylemi kontrolü yapar. Çekirdek sistem, API maliyeti olmadan çalışan statik bir kontrol mekanizmasıdır; kritik alanlarda ise buna ek olarak Cloudflare AI tabanlı akıllı moderasyon katmanı devrededir.
Moderation Modülü (Statik Katman)
Section titled “Moderation Modülü (Statik Katman)”Dosya: app/lib/moderation.ts
Fonksiyon: moderateContent
Section titled “Fonksiyon: moderateContent”moderateContent(text: string): ModerationResultParametreler:
| Parametre | Tip | Açıklama |
|---|---|---|
text | string | Kontrol edilecek metin |
Dönüş Değeri: ModerationResult
interface ModerationResult { isAllowed: boolean; // İçerik onaylandı mı? reason?: string; // Red nedeni (opsiyonel) severity?: 'low' | 'medium' | 'high'; // Şiddet seviyesi matchedWord?: string; // Eşleşen kelime (opsiyonel)}Kontrol Edilen Kategoriler
Section titled “Kontrol Edilen Kategoriler”1. Küfür ve Argo Kelimeler
Section titled “1. Küfür ve Argo Kelimeler”Türkçe küfürler:
- Açık küfürler:
amk,aq,sikik,yarrak,göt,orospu,piç, vb. - Şifreli yazımlar:
s1k,s1kt1r,a.q,p1ç,g0t, vb.
İngilizce küfürler:
fuck,shit,bitch,ass,dick,cock,pussy,cunt,bastard, vb.
2. Nefret Söylemi ve Ayrımcılık
Section titled “2. Nefret Söylemi ve Ayrımcılık”terörist,it,köpek,domuz,şerefsiz, vb.- Irkçı, dini veya cinsiyetçi ayrımcılık içeren kelimeler
3. Spam ve Reklam
Section titled “3. Spam ve Reklam”- Tekrarlayan karakterler:
aaaaaa,!!!!!!, vb. - URL’ler ve e-posta adresleri (bazı durumlarda)
Şiddet Seviyeleri
Section titled “Şiddet Seviyeleri”| Seviye | Açıklama | Aksiyon |
|---|---|---|
high | Açık küfür, nefret söylemi | İçerik reddedilir |
medium | Şifreli küfür, hafif argo | İçerik reddedilir veya uyarı |
low | Spam benzeri içerik | İçerik onaylanır ama uyarı gösterilebilir |
Kullanım Örnekleri
Section titled “Kullanım Örnekleri”Kurs başlığı kontrolü:
import { moderateContent } from '~/lib/moderation';
const result = moderateContent(courseTitle);if (!result.isAllowed) { // Hata mesajı göster throw new Error(result.reason || 'İçerik moderasyon kontrolünden geçemedi');}Mesaj kontrolü:
const result = moderateContent(messageText);if (!result.isAllowed) { // Mesaj gönderilemez return { error: result.reason };}Entegrasyon Noktaları
Section titled “Entegrasyon Noktaları”1. Kurs Oluşturma/Düzenleme
Section titled “1. Kurs Oluşturma/Düzenleme”Dosyalar:
app/routes/instructor.course.$slug.manage.*.tsxapp/graphql/schema.ts(GraphQL mutation’lar)
Kontrol edilen alanlar:
- Kurs başlığı (
title) - Kurs açıklaması (
description) - Bölüm başlıkları (
section.title) - Ders başlıkları (
lesson.title)
2. Mesajlaşma
Section titled “2. Mesajlaşma”Dosyalar:
workers/chat.ts(Durable Object)app/routes/messages.tsx
Kontrol edilen alanlar:
- Mesaj metni (
message.text)
3. Yorumlar ve İncelemeler
Section titled “3. Yorumlar ve İncelemeler”Dosyalar:
app/graphql/schema.ts(review mutation’lar)
Kontrol edilen alanlar:
- Yorum metni (
review.comment)
4. Şikayetler ve DMCA Bildirimleri
Section titled “4. Şikayetler ve DMCA Bildirimleri”Dosyalar:
app/components/courses/ReportCourseModal.tsxapp/routes/course.$id.tsxapp/graphql/schema.ts(ReportCourseInput + reportCourse mutation)app/routes/admin.reports.tsxapp/routes/admin.reports.$courseId.tsx
Kontrol edilen alanlar:
- Şikayet nedeni (
reason) — copyright, inappropriate, spam, quality, other - Detaylı açıklama (
description) — ihlalin nerede olduğu, telif sahibi bilgileri vb.
Şikayet Sistemi (DMCA / Safe Harbor)
Section titled “Şikayet Sistemi (DMCA / Safe Harbor)”Kurs sayfalarında yer alan “Bu kursu şikayet et (DMCA / İhlal)” butonu, platformun Safe Harbor (Güvenli Liman) yükümlülüklerini karşılamak için tasarlanmış uçtan uca bir şikayet akışını tetikler. Amaç; kullanıcı tarafından oluşturulan içerik (UGC) için şeffaf bir ihlal bildirimi ve denetim süreci sağlamaktır.
1. Veritabanı Katmanı — course_reports
Section titled “1. Veritabanı Katmanı — course_reports”- Tablo:
course_reports(app/db/schema.ts) - Alanlar:
id— UUID, primary keycourseId— FK →courses.idreporterId— FK →users.id(sadece giriş yapan kullanıcılar şikayet edebilir)reason— kısa kategori (copyright,inappropriate,spam,quality,other)description— opsiyonel serbest metin alanıstatus—pending|reviewed|resolved|rejectedcreatedAt— oluşturulma zamanı
- İndeksler:
course_reports_course_idx— kurs bazlı sorgularcourse_reports_status_idx— durum bazlı filtreler (özellikle admin listeleri için)
Bu tablo, öğrenci tarafındaki raporları ve admin tarafındaki inceleme durumlarını tek yerde tutar.
2. GraphQL Mutasyonu — reportCourse
Section titled “2. GraphQL Mutasyonu — reportCourse”- Tip tanımı (
app/graphql/schema.ts):input ReportCourseInput { courseId: ID!, reason: String!, description: String }reportCourse(input: ReportCourseInput!): Boolean
- Yetki:
- Sadece giriş yapmış kullanıcılar mutation çalıştırabilir; aksi durumda
"Şikayet oluşturmak için giriş yapmalısınız."hatası döner.
- Sadece giriş yapmış kullanıcılar mutation çalıştırabilir; aksi durumda
- Çalışma:
- Gönderilen
courseId,reason,descriptionalanları course_reports tablosuna insert edilir. - Otomatik Moderasyon Kalkanı (AI): Aynı kurs için
status = "pending"olan şikayet sayısı 5’e ulaştığında kurs otomatik olarakpending_reviewdurumuna alınır,isMarketplaceVisible = falseyapılır ve eğitmene uyarı bildirimi (in-app + e-posta) gönderilir. Detay için Yapay Zeka Destekli Moderasyon sayfasına bakın.
- Gönderilen
3. Frontend — Öğrenci Akışı
Section titled “3. Frontend — Öğrenci Akışı”- Modal bileşeni:
ReportCourseModal(app/components/courses/ReportCourseModal.tsx)- Kurs detay sayfasının (
course.$id.tsx) alt kısmına eklenmiştir. - Şikayet nedenleri select menüsü: Telif hakkı ihlali (DMCA), uygunsuz/zayıf içerik, spam/yanıltıcı, düşük kalite/bozuk video, diğer.
- Detaylı açıklama alanı (opsiyonel) ile öğrenci hangi videoda/hangi noktada ihlal gördüğünü yazabilir.
- Kurs detay sayfasının (
- Davranış:
handleSubmitile/api/graphqlüzerindenreportCoursemutation çağrılır.- Başarılı durumda lokalize bir başarı mesajı (toast) gösterilir ve modal kapanır.
- Hata durumunda lokalize hata mesajı gösterilir; veritabanı kaydı yapılmaz.
4. Admin — Kurs Bazlı Şikayet Listesi (/admin/reports)
Section titled “4. Admin — Kurs Bazlı Şikayet Listesi (/admin/reports)”- Liste sayfası:
app/routes/admin.reports.tsx - URL:
/admin/reports - Amaç: Her kurs için şikayet yoğunluğunu görmek ve en kritik kurslara öncelik vermek.
Özellikler:
- Aggregation (kurs bazlı özet):
- Aynı kursa ait tüm
course_reportskayıtları tek bir kart altında toplanır. totalReports— kurs için açılmış toplam şikayet sayısı.pendingReports— durumupendingolan açık şikayet sayısı.
- Aynı kursa ait tüm
- Sıralama:
- Önce
pendingReports(azalan), - sonra
totalReports(azalan), - son olarak da en yeni şikayet tarihi (azalan).
- Önce
- Arayüz:
- Kart başlığında kurs adı ve eğitmen bilgisi.
- Rozetler: Toplam şikayet sayısı ve açık şikayet sayısı.
- “İncele” butonu ile detay sayfasına (
/admin/reports/:courseId) yönlendirme. - Kart içindeki tablo satırlarında bireysel raporlar için durum dropdown’u (
pending,reviewed,resolved,rejected) veuseFetcherile anlık güncelleme.
5. Admin — Detaylı İnceleme Sayfası (/admin/reports/:courseId)
Section titled “5. Admin — Detaylı İnceleme Sayfası (/admin/reports/:courseId)”- Detay sayfası:
app/routes/admin.reports.$courseId.tsx - URL:
/admin/reports/:courseId - AI Paneli: Sayfada Achidemy AI Moderatör bileşeni bulunur; “Tüm Şikayetleri Analiz Et” butonu ile Cloudflare AI (Llama 3.1 8B) üzerinden şikayetlerin özeti, ortak nedenleri, çıkarılan linkler ve kritiklik skoru alınır. Detay için Yapay Zeka Destekli Moderasyon sayfasına bakın.
Loader:
- İlgili kurs bilgileri (
courses+usersjoin): başlık, slug, mevcut durum,isMarketplaceVisible, eğitmen adı ve e‑posta. - Kursa ait tüm
course_reportskayıtları en yeni tarihten eskiye doğru listelenir.
Sayfa:
- Üst kısımda kurs başlığı, eğitmen bilgisi, mevcut durum ve açık şikayet sayısı gösterilir.
- Her bir rapor için:
- Şikayet nedeni (
reason) - Açıklama (
description) - Durum badge’i (
pending,reviewed,resolved,rejected) - Oluşturulma tarihi ve raporu gönderen kullanıcı bilgisi
- Şikayet nedeni (
Action:
- Intent:
mark_under_review - İşlemler:
- İlgili kurs:
status = "pending_review"isMarketplaceVisible = false(pazardan tamamen kaldırılır)
- O kursa ait ve durumu
pendingolan tümcourse_reportskayıtlarıreviewedyapılır. - Eğitmene, bildirim sistemi üzerinden (notifications tablosu) kursun inceleme altına alındığını ve DMCA/şikayet nedeniyle geçici olarak yayından kaldırıldığını belirten bir mesaj gönderilir. Bildirim dili,
getNotificationLangForUserile ülkesine göre seçilir.
- İlgili kurs:
Bu sayede, hukuken ihtiyaç duyulan “şikayet alındı → incelemeye alındı → pazardan kaldırıldı” zinciri, veritabanı + GraphQL + admin paneli + bildirim sistemi ile uçtan uca dokümante ve izlenebilir hale gelir.
Gelecek İyileştirmeler
Section titled “Gelecek İyileştirmeler”1. Machine Learning Entegrasyonu
Section titled “1. Machine Learning Entegrasyonu”- Perspective API: Google’ın Perspective API’si ile daha gelişmiş moderasyon
- Custom Model: Kendi ML modeli ile eğitim
2. Kullanıcı Bildirimi
Section titled “2. Kullanıcı Bildirimi”- Moderasyon geçmeyen içerik için kullanıcıya açıklayıcı mesaj
- İtiraz mekanizması
3. Otomatik Düzeltme
Section titled “3. Otomatik Düzeltme”- Hafif argo kelimeler için otomatik düzeltme önerileri
- Benzer kelimeler için alternatif öneriler
İlgili Dosyalar
Section titled “İlgili Dosyalar”app/lib/moderation.ts— Moderasyon fonksiyonlarıapp/graphql/schema.ts— GraphQL mutation’larda kullanımworkers/chat.ts— Mesaj moderasyonuapp/routes/instructor.course.$slug.manage.*.tsx— Kurs içerik moderasyonu
Yapay zeka destekli moderasyon: Otomatik şikayet kalkanı, şikayet analizi ve kurs kalite ön incelemesi için Yapay Zeka Destekli Moderasyon (AI Moderation) sayfasına bakın.
AI Destekli Yorum Moderasyonu (Hybrid Model)
Section titled “AI Destekli Yorum Moderasyonu (Hybrid Model)”Kurs yorumları (Course Reviews) için hibrit bir moderasyon modeli kullanılır:
- Önce statik moderasyon (
moderateContent) çalışır — ms seviyesinde hızlıdır. - Yorum statik kontrollerden geçerse, opsiyonel olarak Cloudflare AI üzerinden ek bir inceleme yapılır.
1. Client Wrapper: moderateReviewContent
Section titled “1. Client Wrapper: moderateReviewContent”Dosya: app/lib/moderation.ts
Fonksiyon: moderateReviewContent(comment: string): Promise<{ isAllowed: boolean; reason: string }>
Akış:
moderateContent(comment)ile statik kontroller uygulanır.isAllowed: falsedönerse AI çağrılmadan doğrudan red verilir.
- Yorum boşsa veya sadece whitespace ise yine AI çağrılmaz.
- Diğer durumlarda frontend,
/api/moderate-textendpoint’inePOSTisteği atar:
const res = await fetch("/api/moderate-text", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ text: comment }),});const data = await res.json();return { isAllowed: data.isAllowed ?? true, reason: data.reason || "Yorumunuz topluluk kurallarımıza uymuyor.",};2. REST Endpoint: /api/moderate-text
Section titled “2. REST Endpoint: /api/moderate-text”Dosya: app/routes/api.moderate-text.ts
Endpoint: POST /api/moderate-text
Görev:
- Cloudflare Workers AI (
@cf/meta/llama-3.1-8b-instruct) üzerinden metni analiz eder. - Sadece JSON döner:
{ "isAllowed": true, "reason": "" }veya
{ "isAllowed": false, "reason": "Yorumunuz hakaret/argo içerdiği için topluluk kurallarımız gereği yayınlanamıyor."}Prompt, modelden yalnızca JSON istemek ve markdown’ı yasaklamak üzere kurgulanmıştır; dönen cevapta olası ```json blokları temizlenir, ilk { ile son } arasındaki bölüm parse edilir. Hata durumunda sistem fail-open çalışır (isAllowed: true), böylece AI servisindeki geçici arızalar kullanıcı akışını tamamen kilitlemez.
3. Kurs Yorum Akışı ile Entegrasyon
Section titled “3. Kurs Yorum Akışı ile Entegrasyon”Bileşen: CourseReviewModal — app/components/courses/CourseReviewModal.tsx
Endpoint: POST /api/graphql (createReview / updateReview mutation’ları)
- Kullanıcı yorum yazıp Kaydet / Güncelle butonuna bastığında:
handleAction("upsert")içinde öncesetLoading(true)ile UI kilitlenir.- Ardından
await moderateReviewContent(comment, { courseTitle })çağrılır.
isAllowed === falseise:- Loader durdurulur.
toast.error(reason)gösterilir.- GraphQL mutation gönderilmez, yorum DB’ye yazılmaz.
isAllowed === trueise:createReviewveyaupdateReviewmutation’ı/api/graphqlüzerinden çalışır.- Başarılı sonuçta yorum kaydedilir, sayfa
revalidate()ile tazelenir.
4. Gelecek Kullanım Alanları
Section titled “4. Gelecek Kullanım Alanları”/api/moderate-text ve moderateReviewContent wrapper’ı, ileride:
- Öğrenci–Eğitmen mesajları,
- Soru–Cevap (Q&A) alanları,
- Forum tarzı modüller
için de merkezi bir AI moderasyon servisi olarak yeniden kullanılabilir. Bu sayede platform genelinde tutarlı ve merkezi bir içerik güvenliği katmanı sağlanır.