'array', 'total_count' => 'integer', 'success_count' => 'integer', 'failure_count' => 'integer', 'invalid_token_count' => 'integer', 'success_rate' => 'decimal:2', 'completed_at' => 'datetime', ]; /** * 발송자 (MNG 관리자) */ public function sender(): BelongsTo { return $this->belongsTo(User::class, 'sender_id'); } /** * 테넌트 */ public function tenant(): BelongsTo { return $this->belongsTo(Tenant::class); } /** * 대상 사용자 */ public function targetUser(): BelongsTo { return $this->belongsTo(User::class, 'user_id'); } /** * Scope: 특정 발송자의 로그 */ public function scopeBySender($query, int $senderId) { return $query->where('sender_id', $senderId); } /** * Scope: 특정 상태 */ public function scopeByStatus($query, string $status) { return $query->where('status', $status); } /** * Scope: 최근 N일 */ public function scopeRecent($query, int $days = 7) { return $query->where('created_at', '>=', now()->subDays($days)); } /** * 발송 시작 표시 */ public function markAsSending(): void { $this->update(['status' => self::STATUS_SENDING]); } /** * 발송 완료 표시 */ public function markAsCompleted(array $summary): void { $this->update([ 'status' => self::STATUS_COMPLETED, 'total_count' => $summary['total'], 'success_count' => $summary['success'], 'failure_count' => $summary['failure'], 'invalid_token_count' => $summary['invalid_tokens'], 'success_rate' => $summary['success_rate'], 'completed_at' => now(), ]); } /** * 발송 실패 표시 */ public function markAsFailed(string $errorMessage): void { $this->update([ 'status' => self::STATUS_FAILED, 'error_message' => $errorMessage, 'completed_at' => now(), ]); } }