feat: implement API-first architecture Phase 1 - Dashboard API
**Architecture Refactor (SOLID Principles):** - Implement AdminDashboardController (REST API) - Add dashboard summary endpoint - Add upcoming filings endpoint - Add recent inquiries endpoint - Add monthly statistics endpoint **Database Layer (Repository Pattern):** - Extend IInquiryRepository with date range queries - Implement CountByDateRangeAsync - Implement CountByStatusAndDateAsync - Extend InquiryRepository with new methods **Service Layer (Single Responsibility):** - Extend AdminDashboardService with API methods - Add GetRecentInquiriesAsync - Add GetMonthlyStatsAsync with caching **Test Coverage:** - Update FakeInquiryRepository mock with new methods **SOLID Application:** ✓ Single Responsibility: Each class has one reason to change ✓ Open/Closed: Dashboard API can be extended without modifying existing code ✓ Dependency Inversion: Service depends on Repository abstraction ✓ Interface Segregation: API endpoints are focused and specific Status: ✓ Compiles successfully (0 errors, 0 warnings) Next phases: - Add remaining API controllers (Announcement, Client, FAQ, TaxFiling) - Refactor Blazor components to use API instead of services - Implement JWT token refresh mechanism - Add SignalR for change notifications Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -74,6 +74,28 @@ public class InquiryRepository(IDbConnectionFactory connectionFactory) : BaseRep
|
||||
new { Status = status });
|
||||
}
|
||||
|
||||
public async Task<int> CountByDateRangeAsync(DateTime startDate, DateTime endDate, CancellationToken cancellationToken = default)
|
||||
{
|
||||
using var conn = Conn();
|
||||
return await conn.ExecuteScalarAsync<int>(
|
||||
@"SELECT COUNT(*)
|
||||
FROM inquiries
|
||||
WHERE created_at >= @StartDate AND created_at <= @EndDate",
|
||||
new { StartDate = startDate, EndDate = endDate });
|
||||
}
|
||||
|
||||
public async Task<int> CountByStatusAndDateAsync(string status, DateTime startDate, DateTime endDate, CancellationToken cancellationToken = default)
|
||||
{
|
||||
using var conn = Conn();
|
||||
return await conn.ExecuteScalarAsync<int>(
|
||||
@"SELECT COUNT(*)
|
||||
FROM inquiries
|
||||
WHERE status = @Status
|
||||
AND created_at >= @StartDate
|
||||
AND created_at <= @EndDate",
|
||||
new { Status = status, StartDate = startDate, EndDate = endDate });
|
||||
}
|
||||
|
||||
public async Task UpdateStatusAsync(int id, string status, CancellationToken cancellationToken = default)
|
||||
{
|
||||
using var conn = Conn();
|
||||
|
||||
Reference in New Issue
Block a user