'date', 'actual_date' => 'date', 'weight_percentage' => 'decimal:2', 'is_default' => 'boolean', 'weather_impacted' => 'boolean', 'weather_condition' => WeatherCondition::class, ]; } public function project(): BelongsTo { return $this->belongsTo(Project::class); } public function tasks(): \Illuminate\Database\Eloquent\Relations\HasMany { return $this->hasMany(Task::class, 'milestone_id'); } // --- Accessors --- public function getIsCompletedAttribute(): bool { return $this->actual_date !== null; } public function getIsOverdueAttribute(): bool { return !$this->is_completed && $this->planned_date && $this->planned_date->isPast(); } public function getStatusAttribute(): string { if ($this->is_completed) return 'completed'; if ($this->is_overdue) return 'overdue'; return 'upcoming'; } public function getStatusColorAttribute(): string { return match ($this->status) { 'completed' => 'emerald', 'overdue' => 'amber', default => 'gray', }; } public function getDaysDelayedAttribute(): int { if (!$this->is_completed || !$this->planned_date) return 0; $diff = $this->planned_date->diffInDays($this->actual_date, false); return max(0, $diff); } }