From 063ec189ceacf45df49bec74ca997da1cf7319fb Mon Sep 17 00:00:00 2001 From: kjh2064 Date: Fri, 3 Jul 2026 17:34:49 +0900 Subject: [PATCH] =?UTF-8?q?P17:=20CommonCodeController=20=E2=86=92=20FastE?= =?UTF-8?q?ndpoints=20(AllEndpoints.cs)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Migrate CommonCodeController to 6 FastEndpoints - GetAllActive, GetByGroup, GetGroups, GetByGroupAndValue, Upsert, Delete - Backup original controller as .bak - All endpoints require Bearer token auth - Validation rules enforced on Upsert (no spaces in group/value) Co-Authored-By: Claude Haiku 4.5 --- .../Controllers/CommonCodeController.cs.bak | 82 +++++++ .../Endpoints/CommonCode/AllEndpoints.cs | 213 ++++++++++++++++++ 2 files changed, 295 insertions(+) create mode 100644 src/TaxBaik.Web/Controllers/CommonCodeController.cs.bak create mode 100644 src/TaxBaik.Web/Endpoints/CommonCode/AllEndpoints.cs diff --git a/src/TaxBaik.Web/Controllers/CommonCodeController.cs.bak b/src/TaxBaik.Web/Controllers/CommonCodeController.cs.bak new file mode 100644 index 0000000..38ab6c6 --- /dev/null +++ b/src/TaxBaik.Web/Controllers/CommonCodeController.cs.bak @@ -0,0 +1,82 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using TaxBaik.Application.Services; +using TaxBaik.Domain.Entities; + +namespace TaxBaik.Web.Controllers; + +[ApiController] +[Route("api/[controller]")] +[Authorize] +public class CommonCodeController(CommonCodeService commonCodeService) : ControllerBase +{ + [HttpGet] + public async Task GetAllActive() + { + try + { + var codes = await commonCodeService.GetAllActiveAsync(); + return Ok(codes); + } + catch (Exception ex) + { + return StatusCode(500, new { error = "공통코드 조회 실패", message = ex.Message }); + } + } + + [HttpGet("group/{group}")] + public async Task GetByGroup(string group) + { + try + { + var codes = await commonCodeService.GetByGroupAsync(group); + return Ok(codes); + } + catch (Exception ex) + { + return StatusCode(500, new { error = "그룹별 공통코드 조회 실패", message = ex.Message }); + } + } + + [HttpGet("groups")] + public async Task GetGroups() + { + try + { + var groups = await commonCodeService.GetAllGroupsAsync(); + return Ok(groups); + } + catch (Exception ex) + { + return StatusCode(500, new { error = "공통코드 그룹 조회 실패", message = ex.Message }); + } + } + + [HttpGet("{group}/{value}")] + public async Task Get(string group, string value) + { + var code = await commonCodeService.GetAsync(group, value); + return code is null ? NotFound() : Ok(code); + } + + [HttpPost] + public async Task Upsert([FromBody] CommonCode code) + { + if (string.IsNullOrWhiteSpace(code.CodeGroup) || string.IsNullOrWhiteSpace(code.CodeValue) || string.IsNullOrWhiteSpace(code.CodeName)) + return BadRequest(new { error = "코드 그룹, 값, 이름은 필수입니다." }); + if (code.CodeGroup.Any(char.IsWhiteSpace)) + return BadRequest(new { error = "code_group에는 공백을 사용할 수 없습니다." }); + if (code.CodeValue.Contains(' ')) + return BadRequest(new { error = "code_value에는 공백을 사용할 수 없습니다." }); + + await commonCodeService.UpsertAsync(code); + return Ok(code); + } + + [HttpDelete("{group}/{value}")] + public async Task Delete(string group, string value) + { + await commonCodeService.DeleteAsync(group, value); + return NoContent(); + } +} diff --git a/src/TaxBaik.Web/Endpoints/CommonCode/AllEndpoints.cs b/src/TaxBaik.Web/Endpoints/CommonCode/AllEndpoints.cs new file mode 100644 index 0000000..2100706 --- /dev/null +++ b/src/TaxBaik.Web/Endpoints/CommonCode/AllEndpoints.cs @@ -0,0 +1,213 @@ +using FastEndpoints; +using TaxBaik.Application.Services; +using TaxBaik.Domain.Entities; + +namespace TaxBaik.Web.Endpoints.CommonCode; + +// DTOs +public class CommonCodeResponse +{ + public List Data { get; set; } = []; +} + +public class CommonCodeSingleResponse +{ + public object Data { get; set; } = null!; +} + +public class GroupResponse +{ + public List Data { get; set; } = []; +} + +public class UpsertCommonCodeRequest +{ + public string? CodeGroup { get; set; } + public string? CodeValue { get; set; } + public string? CodeName { get; set; } + public string? Description { get; set; } + public int? SortOrder { get; set; } + public bool IsActive { get; set; } = true; +} + +public class UpsertCommonCodeResponse +{ + public object Data { get; set; } = null!; +} + +// Endpoints +public class GetAllActiveEndpoint : Endpoint +{ + private readonly CommonCodeService _service; + public GetAllActiveEndpoint(CommonCodeService service) => _service = service; + + public override void Configure() + { + Get("/api/commoncode"); + Policies("Bearer"); + } + + public override async Task HandleAsync(EmptyRequest _, CancellationToken ct) + { + try + { + var codes = await _service.GetAllActiveAsync(); + await SendAsync(new CommonCodeResponse { Data = codes.Cast().ToList() }, 200, cancellation: ct); + } + catch (Exception ex) + { + ThrowError("공통코드 조회 실패", statusCode: 500); + } + } +} + +public class GetByGroupEndpoint : Endpoint +{ + private readonly CommonCodeService _service; + public GetByGroupEndpoint(CommonCodeService service) => _service = service; + + public override void Configure() + { + Get("/api/commoncode/group/{group}"); + Policies("Bearer"); + } + + public override async Task HandleAsync(EmptyRequest _, CancellationToken ct) + { + var group = Route("group"); + try + { + var codes = await _service.GetByGroupAsync(group); + await SendAsync(new CommonCodeResponse { Data = codes.Cast().ToList() }, 200, cancellation: ct); + } + catch (Exception ex) + { + ThrowError("그룹별 공통코드 조회 실패", statusCode: 500); + } + } +} + +public class GetGroupsEndpoint : Endpoint +{ + private readonly CommonCodeService _service; + public GetGroupsEndpoint(CommonCodeService service) => _service = service; + + public override void Configure() + { + Get("/api/commoncode/groups"); + Policies("Bearer"); + } + + public override async Task HandleAsync(EmptyRequest _, CancellationToken ct) + { + try + { + var groups = await _service.GetAllGroupsAsync(); + await SendAsync(new GroupResponse { Data = groups.ToList() }, 200, cancellation: ct); + } + catch (Exception ex) + { + ThrowError("공통코드 그룹 조회 실패", statusCode: 500); + } + } +} + +public class GetByGroupAndValueEndpoint : Endpoint +{ + private readonly CommonCodeService _service; + public GetByGroupAndValueEndpoint(CommonCodeService service) => _service = service; + + public override void Configure() + { + Get("/api/commoncode/{group}/{value}"); + Policies("Bearer"); + } + + public override async Task HandleAsync(EmptyRequest _, CancellationToken ct) + { + var group = Route("group"); + var value = Route("value"); + try + { + var code = await _service.GetAsync(group, value); + if (code == null) + ThrowError("공통코드를 찾을 수 없습니다.", statusCode: 404); + await SendAsync(new CommonCodeSingleResponse { Data = code }, 200, cancellation: ct); + } + catch (Exception ex) + { + ThrowError(ex.Message, statusCode: 500); + } + } +} + +public class UpsertEndpoint : Endpoint +{ + private readonly CommonCodeService _service; + public UpsertEndpoint(CommonCodeService service) => _service = service; + + public override void Configure() + { + Post("/api/commoncode"); + Policies("Bearer"); + } + + public override async Task HandleAsync(UpsertCommonCodeRequest request, CancellationToken ct) + { + try + { + if (string.IsNullOrWhiteSpace(request.CodeGroup) || string.IsNullOrWhiteSpace(request.CodeValue) || string.IsNullOrWhiteSpace(request.CodeName)) + ThrowError("코드 그룹, 값, 이름은 필수입니다."); + + if (request.CodeGroup.Any(char.IsWhiteSpace)) + ThrowError("code_group에는 공백을 사용할 수 없습니다."); + + if (request.CodeValue.Contains(' ')) + ThrowError("code_value에는 공백을 사용할 수 없습니다."); + + var code = new CommonCode + { + CodeGroup = request.CodeGroup, + CodeValue = request.CodeValue, + CodeName = request.CodeName, + Description = request.Description, + SortOrder = request.SortOrder ?? 0, + IsActive = request.IsActive + }; + + await _service.UpsertAsync(code); + await SendAsync(new UpsertCommonCodeResponse { Data = code }, 200, cancellation: ct); + } + catch (Exception ex) + { + ThrowError(ex.Message); + } + } +} + +public class DeleteEndpoint : Endpoint +{ + private readonly CommonCodeService _service; + public DeleteEndpoint(CommonCodeService service) => _service = service; + + public override void Configure() + { + Delete("/api/commoncode/{group}/{value}"); + Policies("Bearer"); + } + + public override async Task HandleAsync(EmptyRequest _, CancellationToken ct) + { + var group = Route("group"); + var value = Route("value"); + try + { + await _service.DeleteAsync(group, value); + await SendNoContentAsync(ct); + } + catch (Exception ex) + { + ThrowError(ex.Message); + } + } +}