diff --git a/src/TaxBaik.Web/Endpoints/SitemapEndpoint.cs b/src/TaxBaik.Web/Endpoints/SitemapEndpoint.cs new file mode 100644 index 0000000..0043101 --- /dev/null +++ b/src/TaxBaik.Web/Endpoints/SitemapEndpoint.cs @@ -0,0 +1,61 @@ +using FastEndpoints; +using TaxBaik.Application.Services; + +namespace TaxBaik.Web.Endpoints; + +/// +/// GET /api/sitemap.xml - 동적 사이트맵 생성 +/// 블로그 포스트, FAQ, 공지사항 포함 +/// +public class SitemapEndpoint : EndpointWithoutRequest +{ + private readonly BlogService _blogService; + + public SitemapEndpoint(BlogService blogService) + { + _blogService = blogService; + } + + public override void Configure() + { + Get("/sitemap.xml"); + AllowAnonymous(); + } + + public override async Task ExecuteAsync(CancellationToken ct) + { + var baseUrl = "https://www.taxbaik.com/taxbaik"; + var urls = new List + { + // 정적 페이지 + $"{baseUrl}", + $"{baseUrl}/about", + $"{baseUrl}/services", + $"{baseUrl}/contact", + $"{baseUrl}/privacy", + $"{baseUrl}/terms", + $"{baseUrl}/blog", + $"{baseUrl}/faq", + $"{baseUrl}/announcement", + $"{baseUrl}/inquiry" + }; + + // 동적 블로그 포스트 + var (posts, _) = await _blogService.GetPublishedPagedAsync(1, 1000, categoryId: null, ct: ct); + foreach (var post in posts) + { + urls.Add($"{baseUrl}/blog/{post.Slug}"); + } + + // XML 생성 + var now = DateTime.UtcNow.ToString("yyyy-MM-dd"); + var urlEntries = string.Join("\n", urls.Select(url => + $" \n {System.Net.WebUtility.HtmlEncode(url)}\n {now}\n ")); + + var xml = $"\n\n{urlEntries}\n"; + + // XML Content-Type 설정 + HttpContext.Response.ContentType = "application/xml; charset=utf-8"; + return xml; + } +} diff --git a/src/TaxBaik.Web/Pages/Sitemap.cshtml b/src/TaxBaik.Web/Pages/Sitemap.cshtml deleted file mode 100644 index b81e645..0000000 --- a/src/TaxBaik.Web/Pages/Sitemap.cshtml +++ /dev/null @@ -1,14 +0,0 @@ -@page "/sitemap.xml" -@model TaxBaik.Web.Pages.SitemapModel -@{ - Response.ContentType = "application/xml"; -} - - @foreach (var url in Model.Urls) - { - - @url - @DateTime.UtcNow:yyyy-MM-dd - - } - diff --git a/src/TaxBaik.Web/Pages/Sitemap.cshtml.cs b/src/TaxBaik.Web/Pages/Sitemap.cshtml.cs deleted file mode 100644 index 9884664..0000000 --- a/src/TaxBaik.Web/Pages/Sitemap.cshtml.cs +++ /dev/null @@ -1,49 +0,0 @@ -using Microsoft.AspNetCore.Mvc.RazorPages; -using TaxBaik.Application.Services; - -namespace TaxBaik.Web.Pages; - -public class SitemapModel : PageModel -{ - private readonly BlogService _blogService; - public List Urls { get; set; } = []; - - public SitemapModel(BlogService blogService) - { - _blogService = blogService; - } - - public async Task OnGetAsync() - { - // 프로덕션 도메인 기본값 (배포 환경에서 자동 감지 가능) - var baseUrl = $"{Request.Scheme}://{Request.Host.Value}/taxbaik"; - - // 정적 페이지 (공개 콘텐츠만) - Urls.AddRange(new[] - { - // 홈페이지 - $"{baseUrl}", - $"{baseUrl}/about", - $"{baseUrl}/services", - $"{baseUrl}/contact", - $"{baseUrl}/privacy", - $"{baseUrl}/terms", - - // 공개 콘텐츠 - $"{baseUrl}/blog", - $"{baseUrl}/faq", - $"{baseUrl}/announcement", - $"{baseUrl}/inquiry" - - // 제외: /admin (관리자), /portal (고객 포탈) - // robots.txt에서도 disallow - }); - - // 동적 페이지: 블로그 포스트 - var (posts, _) = await _blogService.GetPublishedPagedAsync(1, 1000); - foreach (var post in posts) - { - Urls.Add($"{baseUrl}/blog/{post.Slug}"); - } - } -}