'integer', 'due_date' => 'date', 'completed_at' => 'datetime', 'assignee_id' => 'integer', 'sort_order' => 'integer', 'created_by' => 'integer', 'updated_by' => 'integer', 'deleted_by' => 'integer', ]; public const STATUS_PENDING = 'pending'; public const STATUS_COMPLETED = 'completed'; public static function getStatuses(): array { return [ self::STATUS_PENDING => '진행중', self::STATUS_COMPLETED => '완료', ]; } public function plan(): BelongsTo { return $this->belongsTo(AdminRoadmapPlan::class, 'plan_id'); } public function assignee(): BelongsTo { return $this->belongsTo(User::class, 'assignee_id'); } public function creator(): BelongsTo { return $this->belongsTo(User::class, 'created_by'); } public function getStatusLabelAttribute(): string { return self::getStatuses()[$this->status] ?? $this->status; } public function getIsCompletedAttribute(): bool { return $this->status === self::STATUS_COMPLETED; } public function getDdayAttribute(): ?int { if (! $this->due_date) { return null; } return now()->startOfDay()->diffInDays($this->due_date, false); } public function getDueStatusAttribute(): ?string { if (! $this->due_date || $this->status === self::STATUS_COMPLETED) { return null; } $dday = $this->dday; if ($dday < 0) { return 'overdue'; } if ($dday <= 7) { return 'due_soon'; } return 'normal'; } }