SPMS_API/SPMS.API/Controllers/PushController.cs
SEAN fe1dcd0176 feat: 예약 발송 등록/취소 API 구현 (#116)
- POST /v1/in/push/schedule (예약 발송 등록)
- POST /v1/in/push/schedule/cancel (예약 취소)
- ScheduleCancelStore: Redis 기반 예약 취소 추적
- ScheduleWorker: 취소된 예약 메시지 ACK 후 스킵 로직 추가

Closes #116
2026-02-10 17:06:04 +09:00

65 lines
2.5 KiB
C#

using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;
using SPMS.Application.DTOs.Push;
using SPMS.Application.Interfaces;
using SPMS.Domain.Common;
namespace SPMS.API.Controllers;
[ApiController]
[Route("v1/in/push")]
[ApiExplorerSettings(GroupName = "push")]
public class PushController : ControllerBase
{
private readonly IPushService _pushService;
public PushController(IPushService pushService)
{
_pushService = pushService;
}
[HttpPost("send")]
[SwaggerOperation(Summary = "단건 발송", Description = "특정 디바이스에 푸시 메시지를 즉시 발송합니다.")]
public async Task<IActionResult> SendAsync([FromBody] PushSendRequestDto request)
{
var serviceId = GetServiceId();
var result = await _pushService.SendAsync(serviceId, request);
return Ok(ApiResponse<PushSendResponseDto>.Success(result));
}
[HttpPost("send/tag")]
[SwaggerOperation(Summary = "태그 발송", Description = "태그 조건에 해당하는 디바이스에 푸시 메시지를 발송합니다.")]
public async Task<IActionResult> SendByTagAsync([FromBody] PushSendTagRequestDto request)
{
var serviceId = GetServiceId();
var result = await _pushService.SendByTagAsync(serviceId, request);
return Ok(ApiResponse<PushSendResponseDto>.Success(result));
}
[HttpPost("schedule")]
[SwaggerOperation(Summary = "예약 발송", Description = "지정 시간에 푸시 메시지 발송을 예약합니다.")]
public async Task<IActionResult> ScheduleAsync([FromBody] PushScheduleRequestDto request)
{
var serviceId = GetServiceId();
var result = await _pushService.ScheduleAsync(serviceId, request);
return Ok(ApiResponse<PushScheduleResponseDto>.Success(result));
}
[HttpPost("schedule/cancel")]
[SwaggerOperation(Summary = "예약 취소", Description = "예약된 발송을 취소합니다.")]
public async Task<IActionResult> CancelScheduleAsync([FromBody] PushScheduleCancelRequestDto request)
{
var serviceId = GetServiceId();
await _pushService.CancelScheduleAsync(request);
return Ok(ApiResponse.Success());
}
private long GetServiceId()
{
if (HttpContext.Items.TryGetValue("ServiceId", out var serviceIdObj) && serviceIdObj is long serviceId)
return serviceId;
throw new Domain.Exceptions.SpmsException(ErrorCodes.BadRequest, "서비스 식별 정보가 없습니다.", 400);
}
}