
-- --------------------------------------------------------
-- Table: migrations
-- --------------------------------------------------------
CREATE TABLE `migrations` (
  `id` INT AUTO_INCREMENT PRIMARY KEY,
  `migration` VARCHAR(255) NOT NULL,
  `batch` INT NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT INTO `migrations` VALUES(1,'0001_01_01_000000_create_users_table',1);
INSERT INTO `migrations` VALUES(2,'0001_01_01_000001_create_cache_table',1);
INSERT INTO `migrations` VALUES(3,'0001_01_01_000002_create_jobs_table',1);
INSERT INTO `migrations` VALUES(4,'2024_01_01_000000_create_semesters_courses_table',1);
INSERT INTO `migrations` VALUES(5,'2024_01_01_000001_create_materials_table',1);
INSERT INTO `migrations` VALUES(6,'2024_01_01_000002_create_posts_comments_table',1);
INSERT INTO `migrations` VALUES(7,'2024_01_01_000004_create_gamification_tables',1);
INSERT INTO `migrations` VALUES(8,'2026_05_03_140512_create_daily_check_ins_table',1);

-- --------------------------------------------------------
-- Table: sessions
-- --------------------------------------------------------
CREATE TABLE `sessions` (
  `id` VARCHAR(255) NOT NULL,
  `user_id` INT DEFAULT NULL,
  `ip_address` VARCHAR(45) DEFAULT NULL,
  `user_agent` TEXT DEFAULT NULL,
  `payload` TEXT NOT NULL,
  `last_activity` INT NOT NULL,
  PRIMARY KEY (`id`),
  KEY `sessions_user_id_index` (`user_id`),
  KEY `sessions_last_activity_index` (`last_activity`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT INTO `sessions` VALUES('6QHycy0dfIFiiQjja6KYusRAzRUw3kMNVBa7PjQP',NULL,'127.0.0.1','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Code/1.126.0 Chrome/148.0.7778.97 Electron/42.2.0 Safari/537.36','eyJfdG9rZW4iOiI2T1NndnB1dElhZlRzTkdsYnFFSzZUbjA4c0xJSDRvM21xMUEyb0t6IiwiX3ByZXZpb3VzIjp7InVybCI6Imh0dHA6XC9cLzEyNy4wLjAuMTo4MDAwIiwicm91dGUiOiJob21lIn0sIl9mbGFzaCI6eyJvbGQiOltdLCJuZXciOltdfX0=',1782698837);
INSERT INTO `sessions` VALUES('315Hk3a5rWkEOrmNb49HZwtIL9sOI8L6VyARluFt',6,'127.0.0.1','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Code/1.126.0 Chrome/148.0.7778.97 Electron/42.2.0 Safari/537.36','eyJfdG9rZW4iOiJxQVJPdEx3NlZtZ2hCUEN2QUF0WXVVSlppcVdZbjB5akdIcDROcmVwIiwiX3ByZXZpb3VzIjp7InVybCI6Imh0dHA6XC9cLzEyNy4wLjAuMTo4MDAwXC9kYXNoYm9hcmQiLCJyb3V0ZSI6ImRhc2hib2FyZCJ9LCJfZmxhc2giOnsib2xkIjpbXSwibmV3IjpbXX0sImxvZ2luX3dlYl81OWJhMzZhZGRjMmIyZjk0MDE1ODBmMDE0YzdmNThlYTRlMzA5ODlkIjo2fQ==',1782698998);
INSERT INTO `sessions` VALUES('ixxqefdJOg9auwuYTD31LaLNhgps5hKZgW7jKpCC',6,'127.0.0.1','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/149.0.0.0 Safari/537.36 Edg/149.0.0.0','eyJfdG9rZW4iOiJEZ2JTT3FIcFlLUG9EOU14TWxhczgzSjk4VlNhWXluYXNuZ09lak1pIiwidXJsIjpbXSwiX3ByZXZpb3VzIjp7InVybCI6Imh0dHA6XC9cLzEyNy4wLjAuMTo4MDAwXC9wcm9maWxlXC8yIiwicm91dGUiOiJwcm9maWxlIn0sIl9mbGFzaCI6eyJvbGQiOltdLCJuZXciOltdfSwibG9naW5fd2ViXzU5YmEzNmFkZGMyYjJmOTQwMTU4MGYwMTRjN2Y1OGVhNGUzMDk4OWQiOjZ9',1782701619);
INSERT INTO `sessions` VALUES('gVVqefiOqMtuxvT6sQFnGWQM1i3KmuUEyjdYTRsB',7,'127.0.0.1','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Code/1.128.0 Chrome/148.0.7778.271 Electron/42.5.0 Safari/537.36','eyJfdG9rZW4iOiJuMjN5SGFlNmtqd0pHazg0RXI4M3h2aWhSQ3huSXZQYzZCSllONlRmIiwiX3ByZXZpb3VzIjp7InVybCI6Imh0dHA6XC9cLzEyNy4wLjAuMTo4MDAwXC9kYXNoYm9hcmQiLCJyb3V0ZSI6ImRhc2hib2FyZCJ9LCJfZmxhc2giOnsib2xkIjpbXSwibmV3IjpbXX0sImxvZ2luX3dlYl81OWJhMzZhZGRjMmIyZjk0MDE1ODBmMDE0YzdmNThlYTRlMzA5ODlkIjo3fQ==',1783862883);
INSERT INTO `sessions` VALUES('d6yiNc5zQarxNBFdbUTYmSRFh4e1m3S7LoNllTHS',7,'127.0.0.1','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0','eyJfdG9rZW4iOiIyOFE3M2gybkczNG9JNDVURE1IYnJUNjE5TTlNbE14MkwwVFRjZHM5IiwidXJsIjpbXSwiX3ByZXZpb3VzIjp7InVybCI6Imh0dHA6XC9cLzEyNy4wLjAuMTo4MDAwXC9sb2dpbiIsInJvdXRlIjoibG9naW4ifSwiX2ZsYXNoIjp7Im9sZCI6W10sIm5ldyI6W119LCJsb2dpbl93ZWJfNTliYTM2YWRkYzJiMmY5NDAxNTgwZjAxNGM3ZjU4ZWE0ZTMwOTg5ZCI6N30=',1783862964);
INSERT INTO `sessions` VALUES('mTXo02BVBaPe49FpTUJfo3z3ugJVYtMPpCFUlweL',7,'127.0.0.1','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0','eyJfdG9rZW4iOiJudzZXWVltR0JCOG1COUNZUnkwOU1pNE9ROGVVcGZTajZuQmpFcmVzIiwibG9naW5fd2ViXzU5YmEzNmFkZGMyYjJmOTQwMTU4MGYwMTRjN2Y1OGVhNGUzMDk4OWQiOjcsIl9mbGFzaCI6eyJvbGQiOltdLCJuZXciOltdfSwiX3ByZXZpb3VzIjp7InVybCI6Imh0dHA6XC9cLzEyNy4wLjAuMTo4MDAwXC9mb3J1bSIsInJvdXRlIjoiZm9ydW0uaW5kZXgifX0=',1783863105);

-- --------------------------------------------------------
-- Table: jobs
-- --------------------------------------------------------
CREATE TABLE `jobs` (
  `id` INT AUTO_INCREMENT PRIMARY KEY,
  `queue` VARCHAR(255) NOT NULL,
  `payload` LONGTEXT NOT NULL,
  `attempts` INT NOT NULL,
  `reserved_at` INT DEFAULT NULL,
  `available_at` INT NOT NULL,
  `created_at` INT NOT NULL,
  KEY `jobs_queue_index` (`queue`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- --------------------------------------------------------
-- Table: job_batches
-- --------------------------------------------------------
CREATE TABLE `job_batches` (
  `id` VARCHAR(255) NOT NULL,
  `name` VARCHAR(255) NOT NULL,
  `total_jobs` INT NOT NULL,
  `pending_jobs` INT NOT NULL,
  `failed_jobs` INT NOT NULL,
  `failed_job_ids` TEXT NOT NULL,
  `options` TEXT,
  `cancelled_at` INT DEFAULT NULL,
  `created_at` INT NOT NULL,
  `finished_at` INT DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- --------------------------------------------------------
-- Table: failed_jobs
-- --------------------------------------------------------
CREATE TABLE `failed_jobs` (
  `id` INT AUTO_INCREMENT PRIMARY KEY,
  `uuid` VARCHAR(255) NOT NULL,
  `connection` TEXT NOT NULL,
  `queue` TEXT NOT NULL,
  `payload` LONGTEXT NOT NULL,
  `exception` LONGTEXT NOT NULL,
  `failed_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  UNIQUE KEY `failed_jobs_uuid_unique` (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- --------------------------------------------------------
-- Table: semesters
-- --------------------------------------------------------
CREATE TABLE `semesters` (
  `id` INT AUTO_INCREMENT PRIMARY KEY,
  `name` VARCHAR(255) NOT NULL,
  `year` VARCHAR(255) DEFAULT NULL,
  `order` INT NOT NULL DEFAULT 1,
  `color` VARCHAR(255) DEFAULT NULL,
  `is_active` TINYINT(1) NOT NULL DEFAULT 1,
  `created_at` DATETIME DEFAULT NULL,
  `updated_at` DATETIME DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT INTO `semesters` VALUES(1,'Semester 1','2023/2024',1,'#6EE7B7',1,'2026-05-04 01:41:59','2026-05-04 01:41:59');
INSERT INTO `semesters` VALUES(2,'Semester 2','2023/2024',2,'#60A5FA',1,'2026-05-04 01:41:59','2026-05-04 01:41:59');
INSERT INTO `semesters` VALUES(3,'Semester 3','2024/2025',3,'#F472B6',1,'2026-05-04 01:41:59','2026-05-04 01:41:59');
INSERT INTO `semesters` VALUES(4,'Semester 4','2024/2025',4,'#FBBF24',1,'2026-05-04 01:41:59','2026-05-04 01:41:59');
INSERT INTO `semesters` VALUES(5,'Semester 5','2025/2026',5,'#A78BFA',1,'2026-05-04 01:41:59','2026-05-04 01:41:59');
INSERT INTO `semesters` VALUES(6,'Semester 6','2025/2026',6,'#34D399',1,'2026-05-04 01:41:59','2026-05-04 01:41:59');

-- --------------------------------------------------------
-- Table: courses
-- --------------------------------------------------------
CREATE TABLE `courses` (
  `id` INT AUTO_INCREMENT PRIMARY KEY,
  `semester_id` INT NOT NULL,
  `name` VARCHAR(255) NOT NULL,
  `code` VARCHAR(255) DEFAULT NULL,
  `description` TEXT DEFAULT NULL,
  `icon` VARCHAR(255) DEFAULT NULL,
  `created_at` DATETIME DEFAULT NULL,
  `updated_at` DATETIME DEFAULT NULL,
  FOREIGN KEY (`semester_id`) REFERENCES `semesters` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT INTO `courses` VALUES(1,1,'Algoritma & Pemrograman','RPL-101','Mata kuliah Algoritma & Pemrograman prodi RPL.','⚙️','2026-05-04 01:41:59','2026-05-04 01:41:59');
INSERT INTO `courses` VALUES(2,1,'Basis Data','RPL-102','Mata kuliah Basis Data prodi RPL.','🗄️','2026-05-04 01:41:59','2026-05-04 01:41:59');
INSERT INTO `courses` VALUES(3,1,'Matematika Diskrit','RPL-103','Mata kuliah Matematika Diskrit prodi RPL.','🔢','2026-05-04 01:41:59','2026-05-04 01:41:59');
INSERT INTO `courses` VALUES(4,2,'Pemrograman Web Dasar','RPL-201','Mata kuliah Pemrograman Web Dasar prodi RPL.','🌐','2026-05-04 01:41:59','2026-05-04 01:41:59');
INSERT INTO `courses` VALUES(5,2,'Jaringan Komputer','RPL-202','Mata kuliah Jaringan Komputer prodi RPL.','🔌','2026-05-04 01:41:59','2026-05-04 01:41:59');
INSERT INTO `courses` VALUES(6,3,'Pemrograman Berorientasi Objek','RPL-301','Mata kuliah Pemrograman Berorientasi Objek prodi RPL.','🧩','2026-05-04 01:41:59','2026-05-04 01:41:59');
INSERT INTO `courses` VALUES(7,3,'Rekayasa Perangkat Lunak','RPL-302','Mata kuliah Rekayasa Perangkat Lunak prodi RPL.','🔧','2026-05-04 01:41:59','2026-05-04 01:41:59');
INSERT INTO `courses` VALUES(8,4,'Framework Web Laravel','RPL-401','Mata kuliah Framework Web Laravel prodi RPL.','🚀','2026-05-04 01:41:59','2026-05-04 01:41:59');
INSERT INTO `courses` VALUES(9,4,'Mobile Programming','RPL-402','Mata kuliah Mobile Programming prodi RPL.','📱','2026-05-04 01:41:59','2026-05-04 01:41:59');
INSERT INTO `courses` VALUES(10,5,'Cloud Computing','RPL-501','Mata kuliah Cloud Computing prodi RPL.','☁️','2026-05-04 01:41:59','2026-05-04 01:41:59');
INSERT INTO `courses` VALUES(11,5,'Keamanan Sistem Informasi','RPL-502','Mata kuliah Keamanan Sistem Informasi prodi RPL.','🔒','2026-05-04 01:41:59','2026-05-04 01:41:59');
INSERT INTO `courses` VALUES(12,6,'Proyek Akhir / Skripsi','RPL-601','Mata kuliah Proyek Akhir / Skripsi prodi RPL.','🎓','2026-05-04 01:42:00','2026-05-04 01:42:00');

-- --------------------------------------------------------
-- Table: materials
-- --------------------------------------------------------
CREATE TABLE `materials` (
  `id` INT AUTO_INCREMENT PRIMARY KEY,
  `course_id` INT NOT NULL,
  `uploaded_by` INT NOT NULL,
  `title` VARCHAR(255) NOT NULL,
  `description` TEXT DEFAULT NULL,
  `file_path` VARCHAR(255) NOT NULL,
  `file_type` ENUM('pdf', 'slide', 'code', 'other') NOT NULL DEFAULT 'other',
  `file_size` INT NOT NULL DEFAULT 0,
  `download_count` INT NOT NULL DEFAULT 0,
  `created_at` DATETIME DEFAULT NULL,
  `updated_at` DATETIME DEFAULT NULL,
  FOREIGN KEY (`course_id`) REFERENCES `courses` (`id`) ON DELETE CASCADE,
  FOREIGN KEY (`uploaded_by`) REFERENCES `users` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT INTO `materials` VALUES(1,1,2,'Modul 1 — Pengantar Algoritma & Flowchart','Materi pengantar algoritma, cara membuat flowchart, dan penulisan pseudocode yang benar. Dilengkapi latihan soal.','sample-algo-modul1.txt','pdf',204800,47,'2026-05-04 01:42:00','2026-05-04 01:42:00');
INSERT INTO `materials` VALUES(2,6,2,'Slide OOP — Class, Inheritance & Polymorphism','Slide perkuliahan Pemrograman Berorientasi Objek. Mencakup konsep dasar OOP: class, object, encapsulation, inheritance, dan polymorphism dengan contoh kode Java.','sample-pbo-slide-oop.txt','slide',1572864,83,'2026-05-04 01:42:00','2026-05-04 01:42:00');
INSERT INTO `materials` VALUES(3,8,2,'Source Code CRUD Laravel 11 — Blog Sederhana','Source code lengkap project CRUD sederhana menggunakan Laravel 11. Termasuk: Model, Controller, Migration, Seeder, dan View Blade. Cocok sebagai referensi tugas.','sample-laravel-crud.txt','code',512000,121,'2026-05-04 01:42:00','2026-05-04 01:42:00');

-- --------------------------------------------------------
-- Table: posts
-- --------------------------------------------------------
CREATE TABLE `posts` (
  `id` INT AUTO_INCREMENT PRIMARY KEY,
  `user_id` INT NOT NULL,
  `course_id` INT NOT NULL,
  `material_id` INT DEFAULT NULL,
  `title` VARCHAR(255) NOT NULL,
  `body` TEXT NOT NULL,
  `has_code_snippet` TINYINT(1) NOT NULL DEFAULT 0,
  `code_snippet` TEXT DEFAULT NULL,
  `code_language` VARCHAR(255) NOT NULL DEFAULT 'php',
  `is_solved` TINYINT(1) NOT NULL DEFAULT 0,
  `views` INT NOT NULL DEFAULT 0,
  `upvotes` INT NOT NULL DEFAULT 0,
  `created_at` DATETIME DEFAULT NULL,
  `updated_at` DATETIME DEFAULT NULL,
  FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
  FOREIGN KEY (`course_id`) REFERENCES `courses` (`id`) ON DELETE CASCADE,
  FOREIGN KEY (`material_id`) REFERENCES `materials` (`id`) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT INTO `posts` VALUES(1,3,8,NULL,'Error: Class \"App\\Http\\Controllers\\Controller\" not found di Laravel 11','Halo teman-teman, saya baru upgrade project dari Laravel 10 ke Laravel 11 dan tiba-tiba muncul error ini:\n\n\"Class App\\Http\\Controllers\\Controller not found\"\n\nSaya sudah cek file Controller.php di folder Http/Controllers tapi filenya tidak ada. Apakah memang dihapus di Laravel 11? Bagaimana cara mengatasinya?\n\nSudah coba:\n- php artisan clear-compiled\n- composer dump-autoload\n\nTapi error masih muncul. Mohon bantuan!',1,'// Error muncul saat extends Controller\nnamespace App\\Http\\Controllers;\n\nuse App\\Http\\Controllers\\Controller; // <- error di sini\n\nclass PostController extends Controller\n{\n    public function index()\n    {\n        return view(\'posts.index\');\n    }\n}','php',1,142,18,'2026-05-04 01:42:00','2026-05-04 01:42:00');
INSERT INTO `posts` VALUES(2,4,6,NULL,'Perbedaan Abstract Class vs Interface di Java, kapan pakai yang mana?','Lagi belajar OOP dan bingung bedanya abstract class sama interface di Java.\n\nDari yang saya baca:\n- Abstract class bisa punya method dengan body\n- Interface semua method harus abstract (tapi di Java 8+ bisa default method)\n\nTapi kapan sebaiknya pakai abstract class dan kapan pakai interface? Ada contoh real case-nya ga? Terutama di konteks project Laravel atau aplikasi web.',1,'// Ini yang saya coba tapi masih bingung bedanya\ninterface Drawable {\n    void draw(); // harus diimplementasi semua\n}\n\nabstract class Shape {\n    String color;\n    \n    abstract void draw(); // wajib override\n    \n    void setColor(String c) { // bisa punya implementasi\n        this.color = c;\n    }\n}','java',0,67,9,'2026-05-04 01:42:00','2026-05-04 01:42:00');
INSERT INTO `posts` VALUES(3,3,4,NULL,'Cara fetch API dengan JavaScript async/await','Bagaimana cara yang benar untuk handle error di async/await?',1,'// Contoh fetch sederhana\nasync function fetchData() {\n    const response = await fetch(\'https://api.example.com/data\');\n    const data = await response.json();\n    console.log(data);\n}','javascript',0,0,0,'2026-05-04 01:42:00','2026-05-04 01:42:00');
INSERT INTO `posts` VALUES(4,4,2,NULL,'Kapan pakai INNER JOIN vs LEFT JOIN di MySQL?','Tugas basis data saya minta ambil data mahasiswa beserta nilai mereka. Saya bingung pakai INNER JOIN atau LEFT JOIN.\n\nKalau pakai INNER JOIN, mahasiswa yang belum punya nilai tidak muncul. Kalau LEFT JOIN, semua mahasiswa muncul tapi yang belum ada nilai kolom nilainya NULL.\n\nMana yang lebih benar dipakai? Dan apakah ada performance difference-nya?',1,'-- INNER JOIN: hanya mahasiswa yang punya nilai\nSELECT m.nama, n.nilai\nFROM mahasiswa m\nINNER JOIN nilai n ON m.id = n.mahasiswa_id;\n\n-- LEFT JOIN: semua mahasiswa, yang belum ada nilai = NULL\nSELECT m.nama, n.nilai\nFROM mahasiswa m\nLEFT JOIN nilai n ON m.id = n.mahasiswa_id;','sql',1,203,24,'2026-05-04 01:42:00','2026-05-04 01:42:00');
INSERT INTO `posts` VALUES(5,3,8,NULL,'Cara implementasi fitur \"Remember Me\" yang aman di Laravel','Saya mau tambahkan fitur remember me di form login Laravel...',1,'public function login(Request $request)\r\n{\r\n    $credentials = $request->validate([\r\n        \'email\'    => \'required|email\',\r\n        \'password\' => \'required\',\r\n    ]);\r\n\r\n    if (Auth::attempt($credentials, $request->boolean(\'remember\'))) {\r\n        $request->session()->regenerate();\r\n        return redirect()->intended(\'/dashboard\');\r\n    }\r\n        \r\n    return back()->withErrors([\'email\' => \'Kredensial tidak valid.\']);\r\n}','php',0,34,6,'2026-05-04 01:42:00','2026-05-04 01:42:00');

-- --------------------------------------------------------
-- Table: comments
-- --------------------------------------------------------
CREATE TABLE `comments` (
  `id` INT AUTO_INCREMENT PRIMARY KEY,
  `user_id` INT NOT NULL,
  `post_id` INT DEFAULT NULL,
  `material_id` INT DEFAULT NULL,
  `parent_id` INT DEFAULT NULL,
  `body` TEXT NOT NULL,
  `has_code_snippet` TINYINT(1) NOT NULL DEFAULT 0,
  `code_snippet` TEXT DEFAULT NULL,
  `code_language` VARCHAR(255) NOT NULL DEFAULT 'php',
  `is_verified_solution` TINYINT(1) NOT NULL DEFAULT 0,
  `upvotes` INT NOT NULL DEFAULT 0,
  `created_at` DATETIME DEFAULT NULL,
  `updated_at` DATETIME DEFAULT NULL,
  FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
  FOREIGN KEY (`post_id`) REFERENCES `posts` (`id`) ON DELETE CASCADE,
  FOREIGN KEY (`material_id`) REFERENCES `materials` (`id`) ON DELETE CASCADE,
  FOREIGN KEY (`parent_id`) REFERENCES `comments` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT INTO `comments` VALUES(1,2,1,NULL,NULL,'Di Laravel 11, base Controller sudah dihapus dari folder Http/Controllers secara default. Ada dua solusi:\n\n**Solusi 1 (Cepat):** Buat manual file Controller.php\n\n**Solusi 2 (Proper):** Langsung extends dari Illuminate foundation saja tanpa intermediate class.',1,'<?php\n// Buat file: app/Http/Controllers/Controller.php\nnamespace App\\Http\\Controllers;\n\nabstract class Controller\n{\n    //\n}\n\n// ATAU langsung extends dari:\nuse Illuminate\\Routing\\Controller as BaseController;\n\nclass PostController extends BaseController\n{\n    // ...\n}','php',1,12,'2026-05-04 01:42:00','2026-05-04 01:42:00');
INSERT INTO `comments` VALUES(2,4,1,NULL,1,'Makasih Pak! Solusi pertama berhasil. Ternyata memang dihapus di L11 ya. Baru tahu 😅',0,NULL,'php',0,0,'2026-05-04 01:42:00','2026-05-04 01:42:00');
INSERT INTO `comments` VALUES(3,3,2,NULL,NULL,'Gampangnya gini:\n- **Interface** = kontrak \"bisa melakukan apa\" (kemampuan). Satu class bisa implement banyak interface.\n- **Abstract class** = template \"adalah apa\" (hubungan is-a). Satu class hanya bisa extends satu abstract class.\n\nContoh: Burung dan Pesawat sama-sama bisa terbang (implement interface Flyable), tapi keduanya beda jenis (tidak perlu extend class yang sama).',0,NULL,'php',0,5,'2026-05-04 01:42:00','2026-05-04 01:42:00');
INSERT INTO `comments` VALUES(4,2,3,NULL,NULL,'Gunakan try-catch dan selalu cek response.ok.',1,'async function fetchData(url) {\r\n    try {\r\n        const response = await fetch(url);\r\n        if (!response.ok) {\r\n            throw new Error(`HTTP error! status: ${response.status}`);\r\n        }\r\n        const data = await response.json();\r\n        return data;\r\n    } catch (error) {\r\n        console.error(\'API error:\', error.message);\r\n        return null;\r\n    }\r\n}','javascript',0,8,'2026-05-04 01:42:00','2026-05-04 01:42:00');
INSERT INTO `comments` VALUES(5,2,4,NULL,NULL,'Tergantung kebutuhan bisnis:\n\n- **INNER JOIN** → pakai kalau kamu HANYA mau data yang ada relasinya. Contoh: laporan nilai (tidak perlu tampilkan mahasiswa yang belum ada nilainya sama sekali).\n\n- **LEFT JOIN** → pakai kalau kamu mau SEMUA data dari tabel kiri meskipun tidak ada relasi. Contoh: daftar mahasiswa lengkap + nilai (kalau belum ada nilai, tampilkan NULL).\n\nUntuk performa: INNER JOIN biasanya sedikit lebih cepat karena dataset lebih kecil, tapi bedanya tidak signifikan kalau index sudah benar.',1,'-- Contoh praktis: rekap nilai per mahasiswa\nSELECT \n    m.nim,\n    m.nama,\n    COUNT(n.id) as jumlah_matkul,\n    AVG(n.nilai) as rata_rata,\n    CASE \n        WHEN AVG(n.nilai) >= 80 THEN \'A\'\n        WHEN AVG(n.nilai) >= 70 THEN \'B\'\n        ELSE \'C\'\n    END as grade\nFROM mahasiswa m\nLEFT JOIN nilai n ON m.id = n.mahasiswa_id\nGROUP BY m.id, m.nim, m.nama\nORDER BY rata_rata DESC;','sql',1,19,'2026-05-04 01:42:00','2026-05-04 01:42:00');
INSERT INTO `comments` VALUES(6,3,NULL,3,NULL,'Pak, di source code-nya ada bagian validasi request-nya tidak? Saya bingung cara bikin FormRequest yang benar.',0,NULL,'php',0,0,'2026-05-04 01:42:00','2026-05-04 01:42:00');
INSERT INTO `comments` VALUES(7,2,NULL,3,NULL,'Ada di folder app/Http/Requests. Bisa run: php artisan make:request StorePostRequest, lalu definisikan rules() di dalamnya.',1,'php artisan make:request StorePostRequest\n\n// Isi rules():\npublic function rules(): array\n{\n    return [\n        \'title\' => [\'required\', \'string\', \'max:255\'],\n        \'body\'  => [\'required\', \'string\'],\n    ];\n}','php',0,0,'2026-05-04 01:42:00','2026-05-04 01:42:00');
INSERT INTO `comments` VALUES(8,4,NULL,1,NULL,'Pak untuk latihan soal nomor 3, flowchart percabangan benar-salahnya bagaimana? Saya masih bingung arah panahnya.',0,NULL,'php',0,0,'2026-05-04 01:42:00','2026-05-04 01:42:00');

-- --------------------------------------------------------
-- Table: badges
-- --------------------------------------------------------
CREATE TABLE `badges` (
  `id` INT AUTO_INCREMENT PRIMARY KEY,
  `name` VARCHAR(255) NOT NULL,
  `slug` VARCHAR(255) NOT NULL,
  `description` TEXT DEFAULT NULL,
  `icon` VARCHAR(255) DEFAULT NULL,
  `category` VARCHAR(255) NOT NULL DEFAULT 'contributor',
  `points_required` INT NOT NULL DEFAULT 0,
  `condition_type` VARCHAR(255) NOT NULL DEFAULT 'points',
  `condition_value` INT NOT NULL DEFAULT 1,
  `created_at` DATETIME DEFAULT NULL,
  `updated_at` DATETIME DEFAULT NULL,
  UNIQUE KEY `badges_slug_unique` (`slug`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT INTO `badges` VALUES(1,'Code Rookie','code-rookie','Bergabung dengan RPLy dan mulai berkontribusi.','🌱','contributor',0,'points',10,'2026-05-04 01:42:00','2026-05-04 01:42:00');
INSERT INTO `badges` VALUES(2,'Helper','helper','Memberikan 3 jawaban Verified Solution.','🤝','helper',0,'verified_answers',3,'2026-05-04 01:42:00','2026-05-04 01:42:00');
INSERT INTO `badges` VALUES(3,'Expert Dev','expert-dev','Meraih 500 poin sebagai kontributor handal.','⭐','expert',0,'points',500,'2026-05-04 01:42:00','2026-05-04 01:42:00');
INSERT INTO `badges` VALUES(4,'Knowledge Sharer','knowledge-sharer','Mengunggah 5 materi ke Ruang Ilmu.','📚','contributor',0,'uploads',5,'2026-05-04 01:42:00','2026-05-04 01:42:00');
INSERT INTO `badges` VALUES(5,'Hadir Terus','hadir-terus','Check-in selama 30 hari.','🔥','attendance',0,'checkins',30,'2026-05-04 01:42:00','2026-05-04 01:42:00');

-- --------------------------------------------------------
-- Table: user_badges
-- --------------------------------------------------------
CREATE TABLE `user_badges` (
  `id` INT AUTO_INCREMENT PRIMARY KEY,
  `user_id` INT NOT NULL,
  `badge_id` INT NOT NULL,
  `awarded_at` DATETIME DEFAULT NULL,
  `created_at` DATETIME DEFAULT NULL,
  `updated_at` DATETIME DEFAULT NULL,
  FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
  FOREIGN KEY (`badge_id`) REFERENCES `badges` (`id`) ON DELETE CASCADE,
  UNIQUE KEY `user_badges_user_id_badge_id_unique` (`user_id`, `badge_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- --------------------------------------------------------
-- Table: daily_check_ins
-- --------------------------------------------------------
CREATE TABLE `daily_check_ins` (
  `id` INT AUTO_INCREMENT PRIMARY KEY,
  `user_id` INT NOT NULL,
  `points_earned` INT NOT NULL DEFAULT 5,
  `streak_day` INT NOT NULL DEFAULT 1,
  `created_at` DATETIME DEFAULT NULL,
  `updated_at` DATETIME DEFAULT NULL,
  FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

