Detailing fungsi semua modul dari bugs error
This commit is contained in:
@@ -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');
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user