using FastEndpoints; using TaxBaik.Application.Services; using TaxBaik.Domain.Entities; using FaqEntity = TaxBaik.Domain.Entities.Faq; namespace TaxBaik.Web.Endpoints.Faq; // DTOs public class CreateFaqRequest { public string Question { get; set; } = string.Empty; public string Answer { get; set; } = string.Empty; public string? Category { get; set; } public int SortOrder { get; set; } } public class UpdateFaqRequest { public string Question { get; set; } = string.Empty; public string Answer { get; set; } = string.Empty; public string? Category { get; set; } public int SortOrder { get; set; } public bool IsActive { get; set; } = true; } public class FaqListResponse { public List Data { get; set; } = []; } public class FaqCreateResponse { public int Id { get; set; } } public class FaqUpdateResponse { public string Message { get; set; } = string.Empty; } // Endpoints public class GetActiveEndpoint : Endpoint { private readonly FaqService _service; public GetActiveEndpoint(FaqService service) => _service = service; public override void Configure() { Get("/api/faq/active"); AllowAnonymous(); } public override async Task HandleAsync(EmptyRequest _, CancellationToken ct) { try { var faqs = await _service.GetActiveAsync(ct); await SendAsync(new FaqListResponse { Data = faqs.ToList() }, 200, cancellation: ct); } catch (Exception ex) { ThrowError(ex.Message, statusCode: 500); } } } public class GetAllEndpoint : Endpoint { private readonly FaqService _service; public GetAllEndpoint(FaqService service) => _service = service; public override void Configure() { Get("/api/faq"); Policies("Bearer"); } public override async Task HandleAsync(EmptyRequest _, CancellationToken ct) { try { var faqs = await _service.GetAllAsync(ct); await SendAsync(new FaqListResponse { Data = faqs.ToList() }, 200, cancellation: ct); } catch (Exception ex) { ThrowError(ex.Message, statusCode: 500); } } } public class GetByIdEndpoint : Endpoint { private readonly FaqService _service; public GetByIdEndpoint(FaqService service) => _service = service; public override void Configure() { Get("/api/faq/{id}"); Policies("Bearer"); } public override async Task HandleAsync(EmptyRequest _, CancellationToken ct) { var id = Route("id"); try { var faq = await _service.GetByIdAsync(id, ct); if (faq == null) ThrowError("FAQ를 찾을 수 없습니다.", statusCode: 404); await SendAsync(faq, 200, cancellation: ct); } catch (Exception ex) { ThrowError(ex.Message, statusCode: 500); } } } public class CreateEndpoint : Endpoint { private readonly FaqService _service; public CreateEndpoint(FaqService service) => _service = service; public override void Configure() { Post("/api/faq"); Policies("Bearer"); } public override async Task HandleAsync(CreateFaqRequest request, CancellationToken ct) { try { var faq = new FaqEntity { Question = request.Question, Answer = request.Answer, Category = request.Category, SortOrder = request.SortOrder, IsActive = true, CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow }; var id = await _service.CreateAsync(faq, ct); await SendAsync(new FaqCreateResponse { Id = id }, 201, cancellation: ct); } catch (ValidationException ex) { ThrowError(ex.Message); } catch (Exception ex) { ThrowError(ex.Message, statusCode: 500); } } } public class UpdateEndpoint : Endpoint { private readonly FaqService _service; public UpdateEndpoint(FaqService service) => _service = service; public override void Configure() { Put("/api/faq/{id}"); Policies("Bearer"); } public override async Task HandleAsync(UpdateFaqRequest request, CancellationToken ct) { var id = Route("id"); try { var faq = new FaqEntity { Id = id, Question = request.Question, Answer = request.Answer, Category = request.Category, SortOrder = request.SortOrder, IsActive = request.IsActive, UpdatedAt = DateTime.UtcNow }; await _service.UpdateAsync(faq, ct); await SendAsync(new FaqUpdateResponse { Message = "FAQ가 수정되었습니다." }, 200, cancellation: ct); } catch (ValidationException ex) { ThrowError(ex.Message); } catch (Exception ex) { ThrowError(ex.Message, statusCode: 500); } } } public class DeleteEndpoint : Endpoint { private readonly FaqService _service; public DeleteEndpoint(FaqService service) => _service = service; public override void Configure() { Delete("/api/faq/{id}"); Policies("Bearer"); } public override async Task HandleAsync(EmptyRequest _, CancellationToken ct) { var id = Route("id"); try { await _service.DeleteAsync(id, ct); await SendAsync(new EmptyResponse(), 204, cancellation: ct); } catch (Exception ex) { ThrowError(ex.Message, statusCode: 500); } } }