<?php
use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema;
return new class extends Migration { public function up():void {
Schema::table('shifts',function(Blueprint $t){$t->json('weekly_off_days')->nullable();$t->unsignedSmallInteger('minimum_work_minutes')->default(480);$t->unsignedSmallInteger('overtime_after_minutes')->default(540);});
Schema::table('attendance_records',function(Blueprint $t){$t->unsignedInteger('late_minutes')->default(0);$t->unsignedInteger('early_leave_minutes')->default(0);$t->unsignedInteger('overtime_minutes')->default(0);$t->string('work_mode')->default('office');$t->boolean('is_locked')->default(false)->index();});
Schema::create('holidays',function(Blueprint $t){$t->id();$t->string('name');$t->date('holiday_date')->unique();$t->boolean('is_paid')->default(true);$t->timestamps();});
Schema::create('attendance_month_locks',function(Blueprint $t){$t->id();$t->string('period')->unique();$t->foreignId('locked_by')->constrained('users')->restrictOnDelete();$t->timestamp('locked_at');$t->text('notes')->nullable();$t->timestamps();});
Schema::create('remote_work_requests',function(Blueprint $t){$t->id();$t->foreignId('user_id')->constrained()->cascadeOnDelete();$t->date('work_date');$t->text('reason');$t->string('status')->default('pending')->index();$t->foreignId('approved_by')->nullable()->constrained('users')->nullOnDelete();$t->timestamp('approved_at')->nullable();$t->timestamps();$t->unique(['user_id','work_date']);});
Schema::create('approval_steps',function(Blueprint $t){$t->id();$t->string('approvable_type');$t->unsignedBigInteger('approvable_id');$t->unsignedSmallInteger('step_order');$t->string('required_role');$t->string('status')->default('pending')->index();$t->foreignId('acted_by')->nullable()->constrained('users')->nullOnDelete();$t->timestamp('acted_at')->nullable();$t->text('comments')->nullable();$t->timestamps();$t->unique(['approvable_type','approvable_id','step_order'],'approval_unique');$t->index(['approvable_type','approvable_id']);});
Schema::table('salary_revisions',function(Blueprint $t){$t->string('status')->default('approved')->index();});
Schema::create('salary_adjustments',function(Blueprint $t){$t->id();$t->foreignId('employee_id')->constrained()->cascadeOnDelete();$t->string('period')->index();$t->string('type')->index();$t->string('label');$t->decimal('amount',14,2);$t->boolean('is_taxable')->default(false);$t->string('status')->default('approved');$t->foreignId('approved_by')->nullable()->constrained('users')->nullOnDelete();$t->timestamps();});
Schema::create('employee_advances',function(Blueprint $t){$t->id();$t->foreignId('employee_id')->constrained()->cascadeOnDelete();$t->decimal('amount',14,2);$t->decimal('remaining_amount',14,2);$t->decimal('monthly_deduction',14,2)->default(0);$t->date('issued_on');$t->string('status')->default('active');$t->foreignId('approved_by')->nullable()->constrained('users')->nullOnDelete();$t->timestamps();});
Schema::table('payroll_items',function(Blueprint $t){$t->decimal('unpaid_leave_deduction',14,2)->default(0);$t->decimal('overtime_amount',14,2)->default(0);$t->decimal('tax_withholding',14,2)->default(0);$t->decimal('advance_deduction',14,2)->default(0);$t->decimal('other_adjustments',14,2)->default(0);$t->string('payment_status')->default('pending');$t->timestamp('paid_at')->nullable();});
Schema::table('stipend_items',function(Blueprint $t){$t->string('payment_status')->default('pending');$t->timestamp('paid_at')->nullable();});
Schema::create('intern_learning_items',function(Blueprint $t){$t->id();$t->foreignId('intern_id')->constrained()->cascadeOnDelete();$t->string('title');$t->text('description')->nullable();$t->date('due_date')->nullable();$t->string('status')->default('pending');$t->unsignedTinyInteger('progress_percent')->default(0);$t->foreignId('reviewed_by')->nullable()->constrained('users')->nullOnDelete();$t->timestamps();});
Schema::create('intern_evaluations',function(Blueprint $t){$t->id();$t->foreignId('intern_id')->constrained()->cascadeOnDelete();$t->foreignId('evaluator_user_id')->constrained('users')->restrictOnDelete();$t->string('evaluation_type')->default('monthly');$t->date('evaluation_date');$t->unsignedTinyInteger('technical_score')->default(0);$t->unsignedTinyInteger('communication_score')->default(0);$t->unsignedTinyInteger('attendance_score')->default(0);$t->unsignedTinyInteger('ownership_score')->default(0);$t->text('strengths')->nullable();$t->text('improvements')->nullable();$t->string('recommendation')->nullable();$t->timestamps();});
Schema::create('intern_certificates',function(Blueprint $t){$t->id();$t->foreignId('intern_id')->unique()->constrained()->cascadeOnDelete();$t->string('certificate_no')->unique();$t->date('issued_on');$t->string('status')->default('issued');$t->text('remarks')->nullable();$t->foreignId('issued_by')->constrained('users')->restrictOnDelete();$t->timestamps();});
Schema::create('performance_cycles',function(Blueprint $t){$t->id();$t->string('name');$t->date('start_date');$t->date('end_date');$t->string('status')->default('draft')->index();$t->timestamps();});
Schema::create('performance_reviews',function(Blueprint $t){$t->id();$t->foreignId('performance_cycle_id')->constrained()->cascadeOnDelete();$t->foreignId('employee_id')->constrained()->cascadeOnDelete();$t->foreignId('reviewer_user_id')->constrained('users')->restrictOnDelete();$t->unsignedTinyInteger('delivery_score')->default(0);$t->unsignedTinyInteger('quality_score')->default(0);$t->unsignedTinyInteger('communication_score')->default(0);$t->unsignedTinyInteger('ownership_score')->default(0);$t->text('achievements')->nullable();$t->text('development_plan')->nullable();$t->string('rating')->nullable();$t->string('status')->default('draft');$t->timestamps();$t->unique(['performance_cycle_id','employee_id','reviewer_user_id'],'performance_unique');});
Schema::create('employee_kpis',function(Blueprint $t){$t->id();$t->foreignId('employee_id')->constrained()->cascadeOnDelete();$t->foreignId('performance_cycle_id')->nullable()->constrained()->cascadeOnDelete();$t->string('title');$t->decimal('weight',5,2)->default(0);$t->decimal('target_value',12,2)->nullable();$t->decimal('actual_value',12,2)->nullable();$t->string('status')->default('active');$t->timestamps();});
Schema::create('worker_documents',function(Blueprint $t){$t->id();$t->foreignId('user_id')->constrained()->cascadeOnDelete();$t->string('document_type')->index();$t->string('title');$t->string('file_path');$t->date('issued_on')->nullable();$t->date('expires_on')->nullable()->index();$t->boolean('is_private')->default(true);$t->foreignId('uploaded_by')->nullable()->constrained('users')->nullOnDelete();$t->timestamps();});
Schema::create('asset_assignments',function(Blueprint $t){$t->id();$t->foreignId('asset_id')->constrained()->cascadeOnDelete();$t->foreignId('user_id')->constrained()->cascadeOnDelete();$t->timestamp('issued_at');$t->timestamp('returned_at')->nullable();$t->string('issue_condition')->nullable();$t->string('return_condition')->nullable();$t->text('damage_notes')->nullable();$t->decimal('recovery_amount',14,2)->default(0);$t->foreignId('issued_by')->nullable()->constrained('users')->nullOnDelete();$t->foreignId('received_by')->nullable()->constrained('users')->nullOnDelete();$t->timestamps();});
Schema::create('offboardings',function(Blueprint $t){$t->id();$t->foreignId('user_id')->constrained()->cascadeOnDelete();$t->string('type')->default('resignation');$t->date('notice_date')->nullable();$t->date('last_working_date');$t->text('reason')->nullable();$t->string('status')->default('initiated')->index();$t->boolean('assets_cleared')->default(false);$t->boolean('finance_cleared')->default(false);$t->boolean('access_revoked')->default(false);$t->decimal('final_settlement_amount',14,2)->default(0);$t->timestamp('settled_at')->nullable();$t->foreignId('processed_by')->nullable()->constrained('users')->nullOnDelete();$t->timestamps();});
Schema::create('mfa_challenges',function(Blueprint $t){$t->id();$t->foreignId('user_id')->constrained()->cascadeOnDelete();$t->string('code_hash');$t->timestamp('expires_at');$t->timestamp('used_at')->nullable();$t->unsignedTinyInteger('attempts')->default(0);$t->string('ip_address',45)->nullable();$t->timestamps();});
Schema::table('users',function(Blueprint $t){$t->boolean('mfa_enabled')->default(false);$t->timestamp('mfa_verified_at')->nullable();});
Schema::create('notifications',function(Blueprint $t){$t->uuid('id')->primary();$t->string('type');$t->morphs('notifiable');$t->text('data');$t->timestamp('read_at')->nullable();$t->timestamps();});
Schema::create('backup_runs',function(Blueprint $t){$t->id();$t->string('filename');$t->string('status')->default('started');$t->unsignedBigInteger('size_bytes')->nullable();$t->string('checksum')->nullable();$t->text('error')->nullable();$t->timestamp('completed_at')->nullable();$t->timestamps();});
}
public function down():void {
foreach(['backup_runs','notifications','mfa_challenges','offboardings','asset_assignments','worker_documents','employee_kpis','performance_reviews','performance_cycles','intern_certificates','intern_evaluations','intern_learning_items','employee_advances','salary_adjustments','approval_steps','remote_work_requests','attendance_month_locks','holidays'] as $x) Schema::dropIfExists($x);
Schema::table('salary_revisions',fn(Blueprint $t)=>$t->dropColumn('status'));
Schema::table('users',fn(Blueprint $t)=>$t->dropColumn(['mfa_enabled','mfa_verified_at']));
Schema::table('stipend_items',fn(Blueprint $t)=>$t->dropColumn(['payment_status','paid_at']));
Schema::table('payroll_items',fn(Blueprint $t)=>$t->dropColumn(['unpaid_leave_deduction','overtime_amount','tax_withholding','advance_deduction','other_adjustments','payment_status','paid_at']));
Schema::table('attendance_records',fn(Blueprint $t)=>$t->dropColumn(['late_minutes','early_leave_minutes','overtime_minutes','work_mode','is_locked']));
Schema::table('shifts',fn(Blueprint $t)=>$t->dropColumn(['weekly_off_days','minimum_work_minutes','overtime_after_minutes']));
}};