Files
sam-manage/app/Models/Admin/AdminPmDailyLogEntry.php
hskwon a2477837d0 feat: [daily-logs] 일일 스크럼 기능 구현
주요 기능:
- 일일 로그 CRUD (생성, 조회, 수정, 삭제, 복원, 영구삭제)
- 로그 항목(Entry) 관리 (추가, 상태변경, 삭제, 순서변경)
- 주간 타임라인 (최근 7일 진행률 표시)
- 테이블 리스트 아코디언 상세보기
- 담당자 자동완성 (일반 사용자는 슈퍼관리자 목록 제외)
- HTMX 기반 동적 테이블 로딩 및 필터링
- Soft Delete 지원

파일 추가:
- Models: AdminPmDailyLog, AdminPmDailyLogEntry
- Controllers: DailyLogController (Web, API)
- Service: DailyLogService
- Requests: StoreDailyLogRequest, UpdateDailyLogRequest
- Views: index, show, table partial, modal-form partial

라우트 추가:
- Web: /daily-logs, /daily-logs/today, /daily-logs/{id}
- API: /api/admin/daily-logs/* (CRUD + 항목관리)
2025-12-01 14:07:55 +09:00

155 lines
3.6 KiB
PHP

<?php
namespace App\Models\Admin;
use App\Models\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
/**
* 프로젝트 관리 - 일일 로그 항목 모델
*
* @property int $id
* @property int $daily_log_id
* @property string $assignee_type
* @property int|null $assignee_id
* @property string $assignee_name
* @property string $content
* @property string $status
* @property int $sort_order
* @property \Carbon\Carbon $created_at
* @property \Carbon\Carbon $updated_at
*/
class AdminPmDailyLogEntry extends Model
{
protected $table = 'admin_pm_daily_log_entries';
protected $fillable = [
'daily_log_id',
'assignee_type',
'assignee_id',
'assignee_name',
'content',
'status',
'sort_order',
];
protected $casts = [
'daily_log_id' => 'integer',
'assignee_id' => 'integer',
'sort_order' => 'integer',
];
/**
* 담당자 유형 상수
*/
public const TYPE_TEAM = 'team';
public const TYPE_USER = 'user';
/**
* 상태 상수
*/
public const STATUS_TODO = 'todo';
public const STATUS_IN_PROGRESS = 'in_progress';
public const STATUS_DONE = 'done';
/**
* 담당자 유형 목록
*/
public static function getAssigneeTypes(): array
{
return [
self::TYPE_TEAM => '팀',
self::TYPE_USER => '개인',
];
}
/**
* 상태 목록
*/
public static function getStatuses(): array
{
return [
self::STATUS_TODO => '예정',
self::STATUS_IN_PROGRESS => '진행중',
self::STATUS_DONE => '완료',
];
}
/**
* 관계: 일일 로그
*/
public function dailyLog(): BelongsTo
{
return $this->belongsTo(AdminPmDailyLog::class, 'daily_log_id');
}
/**
* 관계: 사용자 담당자 (assignee_type이 user인 경우)
*/
public function assigneeUser(): BelongsTo
{
return $this->belongsTo(User::class, 'assignee_id');
}
/**
* 스코프: 상태별 필터
*/
public function scopeStatus($query, string $status)
{
return $query->where('status', $status);
}
/**
* 스코프: 담당자 유형별 필터
*/
public function scopeAssigneeType($query, string $type)
{
return $query->where('assignee_type', $type);
}
/**
* 상태 라벨 (한글)
*/
public function getStatusLabelAttribute(): string
{
return self::getStatuses()[$this->status] ?? $this->status;
}
/**
* 담당자 유형 라벨 (한글)
*/
public function getAssigneeTypeLabelAttribute(): string
{
return self::getAssigneeTypes()[$this->assignee_type] ?? $this->assignee_type;
}
/**
* 상태별 색상 클래스
*/
public function getStatusColorAttribute(): string
{
return match ($this->status) {
self::STATUS_TODO => 'bg-gray-100 text-gray-800',
self::STATUS_IN_PROGRESS => 'bg-yellow-100 text-yellow-800',
self::STATUS_DONE => 'bg-green-100 text-green-800',
default => 'bg-gray-100 text-gray-800',
};
}
/**
* 담당자 유형별 색상 클래스
*/
public function getAssigneeTypeColorAttribute(): string
{
return match ($this->assignee_type) {
self::TYPE_TEAM => 'bg-purple-100 text-purple-800',
self::TYPE_USER => 'bg-blue-100 text-blue-800',
default => 'bg-gray-100 text-gray-800',
};
}
}