Detailing fungsi semua modul dari bugs error

This commit is contained in:
Iwit
2026-06-05 13:39:13 +07:00
parent 1089f60a3d
commit 6a79bc3464
31 changed files with 1927 additions and 228 deletions
@@ -0,0 +1,40 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up()
{
Schema::create('exams', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('description')->nullable();
// Mengakomodasi 3 jenis training sesuai permintaan Anda
$table->enum('training_type', ['matrix_plant', 'product', 'external']);
// Relasi ke Materi/Subject (Satu ujian bisa mewakili satu materi SOP)
$table->foreignId('subject_id')->constrained()->onDelete('cascade');
// Aturan CBT
$table->integer('duration_minutes')->default(60); // Durasi ujian
$table->integer('passing_grade')->default(80); // Nilai standar kelulusan
$table->integer('max_retakes')->default(1); // Kesempatan remedial (1 = bisa remedial 1x)
$table->boolean('is_random_order')->default(true); // Opsi acak soal antar peserta
$table->boolean('is_active')->default(true);
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('exams');
}
};
@@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up()
{
Schema::create('exam_assignments', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id'); // Karyawan yang ditugaskan
$table->foreignId('exam_id')->constrained()->onDelete('cascade');
$table->dateTime('deadline_date'); // Batas akhir pengerjaan
// Status pengerjaan
$table->enum('status', ['pending', 'in_progress', 'passed', 'failed'])->default('pending');
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
}
public function down()
{
Schema::dropIfExists('exam_assignments');
}
};
@@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up()
{
Schema::create('exam_attempts', function (Blueprint $table) {
$table->id();
$table->foreignId('exam_assignment_id')->constrained()->onDelete('cascade'); // Link ke penugasan
$table->integer('attempt_number')->default(1); // Percobaan ke-1, ke-2 (remedial), dst
$table->decimal('final_score', 5, 2)->nullable(); // Nilai akhir (0-100)
$table->enum('status', ['ongoing', 'completed'])->default('ongoing');
$table->dateTime('started_at');
$table->dateTime('completed_at')->nullable();
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('exam_attempts');
}
};
@@ -0,0 +1,30 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up()
{
Schema::table('question_banks', function (Blueprint $table) {
// Menandai jenis soal (default 'multiple_choice' agar data lama Anda tetap aman)
if (!Schema::hasColumn('question_banks', 'question_type')) {
$table->enum('question_type', ['multiple_choice', 'essay'])->default('multiple_choice')->after('id');
}
// Menyimpan kata kunci wajib untuk soal esai (pisahkan dengan koma)
if (!Schema::hasColumn('question_banks', 'essay_keywords')) {
$table->text('essay_keywords')->nullable()->after('question_type');
}
});
}
public function down()
{
Schema::table('question_banks', function (Blueprint $table) {
$table->dropColumn(['question_type', 'essay_keywords']);
});
}
};
@@ -0,0 +1,55 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up()
{
Schema::create('exam_answers', function (Blueprint $table) {
$table->id();
$table->foreignId('exam_attempt_id')->constrained('exam_attempts')->cascadeOnDelete();
$table->foreignId('question_id')->constrained('question_banks')->cascadeOnDelete();
// Snapshot tipe soal (berjaga-jaga jika master soal diubah setelah ujian selesai)
$table->string('question_type', 50)->nullable();
// Jawaban peserta (bisa teks esai, atau huruf opsi A/B/C/D)
$table->longText('student_answer')->nullable();
// Pengecekan Sistem Otomatis (True jika PG benar, False jika salah)
$table->boolean('is_correct')->nullable();
// --- SISTEM PENILAIAN HYBRID ---
// Nilai hitungan mesin/sistem (bisa dari cocoknya kunci jawaban atau deteksi keyword)
$table->decimal('auto_score', 8, 2)->default(0);
// Poin tambahan/pengurangan dari koreksi manual oleh Trainer
$table->decimal('manual_score', 8, 2)->default(0);
// Total nilai mutlak untuk 1 soal ini (auto_score + manual_score)
$table->decimal('final_score', 8, 2)->default(0);
// Feedback/Catatan dari trainer khusus untuk jawaban ini
$table->text('trainer_notes')->nullable();
// Siapa trainer yang menilai soal ini (jika manual)
$table->unsignedBigInteger('graded_by')->nullable();
$table->timestamp('graded_at')->nullable();
// --- FUTURE PROOFING ---
// Kolom JSON super fleksibel untuk menyimpan data apapun di masa depan
// (contoh: log pindah tab browser, durasi waktu spesifik di soal ini, dll)
$table->json('metadata')->nullable();
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('exam_answers');
}
};