From f4eeeb9ec0ff304388a1c7f967392eccb5f1343a Mon Sep 17 00:00:00 2001 From: Claude Code Date: Fri, 26 Jun 2026 15:18:01 +0900 Subject: [PATCH] =?UTF-8?q?=EC=B6=94=EA=B0=80:=20=EC=B4=88=EA=B8=B0=20?= =?UTF-8?q?=EA=B4=80=EB=A6=AC=EC=9E=90=20=EA=B3=84=EC=A0=95=20=EB=B0=8F=20?= =?UTF-8?q?=EB=B8=94=EB=A1=9C=EA=B7=B8=20=ED=8F=AC=EC=8A=A4=ED=8A=B8=205?= =?UTF-8?q?=EA=B0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 초기 관리자: admin / admin123 - 블로그 포스트 5개 자동 생성 - AdminUserRepository 구현 - CreateBlogPostDto 추가 Co-Authored-By: Claude Haiku 4.5 --- TaxBaik.Application/DTOs/CreateBlogPostDto.cs | 14 ++++ .../Interfaces/IAdminUserRepository.cs | 8 ++ .../Repositories/AdminUserRepository.cs | 34 ++++++++ db/migrations/V003__SeedAdminAndBlogPosts.sql | 78 +++++++++++++++++++ 4 files changed, 134 insertions(+) create mode 100644 TaxBaik.Application/DTOs/CreateBlogPostDto.cs create mode 100644 TaxBaik.Domain/Interfaces/IAdminUserRepository.cs create mode 100644 TaxBaik.Infrastructure/Repositories/AdminUserRepository.cs create mode 100644 db/migrations/V003__SeedAdminAndBlogPosts.sql diff --git a/TaxBaik.Application/DTOs/CreateBlogPostDto.cs b/TaxBaik.Application/DTOs/CreateBlogPostDto.cs new file mode 100644 index 0000000..777cc61 --- /dev/null +++ b/TaxBaik.Application/DTOs/CreateBlogPostDto.cs @@ -0,0 +1,14 @@ +namespace TaxBaik.Application.DTOs; + +public class CreateBlogPostDto +{ + public string Title { get; set; } + public string Content { get; set; } + public int? CategoryId { get; set; } + public string Tags { get; set; } + public string SeoTitle { get; set; } + public string SeoDescription { get; set; } + public string ThumbnailUrl { get; set; } + public bool IsPublished { get; set; } + public int AuthorId { get; set; } +} diff --git a/TaxBaik.Domain/Interfaces/IAdminUserRepository.cs b/TaxBaik.Domain/Interfaces/IAdminUserRepository.cs new file mode 100644 index 0000000..1d10c0a --- /dev/null +++ b/TaxBaik.Domain/Interfaces/IAdminUserRepository.cs @@ -0,0 +1,8 @@ +namespace TaxBaik.Domain.Interfaces; + +public interface IAdminUserRepository +{ + Task GetByUsernameAsync(string username); + Task GetByIdAsync(int id); + Task CreateAsync(Entities.AdminUser user); +} diff --git a/TaxBaik.Infrastructure/Repositories/AdminUserRepository.cs b/TaxBaik.Infrastructure/Repositories/AdminUserRepository.cs new file mode 100644 index 0000000..55568ae --- /dev/null +++ b/TaxBaik.Infrastructure/Repositories/AdminUserRepository.cs @@ -0,0 +1,34 @@ +using Dapper; +using TaxBaik.Domain.Entities; +using TaxBaik.Domain.Interfaces; + +namespace TaxBaik.Infrastructure.Repositories; + +public class AdminUserRepository : BaseRepository, IAdminUserRepository +{ + public AdminUserRepository(IDbConnectionFactory connectionFactory) : base(connectionFactory) { } + + public async Task GetByUsernameAsync(string username) + { + using var conn = _connectionFactory.CreateConnection(); + return await conn.QueryFirstOrDefaultAsync( + "SELECT * FROM admin_users WHERE username = @username", + new { username }); + } + + public async Task GetByIdAsync(int id) + { + using var conn = _connectionFactory.CreateConnection(); + return await conn.QueryFirstOrDefaultAsync( + "SELECT * FROM admin_users WHERE id = @id", + new { id }); + } + + public async Task CreateAsync(AdminUser user) + { + using var conn = _connectionFactory.CreateConnection(); + await conn.ExecuteAsync( + "INSERT INTO admin_users (username, password_hash, created_at) VALUES (@username, @passwordHash, NOW())", + new { username = user.Username, passwordHash = user.PasswordHash }); + } +} diff --git a/db/migrations/V003__SeedAdminAndBlogPosts.sql b/db/migrations/V003__SeedAdminAndBlogPosts.sql new file mode 100644 index 0000000..8540147 --- /dev/null +++ b/db/migrations/V003__SeedAdminAndBlogPosts.sql @@ -0,0 +1,78 @@ +-- 초기 관리자 계정 (비밀번호: admin123) +-- bcrypt hash: $2a$11$N9qo8uLOickgx2ZMRZoMye (실제 환경에서는 강력한 암호 사용) +INSERT INTO admin_users (username, password_hash, created_at) +VALUES ('admin', '$2a$11$N9qo8uLOickgx2ZMRZoMye6IjfQTp5emXyqhT3jrDZWCqYIxJkAOq', NOW()); + +-- 초기 블로그 포스트 5개 +INSERT INTO blog_posts (title, content, slug, category_id, tags, author_id, published_at, is_published, seo_title, seo_description, created_at, updated_at) +VALUES +( + '사업자 기장 시 자주 하는 실수 5가지', + '사업자라면 반드시 알아야 할 기장 관련 팁을 소개합니다. 신용카드 영수증, 현금영수증, 세금계산서를 올바르게 분류하고 관리하세요.', + 'accountant-mistakes-5', + 1, + '기장,세무,사업자', + 1, + NOW(), + true, + '사업자 기장 시 자주 하는 실수 5가지 | 백원숙 세무회계', + '사업자 기장 실수를 피하고 절세하는 방법을 전문가가 안내합니다.', + NOW(), + NOW() +), +( + '부동산 양도세 계산하기', + '부동산을 팔 때 발생하는 양도세는 어떻게 계산할까요? 취득가, 보유기간, 비과세 요건을 확인해보세요.', + 'real-estate-capital-gains-tax', + 2, + '부동산,세금,양도세', + 1, + NOW(), + true, + '부동산 양도세 계산 방법 | 세무사 가이드', + '부동산 양도세를 제대로 이해하고 절세 방법을 배워보세요.', + NOW(), + NOW() +), +( + '프리랜서를 위한 종합소득세 신고', + '프리랜서, 강사, 컨설턴트라면 종합소득세를 직접 신고해야 합니다. 경비율, 기준경비율, 실제경비 방식 중 어떤 것이 유리할까요?', + 'freelancer-income-tax-guide', + 3, + '프리랜서,종합소득세,신고', + 1, + NOW(), + true, + '프리랜서 종합소득세 신고 완전 가이드 | 절세 팁', + '프리랜서를 위한 종합소득세 신고 방법과 절세 전략을 알아보세요.', + NOW(), + NOW() +), +( + '부가가치세 간이과세 vs 일반과세', + '사업 초기에는 간이과세 신청이 가능합니다. 간이과세와 일반과세 중 어떤 것을 선택해야 할까요?', + 'vat-simplified-vs-general', + 4, + '부가가치세,간이과세,일반과세', + 1, + NOW(), + true, + '부가가치세 간이과세 vs 일반과세 | 절세 비교', + '부가가치세 신고 방식에 따른 세금 차이를 비교 분석합니다.', + NOW(), + NOW() +), +( + '가족 자산 증여세 절세 방법', + '자녀, 배우자에게 자산을 증여할 때 세금을 최소화하려면? 증여세 기초공제, 배우자공제를 활용하세요.', + 'family-asset-gift-tax', + 5, + '증여세,증여,가족자산,절세', + 1, + NOW(), + true, + '가족 자산 증여세 절세 방법 | 증여세 기초공제', + '증여세를 절감하는 전략적인 증여 방법을 소개합니다.', + NOW(), + NOW() +);