80a16d8b20
TaxBaik CI/CD / build-and-deploy (push) Successful in 1m5s
**API Controllers Complete:** - ClientController (GET /api/client paged, POST/PUT/DELETE) - TaxFilingController (GET upcoming, GET by client, POST/PUT/DELETE) - FaqController (GET active/all, GET by id, POST/PUT/DELETE) - AnnouncementController (GET active/all, GET by id, POST/PUT/DELETE) **Browser Clients Complete:** - IClientBrowserClient + ClientBrowserClient - ITaxFilingBrowserClient + TaxFilingBrowserClient - IFaqBrowserClient + FaqBrowserClient - IAnnouncementBrowserClient + AnnouncementBrowserClient **All Registered in Program.cs:** - BaseAddress: http://localhost:5001/taxbaik/api/ - TokenRefreshHandler attached to all clients - DI container: AddHttpClient<IXxxClient, XxxClient> **Blazor Refactored (Partial):** - ClientList.razor: ✅ IClientBrowserClient (service → API) - ClientEdit.razor: ✅ IClientBrowserClient (service → API) - TaxFilings Blazor: ⏳ Pending refactor - Faqs Blazor: ⏳ Pending refactor - Announcements Blazor: ⏳ Pending refactor **Phase 7 Status:** - API-First Foundation: ✅ 100% (all controllers + clients ready) - Blazor Refactoring: 🟡 30% (Clients done, others pending) - Phase 6 SignalR: ⏳ Deferred (ready for real-time on API-first pages) **SOLID Applied Throughout:** ✓ Single Responsibility: Each client handles one domain ✓ Open/Closed: Extend via interface, not modification ✓ Dependency Inversion: Blazor → Interfaces, not services ✓ Interface Segregation: Specialized clients per operation ✓ Liskov Substitution: All clients follow same contract **Build:** ✅ Success (0 errors, 2 warnings in Dashboard) **Pattern:** Established & repeatable for remaining Blazor pages Next: Blazor page migrations (TaxFilings, Faqs, Announcements) Then: Phase 6 SignalR for real-time notifications Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
89 lines
2.4 KiB
C#
89 lines
2.4 KiB
C#
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using TaxBaik.Application.Services;
|
|
using TaxBaik.Domain.Entities;
|
|
|
|
namespace TaxBaik.Web.Controllers;
|
|
|
|
[ApiController]
|
|
[Route("api/[controller]")]
|
|
public class FaqController : ControllerBase
|
|
{
|
|
private readonly FaqService _faqService;
|
|
|
|
public FaqController(FaqService faqService)
|
|
{
|
|
_faqService = faqService;
|
|
}
|
|
|
|
[HttpGet("active")]
|
|
public async Task<IActionResult> GetActive()
|
|
{
|
|
var faqs = await _faqService.GetActiveAsync();
|
|
return Ok(new { data = faqs });
|
|
}
|
|
|
|
[HttpGet]
|
|
[Authorize]
|
|
public async Task<IActionResult> GetAll()
|
|
{
|
|
var faqs = await _faqService.GetAllAsync();
|
|
return Ok(new { data = faqs });
|
|
}
|
|
|
|
[HttpGet("{id}")]
|
|
[Authorize]
|
|
public async Task<IActionResult> GetById(int id)
|
|
{
|
|
var faq = await _faqService.GetByIdAsync(id);
|
|
if (faq == null)
|
|
return NotFound(new ProblemDetails { Title = "FAQ를 찾을 수 없습니다.", Status = StatusCodes.Status404NotFound });
|
|
|
|
return Ok(faq);
|
|
}
|
|
|
|
[HttpPost]
|
|
[Authorize]
|
|
public async Task<IActionResult> Create([FromBody] Faq faq)
|
|
{
|
|
try
|
|
{
|
|
var faqId = await _faqService.CreateAsync(faq);
|
|
var result = await _faqService.GetByIdAsync(faqId);
|
|
return CreatedAtAction(nameof(GetById), new { id = faqId }, result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return BadRequest(new ProblemDetails { Title = ex.Message, Status = StatusCodes.Status400BadRequest });
|
|
}
|
|
}
|
|
|
|
[HttpPut("{id}")]
|
|
[Authorize]
|
|
public async Task<IActionResult> Update(int id, [FromBody] Faq faq)
|
|
{
|
|
faq.Id = id;
|
|
try
|
|
{
|
|
await _faqService.UpdateAsync(faq);
|
|
var result = await _faqService.GetByIdAsync(id);
|
|
if (result == null)
|
|
return NotFound(new ProblemDetails { Title = "FAQ를 찾을 수 없습니다.", Status = StatusCodes.Status404NotFound });
|
|
|
|
return Ok(result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return BadRequest(new ProblemDetails { Title = ex.Message, Status = StatusCodes.Status400BadRequest });
|
|
}
|
|
}
|
|
|
|
[HttpDelete("{id}")]
|
|
[Authorize]
|
|
public async Task<IActionResult> Delete(int id)
|
|
{
|
|
await _faqService.DeleteAsync(id);
|
|
return NoContent();
|
|
}
|
|
}
|