header('X-Sender-Id'); $result = $this->service->send( $request->validated(), $senderId ? (int) $senderId : null ); if (! $result['success']) { return ApiResponse::error($result['message'], 422, $result); } return $result['data']; }, __('message.fcm.sent')); } /** * 대상 토큰 수 미리보기 */ public function previewCount(Request $request): JsonResponse { return ApiResponse::handle(function () use ($request) { $count = $this->service->previewCount($request->only([ 'tenant_id', 'user_id', 'platform', ])); return ['count' => $count]; }); } /** * 토큰 목록 조회 */ public function tokens(FcmTokenListRequest $request): JsonResponse { return ApiResponse::handle(function () use ($request) { return $this->service->getTokens( $request->validated(), $request->integer('per_page', 20) ); }); } /** * 토큰 통계 */ public function tokenStats(Request $request): JsonResponse { return ApiResponse::handle(function () use ($request) { return $this->service->getTokenStats( $request->integer('tenant_id') ); }); } /** * 토큰 상태 토글 */ public function toggleToken(int $id): JsonResponse { return ApiResponse::handle(function () use ($id) { return $this->service->toggleToken($id); }, __('message.updated')); } /** * 토큰 삭제 */ public function deleteToken(int $id): JsonResponse { return ApiResponse::handle(function () use ($id) { $this->service->deleteToken($id); return ['deleted' => true]; }, __('message.deleted')); } /** * 발송 이력 조회 */ public function history(FcmHistoryRequest $request): JsonResponse { return ApiResponse::handle(function () use ($request) { return $this->service->getHistory( $request->validated(), $request->integer('per_page', 20) ); }); } }