Eğitmen ve Kurs Yönetimi (Instructor Engine)
Kurs oluşturma sihirbazı, müfredat (Section/Lesson), Bunny CDN streaming, performans paneli ve manuel ödeme talebi.
Coursio’da eğitmenler kurs oluşturur, müfredat ve içerik yönetir, gelir/öğrenci istatistiklerini görür ve biriken bakiyeyi çeker. Bu sayfa Kurs Oluşturma Sihirbazı, Müfredat ve İçerik (Section/Lesson, Bunny CDN), Eğitmen Performans Paneli (Recharts ile analiz) ve Manuel Ödeme Talebi akışını açıklar.
Kurs Oluşturma Sihirbazı
Section titled “Kurs Oluşturma Sihirbazı”Dosya: app/routes/instructor.create.tsx
Eğitmen yeni kurs oluşturmak için adım adım sihirbaz kullanır.
Adımlar (4 adım)
Section titled “Adımlar (4 adım)”| Adım | İçerik |
|---|---|
| 1 | Kurs türü seçimi: “Kurs” (video dersler, sınavlar) veya “Pratik Testi” (şu an devre dışı). |
| 2 | Kurs başlığı: Metin alanı (max 60 karakter); en az 5 karakter gerekli. |
| 3 | Kategori: CATEGORIES listesinden ana/alt kategori seçimi; seçim zorunlu. |
| 4 | Zaman taahhüdü: “0-2 saat”, “2-4 saat”, “5+ saat” (opsiyonel). |
Oluşturma Akışı
Section titled “Oluşturma Akışı”- Slug üretimi: Başlıktan
generateSlug(title)ile URL dostu slug; çakışmayı önlemek için rastgele 5 karakter eklenir:slug-xxxxx. - GraphQL mutation:
createCourse(title, slug, category)çağrılır. - Yönlendirme: Başarılıysa eğitmen Hedefler (Goals) sayfasına yönlendirilir:
/{lang}/instructor/course/{slug}/manage/goals.
Sonrası: Kurs Yönetim Akışı
Section titled “Sonrası: Kurs Yönetim Akışı”Kurs oluşturulduktan sonra CourseEditSidebar ile adım adım tamamlanır:
- Planlama: Hedefler (goals), Kurs Yapısı (course-structure), Kurulum & Test (setup).
- İçerik: Filming & Editing (filming), Müfredat (curriculum), Altyazılar (captions).
- Yayın: Landing sayfası (landing), Fiyatlandırma (pricing).
Tamamlanma durumu: goals → learningOutcomes; curriculum → sectionCount/lessonCount; landing → başlık, açıklama, thumbnail, kategori; pricing → fiyat.
Müfredat ve İçerik
Section titled “Müfredat ve İçerik”Bölüm (Section) ve Ders (Lesson) Hiyerarşisi
Section titled “Bölüm (Section) ve Ders (Lesson) Hiyerarşisi”Veritabanı:
sections:id,course_id,title,order,created_at. Her bölüm bir kursa aittir.lessons:id,section_id,title,bunny_video_id,order,is_preview,duration. Her ders bir bölüme aittir; video varsabunny_video_iddolu.
Aynı section altında quiz ve coding exercise tabloları da vardır (quizzes, coding_exercises → section_id); müfredat sayfasında bölüm içinde dersler, quiz’ler ve egzersizler birlikte listelenir.
Dosya: app/routes/instructor.course.$slug.manage.curriculum.tsx
- Bölüm ekleme/düzenleme/silme, sürükle-bırak sıralama (Accordion + order).
- Ders ekleme: başlık, video yükleme (Bunny), önizleme (isPreview), kaynaklar (lesson_resources).
- Video yükleme: Bunny Stream API (presigned URL veya upload endpoint) ile yükleme;
bunnyVideoIdderse kaydedilir. - Bunny işlem durumu:
fetchBunnyVideoStatus(libraryId, videoId, apiKey)ile status/length çekilir;getBunnyVideoStatusKindile “processing” | “ready” | “error” gösterilir (lib/bunny-video-status.ts).
Video İçeriklerinin Bunny CDN Üzerinden Streaming Mantığı
Section titled “Video İçeriklerinin Bunny CDN Üzerinden Streaming Mantığı”Yükleme (eğitmen tarafı):
- Curriculum sayfasında derse video seçilir; Bunny Stream Library’ye yükleme yapılır (BUNNY_LIBRARY_ID, BUNNY_API_KEY).
- Ders kaydına dönen Bunny Video ID (
bunnyVideoId) yazılır.
İzleme (öğrenci tarafı):
Dosya: app/lib/video-security.ts — generateSignedVideoUrl(videoId, libraryId, securityKey, expirationSeconds)
- Amaç: Doğrudan indirme ve yetkisiz erişimi engellemek için imzalı URL kullanılır.
- Algoritma:
tokenData = securityKey + videoId + expires→ SHA-256 hash → query:token=...&expires=.... - URL formatı:
https://iframe.mediadelivery.net/embed/{libraryId}/{videoId}?token={hash}&expires={expires}. - Ortam değişkenleri:
BUNNY_LIBRARY_ID,BUNNY_VIDEO_SECURITY_KEY(Pull Zone Remote Auth Key).
Öğrenci sayfası: app/routes/learn.$slug.tsx loader’da müfredat çekilir; her ders için generateSignedVideoUrl ile signedVideoUrl hesaplanır; oynatıcıda bu URL kullanılır. Kayıt/enrollment kontrolü loader’da yapılır.
Bunny durum kodları (lib/bunny-video-status.ts): 0=Queued, 1=Processing, 2=Encoding → “İşleniyor”; 3=Finished, 4=Resolution finished → “Hazır”; 5=Failed, 8=PresignedUploadFailed → “Hata”.
Eğitmen Performans Paneli
Section titled “Eğitmen Performans Paneli”Layout: app/routes/instructor.performance.tsx — InstructorSidebar + <Outlet />.
Varsayılan yönlendirme: instructor.performance._index.tsx → /{lang}/instructor/performance/students.
Öğrenci İstatistikleri — Students
Section titled “Öğrenci İstatistikleri — Students”Dosya: app/routes/instructor.performance.students.tsx
- Loader:
getInstructorStudents(db, userId)ile son öğrenciler, tüm satın alanlar, iade edilenler, abonelik izleyicileri ve satın alım özeti (subscription, direct, organic, affiliate) alınır. - Metrik kartları: Toplam satın alım, aktif öğrenci sayısı, iade edilen sayısı, abonelik izleyicisi sayısı.
- Sekmeler: Tüm öğrenciler, satın alanlar, iade edilenler, abonelik.
- Tablo: Öğrenci adı, kurs, satın alma tarihi, satın alma türü (badge). Recharts kullanılmaz; istatistikler kart ve tablo ile sunulur.
Gelir Analizi ve Recharts — Reviews / İzlenme Trendleri
Section titled “Gelir Analizi ve Recharts — Reviews / İzlenme Trendleri”Dosya: app/components/instructor/PerformanceReviewsCharts.tsx
- Veri:
watchTrends(tarih bazlı toplam / abonelik / satın alım izlenme süreleri) vecourseAnalytics(kurs bazlı trendler). - Recharts: Dinamik import ile yüklenir (
import("recharts")). Kullanılan bileşenler:LineChart,Line,BarChart,Bar,XAxis,YAxis,CartesianGrid,Tooltip,ResponsiveContainer. - Grafikler:
- Çizgi grafiği: Tarih başına toplam / abonelik / satın alım izlenme dakikaları (watchTrends).
- Çubuk grafiği: Günlük izlenme dakikaları.
- Filtreler: Dönem (1 hafta, 1 ay, 3 ay, 6 ay); kurs seçimi (courseAnalytics üzerinden).
Bu bileşen instructor.performance.reviews sayfasında kullanılır; eğitmen burada izlenme trendlerini ve dolaylı olarak ilgili gelir/etkileşim analizini görür.
Manuel Ödeme Talebi: Biriken Bakiyeyi Çekme Süreci
Section titled “Manuel Ödeme Talebi: Biriken Bakiyeyi Çekme Süreci”Dosya: app/routes/instructor.payouts.tsx
Sayfa Özeti
Section titled “Sayfa Özeti”- Loader:
getInstructorBalance,getInstructorPayoutRequests,getUserById,getInstructorEarnings,getInstructorSubscriptionWatchByCourseile bakiye, talep listesi, kullanıcı ödeme ayarları, kazançlar ve abonelik izlenme verileri alınır. - Stripe Connect:
onboarding=successquery parametresi ile dönüldüğündeisConnectOnboardingCompletedvepayoutMethodgüncellenir.
Bakiye Gösterimi
Section titled “Bakiye Gösterimi”- Toplam bakiye (kurs satışları + affiliate + abonelik payları).
- Son kazançlar listesi (earnings): satış türü badge’i (organik, direkt, affiliate, paket, abonelik), tutar, tarih.
Ödeme Talebi Oluşturma
Section titled “Ödeme Talebi Oluşturma”- Tutar girişi: Minimum çekim tutarı kontrolü (TR ve Stripe Connect için farklı mesajlar).
- Aylık limit: Varsa limit aşılmışsa uyarı.
- TR (Türkiye):
manualPayoutDetails(IBAN/Payoneer) dolu olmalı; değilse “Önce bilgileri kaydedin” uyarısı ve ayarlar açılır. - Stripe Connect:
isConnectOnboardingCompletedveyastripeConnectId/ payout bilgisi dolu olmalı; değilse ödeme bilgisi güncelleme yönlendirmesi. - Mutation:
requestPayout(amount: Float!)GraphQL mutation’ı çağrılır; başarılıysapayout_requeststablosuna kayıt eklenir (status: pending). - Liste: Önceki talepler tabloda gösterilir; durum: pending, processing, completed, rejected.
Admin panelinde bu talepler onaylanır; Stripe Connect için processPayoutTransfer, TR için manuel havale/EFT sonrası durum “completed” yapılır (bkz. Türkiye (TR) Özel Payout Akışı ve Stripe Connect Akışı).
| Konu | Açıklama |
|---|---|
| Kurs sihirbazı | instructor.create.tsx — 4 adım (tür, başlık, kategori, zaman); createCourse mutation → manage/goals’a yönlendirme. |
| Müfredat | Section/Lesson (ve quiz, coding exercise) hiyerarşisi; curriculum sayfasında CRUD ve sıralama. |
| Video | Bunny CDN: yükleme → bunnyVideoId; izleme → generateSignedVideoUrl ile imzalı embed URL. |
| Performans | Öğrenci istatistikleri (performance/students); Recharts ile izlenme trendleri (performance/reviews). |
| Manuel ödeme | instructor.payouts: bakiye, requestPayout mutation, TR/Stripe Connect koşulları ve talep listesi. |
Detaylı ödeme akışları için Stripe Connect, TR Payout ve Checkout & Webhooks sayfalarına bakın.
İlgili Dosyalar
Section titled “İlgili Dosyalar”app/routes/instructor.create.tsx— Kurs oluşturma sihirbazı.app/routes/instructor.payouts.tsx— Eğitmen ödemeler ve payout talebi.app/routes/instructor.course.$slug.manage.curriculum.tsx— Müfredat ve video yükleme (Bunny).app/routes/instructor.course.$slug.manage.*.tsx— Goals, setup, filming, landing, pricing.app/lib/bunny-video-status.ts— Bunny video durumu; fetchBunnyVideoStatus, getBunnyVideoStatusKind.app/lib/video-security.ts— generateSignedVideoUrl.app/routes/api.lesson-resource-upload.ts— Ders kaynağı yükleme.