From 0986233d9b147e93043d5823a19dfcc403f28f1a Mon Sep 17 00:00:00 2001 From: Chris Chen Date: Wed, 27 May 2026 14:03:23 -0700 Subject: [PATCH] feat: add MembersController (CRUD + paged list) Co-Authored-By: Claude Sonnet 4.6 --- .../Controllers/MembersController.cs | 62 +++++++++++++++++++ API/ROLAC.API/Program.cs | 5 +- 2 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 API/ROLAC.API/Controllers/MembersController.cs diff --git a/API/ROLAC.API/Controllers/MembersController.cs b/API/ROLAC.API/Controllers/MembersController.cs new file mode 100644 index 0000000..5288c32 --- /dev/null +++ b/API/ROLAC.API/Controllers/MembersController.cs @@ -0,0 +1,62 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using ROLAC.API.DTOs.Members; +using ROLAC.API.Services; + +namespace ROLAC.API.Controllers; + +[ApiController] +[Route("api/members")] +[Authorize] +public class MembersController : ControllerBase +{ + private readonly IMemberService _members; + public MembersController(IMemberService members) => _members = members; + + /// GET /api/members?page=1&pageSize=20&search=Chen&status=Member&hasUser=false + [HttpGet] + [Authorize(Roles = "super_admin,secretary,pastor")] + public async Task GetPaged( + [FromQuery] int page = 1, + [FromQuery] int pageSize = 20, + [FromQuery] string? search = null, + [FromQuery] string? status = null, + [FromQuery] bool? hasUser = null) + => Ok(await _members.GetPagedAsync(page, pageSize, search, status, hasUser)); + + /// GET /api/members/{id} + [HttpGet("{id:int}")] + [Authorize(Roles = "super_admin,secretary,pastor")] + public async Task GetById(int id) + { + var dto = await _members.GetByIdAsync(id); + return dto is null ? NotFound() : Ok(dto); + } + + /// POST /api/members + [HttpPost] + [Authorize(Roles = "super_admin,secretary")] + public async Task Create([FromBody] CreateMemberRequest request) + { + var id = await _members.CreateAsync(request); + return CreatedAtAction(nameof(GetById), new { id }, new { id }); + } + + /// PUT /api/members/{id} + [HttpPut("{id:int}")] + [Authorize(Roles = "super_admin,secretary")] + public async Task Update(int id, [FromBody] UpdateMemberRequest request) + { + try { await _members.UpdateAsync(id, request); return NoContent(); } + catch (KeyNotFoundException) { return NotFound(); } + } + + /// DELETE /api/members/{id} — soft delete + [HttpDelete("{id:int}")] + [Authorize(Roles = "super_admin,secretary")] + public async Task Delete(int id) + { + try { await _members.DeleteAsync(id); return NoContent(); } + catch (KeyNotFoundException) { return NotFound(); } + } +} diff --git a/API/ROLAC.API/Program.cs b/API/ROLAC.API/Program.cs index 019b708..3272ca5 100644 --- a/API/ROLAC.API/Program.cs +++ b/API/ROLAC.API/Program.cs @@ -82,8 +82,9 @@ builder.Services.AddCors(opt => // --------------------------------------------------------------------------- // Application services // --------------------------------------------------------------------------- -builder.Services.AddScoped(); -builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); // --------------------------------------------------------------------------- // Swagger / MVC