diff --git a/src/TaxBaik.Web/Controllers/BlogController.cs b/src/TaxBaik.Web/Controllers/BlogController.cs.bak similarity index 100% rename from src/TaxBaik.Web/Controllers/BlogController.cs rename to src/TaxBaik.Web/Controllers/BlogController.cs.bak diff --git a/src/TaxBaik.Web/Endpoints/Blog/BlogDtos.cs b/src/TaxBaik.Web/Endpoints/Blog/BlogDtos.cs new file mode 100644 index 0000000..de13b4d --- /dev/null +++ b/src/TaxBaik.Web/Endpoints/Blog/BlogDtos.cs @@ -0,0 +1,33 @@ +using TaxBaik.Application.DTOs; + +namespace TaxBaik.Web.Endpoints.Blog; + +public class BlogPublishedQuery +{ + public int Page { get; set; } = 1; + public int PageSize { get; set; } = 12; +} + +public class BlogAdminQuery +{ + public int Page { get; set; } = 1; + public int PageSize { get; set; } = 20; +} + +public class PaginatedResponse +{ + public List Data { get; set; } = []; + public int Total { get; set; } + public int Page { get; set; } + public int PageSize { get; set; } +} + +public class BlogPostListResponse +{ + public List Posts { get; set; } = []; +} + +public class MessageResponse +{ + public string Message { get; set; } = string.Empty; +} diff --git a/src/TaxBaik.Web/Endpoints/Blog/CreateEndpoint.cs b/src/TaxBaik.Web/Endpoints/Blog/CreateEndpoint.cs new file mode 100644 index 0000000..3632e84 --- /dev/null +++ b/src/TaxBaik.Web/Endpoints/Blog/CreateEndpoint.cs @@ -0,0 +1,34 @@ +using FastEndpoints; +using TaxBaik.Application.DTOs; +using TaxBaik.Application.Services; + +namespace TaxBaik.Web.Endpoints.Blog; + +public class CreateEndpoint : Endpoint +{ + private readonly BlogService _blogService; + + public CreateEndpoint(BlogService blogService) + { + _blogService = blogService; + } + + public override void Configure() + { + Post("/api/blog"); + Policies("Bearer"); + } + + public override async Task HandleAsync(CreateBlogPostDto request, CancellationToken ct) + { + try + { + var result = await _blogService.CreateAsync(request); + await SendAsync(result, 201, cancellation: ct); + } + catch (ValidationException ex) + { + ThrowError(ex.Message, statusCode: 400); + } + } +} diff --git a/src/TaxBaik.Web/Endpoints/Blog/DeleteEndpoint.cs b/src/TaxBaik.Web/Endpoints/Blog/DeleteEndpoint.cs new file mode 100644 index 0000000..8491e47 --- /dev/null +++ b/src/TaxBaik.Web/Endpoints/Blog/DeleteEndpoint.cs @@ -0,0 +1,27 @@ +using FastEndpoints; +using TaxBaik.Application.Services; + +namespace TaxBaik.Web.Endpoints.Blog; + +public class DeleteEndpoint : Endpoint +{ + private readonly BlogService _blogService; + + public DeleteEndpoint(BlogService blogService) + { + _blogService = blogService; + } + + public override void Configure() + { + Delete("/api/blog/{id}"); + Policies("Bearer"); + } + + public override async Task HandleAsync(EmptyRequest _, CancellationToken ct) + { + var id = Route("id"); + await _blogService.ArchiveAsync(id); + await SendAsync(new EmptyResponse(), 204, cancellation: ct); + } +} diff --git a/src/TaxBaik.Web/Endpoints/Blog/GetAdminPagedEndpoint.cs b/src/TaxBaik.Web/Endpoints/Blog/GetAdminPagedEndpoint.cs new file mode 100644 index 0000000..42edf43 --- /dev/null +++ b/src/TaxBaik.Web/Endpoints/Blog/GetAdminPagedEndpoint.cs @@ -0,0 +1,32 @@ +using FastEndpoints; +using TaxBaik.Application.Services; + +namespace TaxBaik.Web.Endpoints.Blog; + +public class GetAdminPagedEndpoint : Endpoint> +{ + private readonly BlogService _blogService; + + public GetAdminPagedEndpoint(BlogService blogService) + { + _blogService = blogService; + } + + public override void Configure() + { + Get("/api/blog/admin"); + Policies("Bearer"); + } + + public override async Task HandleAsync(BlogAdminQuery request, CancellationToken ct) + { + var (items, total) = await _blogService.GetAdminPagedAsync(request.Page, request.PageSize); + await SendAsync(new PaginatedResponse + { + Data = items.Cast().ToList(), + Total = total, + Page = request.Page, + PageSize = request.PageSize + }, 200, cancellation: ct); + } +} diff --git a/src/TaxBaik.Web/Endpoints/Blog/GetAllEndpoint.cs b/src/TaxBaik.Web/Endpoints/Blog/GetAllEndpoint.cs new file mode 100644 index 0000000..55852e9 --- /dev/null +++ b/src/TaxBaik.Web/Endpoints/Blog/GetAllEndpoint.cs @@ -0,0 +1,29 @@ +using FastEndpoints; +using TaxBaik.Application.Services; + +namespace TaxBaik.Web.Endpoints.Blog; + +public class GetAllEndpoint : Endpoint +{ + private readonly BlogService _blogService; + + public GetAllEndpoint(BlogService blogService) + { + _blogService = blogService; + } + + public override void Configure() + { + Get("/api/blog/admin/all"); + Policies("Bearer"); + } + + public override async Task HandleAsync(EmptyRequest _, CancellationToken ct) + { + var posts = await _blogService.GetAllAsync(); + await SendAsync(new BlogPostListResponse + { + Posts = posts.Cast().ToList() + }, 200, cancellation: ct); + } +} diff --git a/src/TaxBaik.Web/Endpoints/Blog/GetArchivedPagedEndpoint.cs b/src/TaxBaik.Web/Endpoints/Blog/GetArchivedPagedEndpoint.cs new file mode 100644 index 0000000..4833b74 --- /dev/null +++ b/src/TaxBaik.Web/Endpoints/Blog/GetArchivedPagedEndpoint.cs @@ -0,0 +1,32 @@ +using FastEndpoints; +using TaxBaik.Application.Services; + +namespace TaxBaik.Web.Endpoints.Blog; + +public class GetArchivedPagedEndpoint : Endpoint> +{ + private readonly BlogService _blogService; + + public GetArchivedPagedEndpoint(BlogService blogService) + { + _blogService = blogService; + } + + public override void Configure() + { + Get("/api/blog/admin/archived"); + Policies("Bearer"); + } + + public override async Task HandleAsync(BlogAdminQuery request, CancellationToken ct) + { + var (items, total) = await _blogService.GetArchivedPagedAsync(request.Page, request.PageSize); + await SendAsync(new PaginatedResponse + { + Data = items.Cast().ToList(), + Total = total, + Page = request.Page, + PageSize = request.PageSize + }, 200, cancellation: ct); + } +} diff --git a/src/TaxBaik.Web/Endpoints/Blog/GetByIdEndpoint.cs b/src/TaxBaik.Web/Endpoints/Blog/GetByIdEndpoint.cs new file mode 100644 index 0000000..09d2b6d --- /dev/null +++ b/src/TaxBaik.Web/Endpoints/Blog/GetByIdEndpoint.cs @@ -0,0 +1,32 @@ +using FastEndpoints; +using TaxBaik.Application.Services; + +namespace TaxBaik.Web.Endpoints.Blog; + +public class GetByIdEndpoint : Endpoint +{ + private readonly BlogService _blogService; + + public GetByIdEndpoint(BlogService blogService) + { + _blogService = blogService; + } + + public override void Configure() + { + Get("/api/blog/admin/{id}"); + Policies("Bearer"); + } + + public override async Task HandleAsync(EmptyRequest _, CancellationToken ct) + { + var id = Route("id"); + var post = await _blogService.GetByIdAsync(id); + if (post == null) + { + ThrowError("포스트를 찾을 수 없습니다.", statusCode: 404); + } + + await SendAsync(post, 200, cancellation: ct); + } +} diff --git a/src/TaxBaik.Web/Endpoints/Blog/GetBySlugEndpoint.cs b/src/TaxBaik.Web/Endpoints/Blog/GetBySlugEndpoint.cs new file mode 100644 index 0000000..ce4cdb2 --- /dev/null +++ b/src/TaxBaik.Web/Endpoints/Blog/GetBySlugEndpoint.cs @@ -0,0 +1,32 @@ +using FastEndpoints; +using TaxBaik.Application.Services; + +namespace TaxBaik.Web.Endpoints.Blog; + +public class GetBySlugEndpoint : Endpoint +{ + private readonly BlogService _blogService; + + public GetBySlugEndpoint(BlogService blogService) + { + _blogService = blogService; + } + + public override void Configure() + { + Get("/api/blog/{slug}"); + AllowAnonymous(); + } + + public override async Task HandleAsync(EmptyRequest _, CancellationToken ct) + { + var slug = Route("slug") ?? string.Empty; + var post = await _blogService.GetBySlugAsync(slug); + if (post == null) + { + ThrowError("포스트를 찾을 수 없습니다.", statusCode: 404); + } + + await SendAsync(post, 200, cancellation: ct); + } +} diff --git a/src/TaxBaik.Web/Endpoints/Blog/GetPublishedEndpoint.cs b/src/TaxBaik.Web/Endpoints/Blog/GetPublishedEndpoint.cs new file mode 100644 index 0000000..58a32bc --- /dev/null +++ b/src/TaxBaik.Web/Endpoints/Blog/GetPublishedEndpoint.cs @@ -0,0 +1,32 @@ +using FastEndpoints; +using TaxBaik.Application.Services; + +namespace TaxBaik.Web.Endpoints.Blog; + +public class GetPublishedEndpoint : Endpoint> +{ + private readonly BlogService _blogService; + + public GetPublishedEndpoint(BlogService blogService) + { + _blogService = blogService; + } + + public override void Configure() + { + Get("/api/blog"); + AllowAnonymous(); + } + + public override async Task HandleAsync(BlogPublishedQuery request, CancellationToken ct) + { + var (items, total) = await _blogService.GetPublishedPagedAsync(request.Page, request.PageSize); + await SendAsync(new PaginatedResponse + { + Data = items.Cast().ToList(), + Total = total, + Page = request.Page, + PageSize = request.PageSize + }, 200, cancellation: ct); + } +} diff --git a/src/TaxBaik.Web/Endpoints/Blog/RestoreEndpoint.cs b/src/TaxBaik.Web/Endpoints/Blog/RestoreEndpoint.cs new file mode 100644 index 0000000..180eef2 --- /dev/null +++ b/src/TaxBaik.Web/Endpoints/Blog/RestoreEndpoint.cs @@ -0,0 +1,27 @@ +using FastEndpoints; +using TaxBaik.Application.Services; + +namespace TaxBaik.Web.Endpoints.Blog; + +public class RestoreEndpoint : Endpoint +{ + private readonly BlogService _blogService; + + public RestoreEndpoint(BlogService blogService) + { + _blogService = blogService; + } + + public override void Configure() + { + Post("/api/blog/{id}/restore"); + Policies("Bearer"); + } + + public override async Task HandleAsync(EmptyRequest _, CancellationToken ct) + { + var id = Route("id"); + await _blogService.RestoreAsync(id); + await SendAsync(new EmptyResponse(), 204, cancellation: ct); + } +} diff --git a/src/TaxBaik.Web/Endpoints/Blog/UpdateEndpoint.cs b/src/TaxBaik.Web/Endpoints/Blog/UpdateEndpoint.cs new file mode 100644 index 0000000..431b120 --- /dev/null +++ b/src/TaxBaik.Web/Endpoints/Blog/UpdateEndpoint.cs @@ -0,0 +1,40 @@ +using FastEndpoints; +using TaxBaik.Application.DTOs; +using TaxBaik.Application.Services; + +namespace TaxBaik.Web.Endpoints.Blog; + +public class UpdateEndpoint : Endpoint +{ + private readonly BlogService _blogService; + + public UpdateEndpoint(BlogService blogService) + { + _blogService = blogService; + } + + public override void Configure() + { + Put("/api/blog/{id}"); + Policies("Bearer"); + } + + public override async Task HandleAsync(CreateBlogPostDto request, CancellationToken ct) + { + var id = Route("id"); + try + { + var result = await _blogService.UpdateAsync(id, request); + if (result == null) + { + ThrowError("포스트를 찾을 수 없습니다.", statusCode: 404); + } + + await SendAsync(result, 200, cancellation: ct); + } + catch (ValidationException ex) + { + ThrowError(ex.Message, statusCode: 400); + } + } +}