SPMS_API/SPMS.Infrastructure/Caching/ScheduleCancelStore.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

59 lines
1.8 KiB
C#

using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using SPMS.Application.Interfaces;
using SPMS.Application.Settings;
namespace SPMS.Infrastructure.Caching;
public class ScheduleCancelStore : IScheduleCancelStore
{
private static readonly TimeSpan DefaultTtl = TimeSpan.FromDays(7);
private readonly RedisConnection _redis;
private readonly RedisSettings _settings;
private readonly ILogger<ScheduleCancelStore> _logger;
public ScheduleCancelStore(
RedisConnection redis,
IOptions<RedisSettings> settings,
ILogger<ScheduleCancelStore> logger)
{
_redis = redis;
_settings = settings.Value;
_logger = logger;
}
public async Task MarkCancelledAsync(string scheduleId, CancellationToken cancellationToken = default)
{
var key = $"{_settings.InstanceName}schedule_cancel:{scheduleId}";
try
{
var db = await _redis.GetDatabaseAsync();
await db.StringSetAsync(key, "1", DefaultTtl);
_logger.LogInformation("예약 취소 등록: scheduleId={ScheduleId}", scheduleId);
}
catch (Exception ex)
{
_logger.LogError(ex, "예약 취소 등록 실패: scheduleId={ScheduleId}", scheduleId);
throw;
}
}
public async Task<bool> IsCancelledAsync(string scheduleId, CancellationToken cancellationToken = default)
{
var key = $"{_settings.InstanceName}schedule_cancel:{scheduleId}";
try
{
var db = await _redis.GetDatabaseAsync();
return await db.KeyExistsAsync(key);
}
catch (Exception ex)
{
_logger.LogError(ex, "예약 취소 확인 실패: scheduleId={ScheduleId} — 취소되지 않은 것으로 처리", scheduleId);
return false;
}
}
}