using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Swashbuckle.AspNetCore.Annotations; using SPMS.Application.DTOs.Account; using SPMS.Application.Interfaces; using SPMS.Domain.Common; namespace SPMS.API.Controllers; [ApiController] [Route("v1/in/account")] [ApiExplorerSettings(GroupName = "account")] [Authorize(Roles = "Super")] public class AccountController : ControllerBase { private readonly IAccountService _accountService; public AccountController(IAccountService accountService) { _accountService = accountService; } [HttpPost("create")] [SwaggerOperation( Summary = "운영자 계정 생성", Description = "Super Admin이 새로운 운영자(Manager/User) 계정을 생성합니다.")] [SwaggerResponse(200, "생성 성공", typeof(ApiResponse))] [SwaggerResponse(400, "잘못된 요청")] [SwaggerResponse(401, "인증되지 않은 요청")] [SwaggerResponse(403, "권한 없음")] [SwaggerResponse(409, "이메일 중복")] public async Task CreateAsync([FromBody] CreateAccountRequestDto request) { var result = await _accountService.CreateAsync(request); return Ok(ApiResponse.Success(result)); } [HttpPost("list")] [SwaggerOperation( Summary = "운영자 목록 조회", Description = "Super Admin이 운영자(Manager/User) 목록을 조회합니다. Super Admin은 목록에 포함되지 않습니다.")] [SwaggerResponse(200, "조회 성공", typeof(ApiResponse))] [SwaggerResponse(401, "인증되지 않은 요청")] [SwaggerResponse(403, "권한 없음")] public async Task GetListAsync([FromBody] AccountListRequestDto request) { var result = await _accountService.GetListAsync(request); return Ok(ApiResponse.Success(result)); } [HttpPost("{adminCode}")] [SwaggerOperation( Summary = "운영자 상세 조회", Description = "Super Admin이 특정 운영자의 상세 정보를 조회합니다.")] [SwaggerResponse(200, "조회 성공", typeof(ApiResponse))] [SwaggerResponse(401, "인증되지 않은 요청")] [SwaggerResponse(403, "권한 없음")] [SwaggerResponse(404, "운영자를 찾을 수 없음")] public async Task GetByAdminCodeAsync([FromRoute] string adminCode) { var result = await _accountService.GetByAdminCodeAsync(adminCode); return Ok(ApiResponse.Success(result)); } [HttpPost("{adminCode}/update")] [SwaggerOperation( Summary = "운영자 정보 수정", Description = "Super Admin이 운영자의 정보(이름, 전화번호, 권한)를 수정합니다.")] [SwaggerResponse(200, "수정 성공", typeof(ApiResponse))] [SwaggerResponse(400, "잘못된 요청")] [SwaggerResponse(401, "인증되지 않은 요청")] [SwaggerResponse(403, "권한 없음")] [SwaggerResponse(404, "운영자를 찾을 수 없음")] public async Task UpdateAsync( [FromRoute] string adminCode, [FromBody] UpdateAccountRequestDto request) { var result = await _accountService.UpdateAsync(adminCode, request); return Ok(ApiResponse.Success(result)); } [HttpPost("{adminCode}/delete")] [SwaggerOperation( Summary = "운영자 계정 삭제", Description = "Super Admin이 운영자 계정을 삭제합니다. (Soft Delete)")] [SwaggerResponse(200, "삭제 성공")] [SwaggerResponse(401, "인증되지 않은 요청")] [SwaggerResponse(403, "권한 없음")] [SwaggerResponse(404, "운영자를 찾을 수 없음")] public async Task DeleteAsync([FromRoute] string adminCode) { await _accountService.DeleteAsync(adminCode); return Ok(ApiResponse.Success()); } [HttpPost("operator/create")] [SwaggerOperation( Summary = "운영자 계정 생성 (이메일 링크)", Description = "Super Admin이 운영자 계정을 생성합니다. 비밀번호 설정 이메일이 발송됩니다.")] [SwaggerResponse(200, "생성 성공", typeof(ApiResponse))] [SwaggerResponse(400, "잘못된 요청")] [SwaggerResponse(401, "인증되지 않은 요청")] [SwaggerResponse(403, "권한 없음")] [SwaggerResponse(409, "이메일 중복")] public async Task CreateOperatorAsync([FromBody] OperatorCreateRequestDto request) { var result = await _accountService.CreateOperatorAsync(request); return Ok(ApiResponse.Success(result)); } [HttpPost("operator/delete")] [SwaggerOperation( Summary = "운영자 계정 삭제", Description = "Super Admin이 운영자 계정을 삭제합니다. (Soft Delete) 자기 자신은 삭제할 수 없습니다.")] [SwaggerResponse(200, "삭제 성공")] [SwaggerResponse(401, "인증되지 않은 요청")] [SwaggerResponse(403, "권한 없음 / 자기 자신 삭제 불가")] [SwaggerResponse(404, "운영자를 찾을 수 없음")] public async Task DeleteOperatorAsync([FromBody] OperatorDeleteRequestDto request) { var adminId = GetAdminId(); await _accountService.DeleteOperatorAsync(request.AdminCode, adminId); return Ok(ApiResponse.Success()); } [HttpPost("operator/list")] [SwaggerOperation( Summary = "운영자 목록 조회", Description = "Super Admin이 운영자(Manager/User) 목록을 조회합니다. is_active 필터로 비활성 운영자도 조회 가능합니다.")] [SwaggerResponse(200, "조회 성공", typeof(ApiResponse))] [SwaggerResponse(401, "인증되지 않은 요청")] [SwaggerResponse(403, "권한 없음")] public async Task GetOperatorListAsync([FromBody] OperatorListRequestDto request) { var result = await _accountService.GetOperatorListAsync(request); return Ok(ApiResponse.Success(result)); } [HttpPost("operator/password/reset")] [SwaggerOperation( Summary = "운영자 비밀번호 초기화", Description = "Super Admin이 운영자의 비밀번호를 초기화합니다. 비밀번호 재설정 이메일이 발송됩니다.")] [SwaggerResponse(200, "초기화 성공", typeof(ApiResponse))] [SwaggerResponse(401, "인증되지 않은 요청")] [SwaggerResponse(403, "권한 없음")] [SwaggerResponse(404, "운영자를 찾을 수 없음")] public async Task ResetOperatorPasswordAsync([FromBody] OperatorPasswordResetRequestDto request) { var result = await _accountService.ResetOperatorPasswordAsync(request.AdminCode); return Ok(ApiResponse.Success(result)); } private long GetAdminId() { var adminIdClaim = User.FindFirst("adminId")?.Value; if (string.IsNullOrEmpty(adminIdClaim) || !long.TryParse(adminIdClaim, out var adminId)) { throw new SPMS.Domain.Exceptions.SpmsException( ErrorCodes.Unauthorized, "인증 정보를 확인할 수 없습니다.", 401); } return adminId; } }