get_student_classes()#

Oturum açmış öğrencinin kayıtlı olduğu tüm sınıfları öğretmen bilgileriyle birlikte getiren fonksiyon.


Fonksiyon İmzası#

CREATE OR REPLACE FUNCTION get_student_classes()
RETURNS TABLE(...)
SECURITY DEFINER
SET search_path TO 'public'

Amaç#

Öğrencinin üye olduğu tüm sınıfları listeler. Her sınıf için öğretmen bilgilerini de getirir. Soft-delete edilmemiş (deleted_at IS NULL) üyelikler gösterilir. Sonuçlar katılma tarihine göre sıralanır.


Parametreler#

Bu fonksiyon parametre almaz. auth.uid() kullanarak oturum açmış kullanıcıyı otomatik tespit eder.


Dönüş Değeri#

Type: TABLE

Kolonlar#

KolonTipAçıklama
idINTEGERSınıf ID’si
nameVARCHARSınıf adı
codeVARCHARSınıf kodu (katılım kodu)
academic_yearVARCHARAkademik yıl (örn: “2024-2025”)
termVARCHARDönem (örn: “Güz”, “Bahar”)
school_idINTEGEROkul ID’si
teacher_idINTEGERÖğretmen ID’si
teacher_nameVARCHARÖğretmen adı
teacher_emailVARCHARÖğretmen e-posta
created_atTIMESTAMPSınıf oluşturulma tarihi
updated_atTIMESTAMPSınıf güncellenme tarihi

SQL Kodu#

CREATE OR REPLACE FUNCTION public.get_student_classes()
 RETURNS TABLE(
   id integer, 
   name character varying, 
   code character varying, 
   academic_year character varying, 
   term character varying, 
   school_id integer, 
   teacher_id integer, 
   teacher_name character varying, 
   teacher_email character varying, 
   created_at timestamp with time zone, 
   updated_at timestamp with time zone
 )
 LANGUAGE plpgsql
 SECURITY DEFINER
 SET search_path TO 'public'
AS $function$
DECLARE
  v_user_id int;
BEGIN
  SELECT u.id INTO v_user_id
  FROM users u
  WHERE u.auth_user_id = auth.uid();

  IF v_user_id IS NULL THEN
    RAISE EXCEPTION 'Oturum açmanız gerekiyor.';
  END IF;

  RETURN QUERY
  SELECT 
    c.id,
    c.name,
    c.code,
    c.academic_year,
    c.term,
    c.school_id,
    c.teacher_id,
    t.name as teacher_name,
    t.email as teacher_email,
    c.created_at,
    c.updated_at
  FROM classes c
  INNER JOIN class_members cm ON c.id = cm.class_id
  LEFT JOIN users t ON c.teacher_id = t.id
  WHERE cm.student_id = v_user_id
    AND cm.deleted_at IS NULL
  ORDER BY cm.joined_at DESC;
END;
$function$

Kullanım Örneği#

Projede Kullanım#

Dosya: lib/common/services/class_member_service.dart
Satır: ~116, ~304
Açıklama: Class member servisinde öğrencinin kayıtlı olduğu sınıfları getirmek için kullanılır.

/// Supabase RPC fonksiyonunu kullanıyoruz: get_student_classes()
final response = await _client.rpc('get_student_classes');

// Öğrenci için sınıf bilgisi al
final studentClasses = await _client.rpc('get_student_classes');

SQL Örneği#

-- Öğrenci olarak kendi sınıflarını listele
SELECT * FROM get_student_classes();

-- Sadece aktif dönem sınıflarını getir
SELECT * FROM get_student_classes()
WHERE academic_year = '2024-2025' AND term = 'Güz';

-- Belirli bir öğretmenin sınıflarını bul
SELECT * FROM get_student_classes()
WHERE teacher_name = 'Mehmet Hoca';

-- Sınıf ismi ve öğretmen ile listele
SELECT name, teacher_name, teacher_email
FROM get_student_classes();

Örnek Sonuç#

| id | name              | code     | academic_year | term  | teacher_name    | teacher_email          |
|----|-------------------|----------|---------------|-------|-----------------|------------------------|
| 15 | 10-A Matematik    | ABC123XY | 2024-2025     | Güz   | Mehmet Yılmaz   | mehmet@okul.edu.tr    |
| 8  | 9-B Fizik         | DEF456ZW | 2024-2025     | Güz   | Ayşe Demir      | ayse@okul.edu.tr      |
| 3  | 11-C Kimya        | GHI789QR | 2023-2024     | Bahar | Ali Kaya        | ali@okul.edu.tr       |

Özellikler#

  • Otomatik kullanıcı tespiti: auth.uid() ile
  • Soft-delete kontrolü: deleted_at IS NULL
  • LEFT JOIN: Öğretmen silinmiş olsa bile sınıf görünür
  • Sıralı sonuç: En son katıldığı sınıf en üstte
  • SECURITY DEFINER: Owner yetkisiyle çalışır

Sıralama#

ORDER BY cm.joined_at DESC

En son katıldığı sınıflar önce listelenir. Bu sayede aktif sınıflar üstte görünür.


Güvenlik#

  • auth.uid() kontrolü: Sadece kendi sınıflarını görebilir
  • SECURITY DEFINER: Fonksiyon owner yetkisiyle çalışır
  • SET search_path: SQL injection koruması

Hata Mesajları#

HataAçıklama
Oturum açmanız gerekiyor.auth.uid() NULL veya users tablosunda eşleşme yok

İlgili Tablolar#

  • public.classes
  • public.class_members
  • public.users (öğrenci ve öğretmen)
  • public.schools (dolaylı)

Veri Modeli#

users (student) 
    |
    | student_id
    |
class_members ----< class_id >---- classes ----< teacher_id >---- users (teacher)

Performans İpuçları#

  1. Index’ler:
CREATE INDEX idx_class_members_student_id ON class_members(student_id);
CREATE INDEX idx_class_members_deleted_at ON class_members(deleted_at);
CREATE INDEX idx_classes_teacher_id ON classes(teacher_id);
  1. Sayfalama (Pagination):
-- İlk 10 sınıf
SELECT * FROM get_student_classes() LIMIT 10;

-- Sonraki 10 sınıf
SELECT * FROM get_student_classes() LIMIT 10 OFFSET 10;

Mobil Uygulama Kullanımı#

// Flutter/Dart örneği
final response = await supabase
    .rpc('get_student_classes')
    .execute();

final classes = response.data as List;
for (var classData in classes) {
  print('${classData['name']} - ${classData['teacher_name']}');
}

İlgili Fonksiyonlar#

  • get_class_students() - Sınıftaki tüm öğrencileri listele
  • join_class_by_code() - Kod ile sınıfa katıl
  • get_class_syllabi() - Sınıf müfredatlarını listele

Notlar#

İpucu: Eğer öğrenci hiçbir sınıfa kayıtlı değilse, boş tablo döner (hata fırlatmaz).

Kullanım Senaryosu: Mobil uygulamada “Sınıflarım” ekranında kullanılır.

Dikkat: LEFT JOIN kullanıldığı için teacher_name NULL olabilir (öğretmen silinmişse).