Files
sam-api/app/Services/Fcm/FcmBatchResult.php
hskwon 10a64fb0a5 feat: FCM 실서비스 확장 - 대량 발송 및 무효 토큰 관리
- FcmSender.sendToMany() 추가 (chunk/rate limit 지원)
- FcmBatchResult 클래스 추가 (발송 결과 집계)
- fcm:send 명령어 추가 (대량 발송, dry-run 지원)
- fcm:prune-invalid 명령어 추가 (무효 토큰 정리)
- PushDeviceToken에 last_error, last_error_at 컬럼 추가
- 실패 토큰 자동 비활성화 (UNREGISTERED, NOT_FOUND, INVALID_ARGUMENT)
2025-12-18 23:01:06 +09:00

113 lines
2.2 KiB
PHP

<?php
namespace App\Services\Fcm;
class FcmBatchResult
{
/** @var array<string, FcmResponse> */
private array $responses = [];
private int $successCount = 0;
private int $failureCount = 0;
/** @var array<string> 무효 토큰 목록 */
private array $invalidTokens = [];
/**
* 응답 추가
*/
public function addResponse(string $token, FcmResponse $response): void
{
$this->responses[$token] = $response;
if ($response->success) {
$this->successCount++;
} else {
$this->failureCount++;
if ($response->isInvalidToken()) {
$this->invalidTokens[] = $token;
}
}
}
/**
* 전체 발송 수
*/
public function getTotal(): int
{
return count($this->responses);
}
/**
* 성공 수
*/
public function getSuccessCount(): int
{
return $this->successCount;
}
/**
* 실패 수
*/
public function getFailureCount(): int
{
return $this->failureCount;
}
/**
* 무효 토큰 목록 (비활성화 필요)
*
* @return array<string>
*/
public function getInvalidTokens(): array
{
return $this->invalidTokens;
}
/**
* 모든 응답
*
* @return array<string, FcmResponse>
*/
public function getResponses(): array
{
return $this->responses;
}
/**
* 특정 토큰의 응답
*/
public function getResponse(string $token): ?FcmResponse
{
return $this->responses[$token] ?? null;
}
/**
* 성공률 (%)
*/
public function getSuccessRate(): float
{
if ($this->getTotal() === 0) {
return 0.0;
}
return round(($this->successCount / $this->getTotal()) * 100, 2);
}
/**
* 요약 정보
*/
public function toSummary(): array
{
return [
'total' => $this->getTotal(),
'success' => $this->successCount,
'failure' => $this->failureCount,
'invalid_tokens' => count($this->invalidTokens),
'success_rate' => $this->getSuccessRate(),
];
}
}