214 lines
10 KiB
C#
214 lines
10 KiB
C#
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Swashbuckle.AspNetCore.Annotations;
|
|
using SPMS.Application.DTOs.Service;
|
|
using SPMS.Application.Interfaces;
|
|
using SPMS.Domain.Common;
|
|
|
|
namespace SPMS.API.Controllers;
|
|
|
|
[ApiController]
|
|
[Route("v1/in/service")]
|
|
[ApiExplorerSettings(GroupName = "service")]
|
|
[Authorize(Roles = "Super")]
|
|
public class ServiceController : ControllerBase
|
|
{
|
|
private readonly IServiceManagementService _serviceManagementService;
|
|
|
|
public ServiceController(IServiceManagementService serviceManagementService)
|
|
{
|
|
_serviceManagementService = serviceManagementService;
|
|
}
|
|
|
|
[HttpPost("create")]
|
|
[SwaggerOperation(
|
|
Summary = "서비스 등록",
|
|
Description = "새로운 서비스를 등록합니다. ServiceCode와 API Key가 자동 생성되며, API Key는 응답에서 1회만 표시됩니다.")]
|
|
[SwaggerResponse(200, "등록 성공", typeof(ApiResponse<CreateServiceResponseDto>))]
|
|
[SwaggerResponse(400, "잘못된 요청")]
|
|
[SwaggerResponse(401, "인증되지 않은 요청")]
|
|
[SwaggerResponse(403, "권한 없음")]
|
|
[SwaggerResponse(409, "이미 존재하는 서비스명")]
|
|
public async Task<IActionResult> CreateAsync([FromBody] CreateServiceRequestDto request)
|
|
{
|
|
var adminIdClaim = User.FindFirst("adminId")?.Value;
|
|
if (string.IsNullOrEmpty(adminIdClaim) || !long.TryParse(adminIdClaim, out var adminId))
|
|
{
|
|
return Unauthorized(ApiResponse<object>.Fail("101", "인증 정보가 유효하지 않습니다."));
|
|
}
|
|
|
|
var result = await _serviceManagementService.CreateAsync(request, adminId);
|
|
return Ok(ApiResponse<CreateServiceResponseDto>.Success(result));
|
|
}
|
|
|
|
[HttpPost("update")]
|
|
[SwaggerOperation(
|
|
Summary = "서비스 수정",
|
|
Description = "기존 서비스의 정보를 수정합니다. 서비스명, 설명, 웹훅 URL, 태그를 변경할 수 있습니다.")]
|
|
[SwaggerResponse(200, "수정 성공", typeof(ApiResponse<ServiceResponseDto>))]
|
|
[SwaggerResponse(400, "변경된 내용 없음")]
|
|
[SwaggerResponse(401, "인증되지 않은 요청")]
|
|
[SwaggerResponse(403, "권한 없음")]
|
|
[SwaggerResponse(404, "서비스를 찾을 수 없음")]
|
|
[SwaggerResponse(409, "이미 존재하는 서비스명")]
|
|
public async Task<IActionResult> UpdateAsync([FromBody] UpdateServiceRequestDto request)
|
|
{
|
|
var result = await _serviceManagementService.UpdateAsync(request);
|
|
return Ok(ApiResponse<ServiceResponseDto>.Success(result));
|
|
}
|
|
|
|
[HttpPost("list")]
|
|
[SwaggerOperation(
|
|
Summary = "서비스 목록 조회",
|
|
Description = "등록된 서비스 목록을 조회합니다. 페이징, 검색, 상태 필터를 지원합니다.")]
|
|
[SwaggerResponse(200, "조회 성공", typeof(ApiResponse<ServiceListResponseDto>))]
|
|
[SwaggerResponse(401, "인증되지 않은 요청")]
|
|
[SwaggerResponse(403, "권한 없음")]
|
|
public async Task<IActionResult> GetListAsync([FromBody] ServiceListRequestDto request)
|
|
{
|
|
var result = await _serviceManagementService.GetListAsync(request);
|
|
return Ok(ApiResponse<ServiceListResponseDto>.Success(result));
|
|
}
|
|
|
|
[HttpPost("{serviceCode}")]
|
|
[SwaggerOperation(
|
|
Summary = "서비스 상세 조회",
|
|
Description = "특정 서비스의 상세 정보를 조회합니다.")]
|
|
[SwaggerResponse(200, "조회 성공", typeof(ApiResponse<ServiceResponseDto>))]
|
|
[SwaggerResponse(401, "인증되지 않은 요청")]
|
|
[SwaggerResponse(403, "권한 없음")]
|
|
[SwaggerResponse(404, "서비스를 찾을 수 없음")]
|
|
public async Task<IActionResult> GetByServiceCodeAsync([FromRoute] string serviceCode)
|
|
{
|
|
var result = await _serviceManagementService.GetByServiceCodeAsync(serviceCode);
|
|
return Ok(ApiResponse<ServiceResponseDto>.Success(result));
|
|
}
|
|
|
|
[HttpPost("{serviceCode}/status")]
|
|
[SwaggerOperation(
|
|
Summary = "서비스 상태 변경",
|
|
Description = "서비스의 상태를 변경합니다. (Active: 0, Suspended: 1)")]
|
|
[SwaggerResponse(200, "상태 변경 성공", typeof(ApiResponse<ServiceResponseDto>))]
|
|
[SwaggerResponse(400, "잘못된 요청 또는 이미 해당 상태")]
|
|
[SwaggerResponse(401, "인증되지 않은 요청")]
|
|
[SwaggerResponse(403, "권한 없음")]
|
|
[SwaggerResponse(404, "서비스를 찾을 수 없음")]
|
|
public async Task<IActionResult> ChangeStatusAsync(
|
|
[FromRoute] string serviceCode,
|
|
[FromBody] ChangeServiceStatusRequestDto request)
|
|
{
|
|
var result = await _serviceManagementService.ChangeStatusAsync(serviceCode, request);
|
|
return Ok(ApiResponse<ServiceResponseDto>.Success(result));
|
|
}
|
|
|
|
[HttpPost("{serviceCode}/apikey/refresh")]
|
|
[SwaggerOperation(
|
|
Summary = "API Key 재발급",
|
|
Description = "서비스의 API Key를 재발급합니다. 기존 키는 즉시 무효화되며, 새 키는 1회만 표시됩니다.")]
|
|
[SwaggerResponse(200, "재발급 성공", typeof(ApiResponse<ApiKeyRefreshResponseDto>))]
|
|
[SwaggerResponse(401, "인증되지 않은 요청")]
|
|
[SwaggerResponse(403, "권한 없음")]
|
|
[SwaggerResponse(404, "서비스를 찾을 수 없음")]
|
|
public async Task<IActionResult> RefreshApiKeyAsync([FromRoute] string serviceCode)
|
|
{
|
|
var result = await _serviceManagementService.RefreshApiKeyAsync(serviceCode);
|
|
return Ok(ApiResponse<ApiKeyRefreshResponseDto>.Success(result));
|
|
}
|
|
|
|
[HttpPost("{serviceCode}/apns")]
|
|
[SwaggerOperation(
|
|
Summary = "APNs 키 등록",
|
|
Description = "APNs 푸시 발송을 위한 인증 정보를 등록합니다. .p8 파일 내용, Key ID(10자리), Team ID(10자리), Bundle ID가 필요합니다.")]
|
|
[SwaggerResponse(200, "등록 성공", typeof(ApiResponse))]
|
|
[SwaggerResponse(400, "잘못된 요청 (유효하지 않은 키 형식)")]
|
|
[SwaggerResponse(401, "인증되지 않은 요청")]
|
|
[SwaggerResponse(403, "권한 없음")]
|
|
[SwaggerResponse(404, "서비스를 찾을 수 없음")]
|
|
public async Task<IActionResult> RegisterApnsCredentialsAsync(
|
|
[FromRoute] string serviceCode,
|
|
[FromBody] ApnsCredentialsRequestDto request)
|
|
{
|
|
await _serviceManagementService.RegisterApnsCredentialsAsync(serviceCode, request);
|
|
return Ok(ApiResponse.Success());
|
|
}
|
|
|
|
[HttpPost("{serviceCode}/fcm")]
|
|
[SwaggerOperation(
|
|
Summary = "FCM 키 등록",
|
|
Description = "FCM 푸시 발송을 위한 Service Account JSON을 등록합니다. Firebase Console에서 다운로드한 service-account.json 내용이 필요합니다.")]
|
|
[SwaggerResponse(200, "등록 성공", typeof(ApiResponse))]
|
|
[SwaggerResponse(400, "잘못된 요청 (유효하지 않은 JSON 형식)")]
|
|
[SwaggerResponse(401, "인증되지 않은 요청")]
|
|
[SwaggerResponse(403, "권한 없음")]
|
|
[SwaggerResponse(404, "서비스를 찾을 수 없음")]
|
|
public async Task<IActionResult> RegisterFcmCredentialsAsync(
|
|
[FromRoute] string serviceCode,
|
|
[FromBody] FcmCredentialsRequestDto request)
|
|
{
|
|
await _serviceManagementService.RegisterFcmCredentialsAsync(serviceCode, request);
|
|
return Ok(ApiResponse.Success());
|
|
}
|
|
|
|
[HttpPost("{serviceCode}/credentials")]
|
|
[SwaggerOperation(
|
|
Summary = "푸시 키 정보 조회",
|
|
Description = "서비스에 등록된 APNs/FCM 키의 메타 정보를 조회합니다. 민감 정보(Private Key)는 반환되지 않습니다.")]
|
|
[SwaggerResponse(200, "조회 성공", typeof(ApiResponse<CredentialsResponseDto>))]
|
|
[SwaggerResponse(401, "인증되지 않은 요청")]
|
|
[SwaggerResponse(403, "권한 없음")]
|
|
[SwaggerResponse(404, "서비스를 찾을 수 없음")]
|
|
public async Task<IActionResult> GetCredentialsAsync([FromRoute] string serviceCode)
|
|
{
|
|
var result = await _serviceManagementService.GetCredentialsAsync(serviceCode);
|
|
return Ok(ApiResponse<CredentialsResponseDto>.Success(result));
|
|
}
|
|
|
|
[HttpPost("{serviceCode}/ip/list")]
|
|
[SwaggerOperation(
|
|
Summary = "IP 화이트리스트 조회",
|
|
Description = "서비스에 등록된 IP 화이트리스트 목록을 조회합니다.")]
|
|
[SwaggerResponse(200, "조회 성공", typeof(ApiResponse<IpListResponseDto>))]
|
|
[SwaggerResponse(401, "인증되지 않은 요청")]
|
|
[SwaggerResponse(403, "권한 없음")]
|
|
[SwaggerResponse(404, "서비스를 찾을 수 없음")]
|
|
public async Task<IActionResult> GetIpListAsync([FromRoute] string serviceCode)
|
|
{
|
|
var result = await _serviceManagementService.GetIpListAsync(serviceCode);
|
|
return Ok(ApiResponse<IpListResponseDto>.Success(result));
|
|
}
|
|
|
|
[HttpPost("{serviceCode}/ip/add")]
|
|
[SwaggerOperation(
|
|
Summary = "IP 추가",
|
|
Description = "서비스의 IP 화이트리스트에 새 IP를 추가합니다. IPv4 형식만 지원합니다.")]
|
|
[SwaggerResponse(200, "추가 성공", typeof(ApiResponse<ServiceIpDto>))]
|
|
[SwaggerResponse(400, "잘못된 요청 (유효하지 않은 IP 형식)")]
|
|
[SwaggerResponse(401, "인증되지 않은 요청")]
|
|
[SwaggerResponse(403, "권한 없음")]
|
|
[SwaggerResponse(404, "서비스를 찾을 수 없음")]
|
|
[SwaggerResponse(409, "이미 등록된 IP")]
|
|
public async Task<IActionResult> AddIpAsync(
|
|
[FromRoute] string serviceCode,
|
|
[FromBody] AddIpRequestDto request)
|
|
{
|
|
var result = await _serviceManagementService.AddIpAsync(serviceCode, request);
|
|
return Ok(ApiResponse<ServiceIpDto>.Success(result));
|
|
}
|
|
|
|
[HttpPost("{serviceCode}/ip/delete")]
|
|
[SwaggerOperation(
|
|
Summary = "IP 삭제",
|
|
Description = "서비스의 IP 화이트리스트에서 IP를 삭제합니다.")]
|
|
[SwaggerResponse(200, "삭제 성공", typeof(ApiResponse))]
|
|
[SwaggerResponse(401, "인증되지 않은 요청")]
|
|
[SwaggerResponse(403, "권한 없음")]
|
|
[SwaggerResponse(404, "서비스 또는 IP를 찾을 수 없음")]
|
|
public async Task<IActionResult> DeleteIpAsync(
|
|
[FromRoute] string serviceCode,
|
|
[FromBody] DeleteIpRequestDto request)
|
|
{
|
|
await _serviceManagementService.DeleteIpAsync(serviceCode, request);
|
|
return Ok(ApiResponse.Success());
|
|
}
|
|
}
|