Skip to content

API Referansı ve GraphQL

REST endpoint'leri (api.*.ts), GraphQL Yoga, Better Auth kimlik doğrulama ve session yönetimi.

Achidemy’de REST API route’ları (api.*.ts), GraphQL (GraphQL Yoga) ve Better Auth ile kimlik doğrulama/session yönetimi kullanılır. Bu sayfa tüm api.* endpoint’lerinin görev ve parametrelerini, api.graphql.ts üzerinden şema ve client entegrasyonunu ve Better Auth hook’ları ile session yönetimini özetler. Her endpoint’in ne için ve nasıl kullanıldığı, istek/yanıt formatları ve örnek çağrılar için Platform API Referansı sayfasına bakın.

REST Endpoints — api.*.ts Görevleri ve Parametreleri

Section titled “REST Endpoints — api.*.ts Görevleri ve Parametreleri”

Route tanımları app/routes.ts içindedir; dil prefix’i yok (/api/...).

EndpointDosyaMethodGörevParametreler / Gövde
POST /api/graphqlapi.graphql.tsGET/POSTGraphQL sorgu ve mutation; aşağıda ayrıca açıklanır.Body: { query, variables }
/api/auth/api.auth.ts*Better Auth handler; giriş, kayıt, çıkış, OAuth, şifre sıfırlama, session.Better Auth path’lerine göre (örn. sign-in/email, sign-up/email, sign-out, callback/google).
POST /api/stripe/webhookapi.stripe.webhook.tsPOSTStripe webhook; checkout.session.completed, payment_intent.succeeded, subscription vb.Stripe-Signature header; raw body imza doğrulaması.
POST /api/stripe/connect-onboardingapi.stripe.connect-onboarding.tsPOSTStripe Connect Express onboarding; Account Link ile yönlendirme.Form/cookie (session); redirect döner.
POST /api/moderate-textapi.moderate-text.tsPOSTCloudflare AI ile metin moderasyonu; yorumlar, mesajlar ve Q&A için ortak AI filtresi.JSON: { text: string } — dönüş: { isAllowed: boolean, reason: string }.
POST /api/instructor/update-manual-payoutapi.instructor.update-manual-payout.tsPOSTTR eğitmeni: manuel ödeme bilgisi (IBAN/Payoneer) güncelleme.FormData: details (string). Yetki: session + role instructor.
POST /api/lesson-resource-uploadapi.lesson-resource-upload.tsPOSTDers kaynağı (PDF vb.) yükleme; Bunny Storage.FormData: lessonId, file. Yetki: eğitmen (kurs sahibi). Env: BUNNY_STORAGE_*.
POST /api/lesson/caption-uploadapi.lesson.caption-upload.tsPOSTVideo altyazısı (.vtt) yükleme; Bunny Stream + lesson_captions.FormData: lessonId, captionFile, langCode, label. Env: BUNNY_LIBRARY_ID, BUNNY_API_KEY / BUNNY_STREAM_API_KEY.
POST /api/lesson/caption-deleteapi.lesson.caption-delete.tsPOSTVideo altyazısı silme; Bunny Stream + lesson_captions.FormData: captionId. Env: BUNNY_LIBRARY_ID, BUNNY_API_KEY / BUNNY_STREAM_API_KEY.
POST /api/chat-image-uploadapi.chat-image-upload.tsPOSTMesajda görsel yükleme; Bunny Storage.FormData: file (image/jpeg,png,gif,webp). Dönüş: { url }. Env: BUNNY_STORAGE_*, BUNNY_PULL_ZONE_URL.
GET /api/certificate/:id/downloadapi.certificate.$id.download.tsGETSertifika PDF indirme.Path: id (sertifika UUID). Yetki: session; sertifika userId eşleşmeli.
GET /api/certificates/:id/download(aynı dosya)GETAynı; plural URL (geriye dönük uyumluluk).Aynı.
GET /api/invoice/:enrollmentId/downloadapi.invoice.$enrollmentId.download.tsGETSatın alma faturası PDF indirme.Path: enrollmentId. Yetki: session; enrollment userId eşleşmeli.
GET /api/admin/activitiesapi.admin.activities.tsGETAdmin “Tüm bildirimler” modalı; ödeme talepleri + kurs onayları.Yetki: session + role admin. Dönüş: { activities } (JSON).
POST /api/video-telemetryapi.video-telemetry.tsPOSTVideo telemetri heartbeat (15 sn blok); watch_time_logs insert + daily_activities upsert + subscription_watch_logs upsert + streak tetikleme + Enterprise anti‑cheat (payout koruması).JSON: courseId, lessonId, durationSeconds (genelde 15), timestamp?. Session zorunlu.
POST /api/update-progressapi.update-progress.tsPOST(Legacy) Video izleme ilerlemesi (saniye) kaydı; user_lessons_progress, daily_activities, subscription_watch_logs.JSON: userId, lessonId, courseId, instructorId, secondsWatched, isSubscription.
GET /api/algolia-syncapi.algolia-sync.tsGETTüm yayındaki kursları Algolia arama index’ine toplu senkronize eder; index ayarlarını (searchableAttributes, typoTolerance) yapılandırır. Tek seferlik başlangıç verisi aktarımı için.Parametre yok. Env: VITE_ALGOLIA_APP_ID, ALGOLIA_ADMIN_KEY. Dönüş: { settings, sync: { synced }, totalPublished }.

Not: api.exercise-resource-upload.ts ve api.quiz-resource-upload.ts projede dosya olarak vardır; routes.ts içinde route tanımı yoksa doğrudan /api/... ile erişilmez (iç kullanım veya farklı mount edilmiş olabilir). Dokümante edilen liste routes.ts’teki API route’larına göredir.

Veri için route loader, form/mutation için action kullanılır.

Dosya: app/routes/api.graphql.ts
Endpoint: POST /api/graphql (GET de desteklenir; Yoga varsayılanı).

Akış:

  1. context.cloudflare.env ve getDbUrl(env) ile DB bağlantısı; initAuth(dbUrl, env, context.cloudflare?.ctx) ile Better Auth (Cloudflare ctx.waitUntil ile arka plan e-posta gönderimi desteklenir).
  2. auth.api.getSession({ headers: request.headers }) ile oturum alınır.
  3. createYoga (graphql-yoga) ile Yoga instance: schema (app/graphql/schema.ts), graphqlEndpoint: "/api/graphql", context fonksiyonu db, request, user (session?.user + role), cloudflare (bölgesel fiyat/ülke için) döner.
  4. yoga.handleRequest(request) ile istek işlenir; GET (GraphiQL/playground) ve POST (sorgu) desteklenir.

Performans notu: GraphQL şeması içinde ağır sorgular (ör. categoryTree, adminStats, enrolledCourses) N+1 sorgu problemi olmadan, toplu SQL (group by) ve in‑memory cache ile optimize edilmiştir. Cloudflare Workers üzerinde global scope değişkenleri (Map) ardışık istekler arasında RAM’de tutulur; bu sayede categoryTree sonucu 1 saatlik TTL ile bellekte saklanır, admin istatistikleri ve öğrenci kurs listesi ise tek seferde toplu sorgular ile hesaplanır.

Şema tanımları: app/graphql/schema.ts

  • createSchema (graphql-yoga) ile tek bir şema: typeDefs (SDL string) + resolvers (Query, Mutation, tipler).
  • GraphQLContext: { db, request?, user?, cloudflare? } — resolver’lar user ile yetkilendirme, request ile cookie/header, cloudflare ile request.cf (ülke) kullanır.
  • Tipler: User, Course, Enrollment, Review, Certificate, PayoutRequest, CartItem, CourseBundle vb.
  • Query örnekleri: courses, courseBySlug, me, myCertificates, conversationMessages, unreadMessagesCount, admin için listeler vb.
  • Mutation örnekleri: createCourse, updateCourse, toggleLessonCompletion, recordLearningActivity, requestPayout, createStripeCheckoutSession, addBundleToCart, createBundleCheckoutSession, addToCart, createReview, reportCourse (kurs şikayet sistemi; DMCA / içerik ihlali) vb. Paket checkout ve vitrin: Kurs ve Paket Vitrin Sayfaları.

Client entegrasyonu: Uygulama içinde fetch("/api/graphql", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ query, variables }) }) ile sorgu/mutation atılır; cookie ile session gönderilir (credentials: “include”). Dil prefix’i yok; base URL’e göre /api/graphql kullanılır.

  • SDL:
    • input ReportCourseInput { courseId: ID!, reason: String!, description: String }
    • reportCourse(input: ReportCourseInput!): Boolean
  • Amaç: Öğrencilerin kursları DMCA / içerik ihlali / spam gibi sebeplerle şikayet etmesini sağlamak.
  • Yetki: Sadece giriş yapmış kullanıcılar; anonim kullanıcılar için resolver "Şikayet oluşturmak için giriş yapmalısınız." hatası üretir.
  • Veritabanı: course_reports tablosuna insert; courseId, reporterId, reason, description, status="pending" ve createdAt alanları doldurulur.
  • Otomatik kalkan: Pending şikayet sayısı 5’e ulaştığında kurs otomatik pending_review yapılır ve eğitmene bildirim gönderilir.
  • Kullanım: ReportCourseModal bileşeni (app/components/courses/ReportCourseModal.tsx), kurs detay sayfasında /api/graphql üzerinden bu mutasyonu çağırır.

AI Şikayet Analizi — analyzeCourseReports

Section titled “AI Şikayet Analizi — analyzeCourseReports”
  • SDL: analyzeCourseReports(courseId: ID!): AIReportAnalysis
  • Dönüş: { summary, commonReasons, extractedLinks, criticalityScore, recommendation }
  • Yetki: Sadece admin.
  • Amaç: Bir kursa gelen tüm şikayetleri Cloudflare AI (Llama 3.1 8B) ile özetlemek; ortak nedenler, linkler ve kritiklik skoru üretir.
  • Kullanım: /admin/reports/:courseId sayfasında AIReportAnalyzer bileşeni.

AI Kurs Kalite Ön İncelemesi — analyzeCourseContentForAdmin

Section titled “AI Kurs Kalite Ön İncelemesi — analyzeCourseContentForAdmin”
  • SDL: analyzeCourseContentForAdmin(courseId: ID!): AICourseAnalysis
  • Dönüş: { summary, contentIssues, missingAssets, profanityDetected, qualityScore, recommendation }
  • Yetki: Sadece admin.
  • Amaç: Kurs başlığı, açıklaması, müfredatı, fiyatı ve eksik asset’leri (kapak, tanıtım videosu) Cloudflare AI ile analiz etmek.
  • Kullanım: /admin/course/:slug/preview sayfasında AICourseReviewer bileşeni (app/components/admin/AICourseReviewer.tsx).

Detaylı açıklama için Yapay Zeka Destekli Moderasyon sayfasına bakın.

Better Auth — Kimlik Doğrulama Hook’ları ve Session Yönetimi

Section titled “Better Auth — Kimlik Doğrulama Hook’ları ve Session Yönetimi”

Base path: /api/auth
Dosya: app/routes/api.auth.ts — tüm istekler auth.handler(request) ile Better Auth’a iletilir.

Konfigürasyon: app/lib/auth.tsbetterAuth({ ... })

  • basePath: /api/auth
  • baseURL: env BASE_URL veya localhost
  • database: Drizzle adapter (PostgreSQL); user, session, account, verification tabloları.
  • socialProviders: Google (clientId, clientSecret; overrideUserInfoOnSignIn: true).
  • emailAndPassword: enabled; sendResetPassword (şifre sıfırlama linki, dil destekli URL); onPasswordReset; resetPasswordTokenExpiresIn: 3600.
  • emailVerification: enabled; sendOnSignUp: true; sendVerificationEmail (dil destekli verify-email URL); afterEmailVerification.
  • user.additionalFields: role (string, default “student”), onboardingCompleted (boolean), stripeCustomerId (string).
  • databaseHooks:
    • user.create.after: OAuth ile oluşturmada imagegoogleImage güncellemesi; emailVerified ise hoş geldin e-postası (sendWelcomeEmail).
    • user.update.after: Google ile giriş/güncellemede imagegoogleImage senkronizasyonu.

Session yönetimi: Better Auth, cookie tabanlı session kullanır. auth.api.getSession({ headers: request.headers }) ile mevcut oturum okunur; resolver’lar ve API route’ları bu session’a göre user ve yetki kontrolü yapar. Çıkış: /api/auth/sign-out (Better Auth endpoint’i).

Kullanım: Login/register sayfaları Better Auth client (örn. signIn.email, signUp.email) ile /api/auth path’lerini tetikler; callback ve redirect’ler BASE_URL ve dil path’ine göre yapılandırılır.

KonuAçıklama
REST api.*routes.ts’te tanımlı endpoint’ler: graphql, auth/*, stripe/webhook, stripe/connect-onboarding, moderate-text, instructor/update-manual-payout, lesson-resource-upload, lesson/caption-upload, lesson/caption-delete, chat-image-upload, certificate(s)/:id/download, invoice/:enrollmentId/download, admin/activities, video-telemetry (heartbeat), update-progress (legacy).
GraphQLPOST /api/graphql; Yoga + schema (typeDefs + resolvers); context: db, request, user, cloudflare. Client: fetch + credentials.
Better Auth/api/auth/* → auth.handler; Drizzle + Google + email/password + verification + reset; databaseHooks (user create/update); session cookie ile getSession.

İlgili mimari: Checkout & Webhooks (Stripe webhook), Stripe Connect (connect-onboarding), TR Payout (update-manual-payout), Video Altyazıları (caption-upload, caption-delete), Öğrenme Deneyimi (video-telemetry), Kurs ve Paket Vitrin Sayfaları (bundle checkout), İletişim (chat-image-upload).

  • app/routes/api.graphql.ts — GraphQL Yoga endpoint; şema ve context.
  • app/routes/api.auth.ts — Better Auth handler (tüm /api/auth/*).
  • app/graphql/schema.ts — GraphQL typeDefs ve resolvers.
  • app/lib/auth.ts — Better Auth yapılandırması.
  • app/lib/graphql-client.ts — Uygulama içi GraphQL istemcisi.