개선: 배포 검증과 관리자 UX 안정화
TaxBaik Browser E2E / browser-e2e (push) Failing after 1m3s
TaxBaik CI/CD / build-and-deploy (push) Failing after 2m46s

This commit is contained in:
2026-06-27 20:57:09 +09:00
parent 64b08831e8
commit f29f2c3cff
51 changed files with 948 additions and 199 deletions
@@ -14,6 +14,7 @@ public static class DependencyInjection
services.AddScoped<ICategoryRepository, CategoryRepository>();
services.AddScoped<IBlogPostRepository, BlogPostRepository>();
services.AddScoped<IInquiryRepository, InquiryRepository>();
services.AddScoped<ISiteSettingRepository, SiteSettingRepository>();
return services;
}
@@ -70,6 +70,30 @@ public class BlogPostRepository(IDbConnectionFactory connectionFactory) : BaseRe
ORDER BY bp.created_at DESC");
}
public async Task<(IEnumerable<BlogPost> Items, int Total)> GetAdminPagedAsync(
int page, int pageSize, CancellationToken cancellationToken = default)
{
using var conn = Conn();
var offset = (page - 1) * pageSize;
using var reader = await conn.QueryMultipleAsync(
@"SELECT bp.id, bp.title, bp.content, bp.slug, bp.category_id, bp.tags, bp.author_id,
bp.published_at, bp.view_count, bp.seo_title, bp.seo_description, bp.thumbnail_url,
bp.is_published, bp.created_at, bp.updated_at, c.name AS category_name
FROM blog_posts bp
LEFT JOIN categories c ON bp.category_id = c.id
ORDER BY bp.created_at DESC
LIMIT @PageSize OFFSET @Offset;
SELECT COUNT(*) FROM blog_posts;",
new { PageSize = pageSize, Offset = offset });
var items = (await reader.ReadAsync<BlogPost>()).ToList();
var total = await reader.ReadFirstAsync<int>();
return (items, total);
}
public async Task<int> CreateAsync(BlogPost post, CancellationToken cancellationToken = default)
{
using var conn = Conn();
@@ -47,6 +47,30 @@ public class InquiryRepository(IDbConnectionFactory connectionFactory) : BaseRep
return (items, total);
}
public async Task<int> CountAsync(CancellationToken cancellationToken = default)
{
using var conn = Conn();
return await conn.ExecuteScalarAsync<int>("SELECT COUNT(*) FROM inquiries");
}
public async Task<int> CountThisMonthAsync(CancellationToken cancellationToken = default)
{
using var conn = Conn();
return await conn.ExecuteScalarAsync<int>(
@"SELECT COUNT(*)
FROM inquiries
WHERE created_at >= date_trunc('month', NOW())
AND created_at < date_trunc('month', NOW()) + INTERVAL '1 month'");
}
public async Task<int> CountByStatusAsync(string status, CancellationToken cancellationToken = default)
{
using var conn = Conn();
return await conn.ExecuteScalarAsync<int>(
"SELECT COUNT(*) FROM inquiries WHERE status = @Status",
new { Status = status });
}
public async Task UpdateStatusAsync(int id, string status, CancellationToken cancellationToken = default)
{
using var conn = Conn();
@@ -0,0 +1,30 @@
using Dapper;
using TaxBaik.Domain.Entities;
using TaxBaik.Domain.Interfaces;
namespace TaxBaik.Infrastructure.Repositories;
public class SiteSettingRepository(IDbConnectionFactory connectionFactory) : BaseRepository(connectionFactory), ISiteSettingRepository
{
public async Task<IReadOnlyDictionary<string, string>> GetAllAsync(CancellationToken cancellationToken = default)
{
using var conn = Conn();
var rows = await conn.QueryAsync<SiteSetting>(
"SELECT key, value, updated_at AS UpdatedAt FROM site_settings ORDER BY key");
return rows.ToDictionary(x => x.Key, x => x.Value);
}
public async Task UpsertAsync(IEnumerable<SiteSetting> settings, CancellationToken cancellationToken = default)
{
using var conn = Conn();
foreach (var setting in settings)
{
await conn.ExecuteAsync(
@"INSERT INTO site_settings (key, value, updated_at)
VALUES (@Key, @Value, NOW())
ON CONFLICT (key)
DO UPDATE SET value = EXCLUDED.value, updated_at = NOW()",
setting);
}
}
}