WIP
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using ROLAC.API.Authorization;
|
||||
using ROLAC.API.DTOs.Ministry;
|
||||
using ROLAC.API.Services;
|
||||
|
||||
namespace ROLAC.API.Controllers;
|
||||
@@ -13,6 +15,31 @@ public class MinistriesController : ControllerBase
|
||||
public MinistriesController(IMinistryService svc) => _svc = svc;
|
||||
|
||||
[HttpGet]
|
||||
[HasPermission(Modules.Ministries, PermissionActions.Read)]
|
||||
public async Task<IActionResult> GetAll([FromQuery] bool includeInactive = false)
|
||||
=> Ok(await _svc.GetAllAsync(includeInactive));
|
||||
|
||||
[HttpPost]
|
||||
[HasPermission(Modules.Ministries, PermissionActions.Write)]
|
||||
public async Task<IActionResult> Create([FromBody] CreateMinistryRequest request)
|
||||
{
|
||||
var id = await _svc.CreateAsync(request);
|
||||
return CreatedAtAction(nameof(GetAll), new { id }, new { id });
|
||||
}
|
||||
|
||||
[HttpPut("{id:int}")]
|
||||
[HasPermission(Modules.Ministries, PermissionActions.Write)]
|
||||
public async Task<IActionResult> Update(int id, [FromBody] UpdateMinistryRequest request)
|
||||
{
|
||||
try { await _svc.UpdateAsync(id, request); return NoContent(); }
|
||||
catch (KeyNotFoundException) { return NotFound(); }
|
||||
}
|
||||
|
||||
[HttpDelete("{id:int}")]
|
||||
[HasPermission(Modules.Ministries, PermissionActions.Delete)]
|
||||
public async Task<IActionResult> Deactivate(int id)
|
||||
{
|
||||
try { await _svc.DeactivateAsync(id); return NoContent(); }
|
||||
catch (KeyNotFoundException) { return NotFound(); }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
namespace ROLAC.API.DTOs.Ministry;
|
||||
|
||||
public class CreateMinistryRequest
|
||||
{
|
||||
[Required, MaxLength(200)] public string Name_en { get; set; } = "";
|
||||
[MaxLength(200)] public string? Name_zh { get; set; }
|
||||
[MaxLength(500)] public string? Description_en { get; set; }
|
||||
[MaxLength(500)] public string? Description_zh { get; set; }
|
||||
public int SortOrder { get; set; }
|
||||
}
|
||||
@@ -5,6 +5,8 @@ public class MinistryDto
|
||||
public int Id { get; set; }
|
||||
public string Name_en { get; set; } = "";
|
||||
public string? Name_zh { get; set; }
|
||||
public string? Description_en { get; set; }
|
||||
public string? Description_zh { get; set; }
|
||||
public int SortOrder { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
namespace ROLAC.API.DTOs.Ministry;
|
||||
|
||||
public class UpdateMinistryRequest
|
||||
{
|
||||
[Required, MaxLength(200)] public string Name_en { get; set; } = "";
|
||||
[MaxLength(200)] public string? Name_zh { get; set; }
|
||||
[MaxLength(500)] public string? Description_en { get; set; }
|
||||
[MaxLength(500)] public string? Description_zh { get; set; }
|
||||
public bool IsActive { get; set; } = true;
|
||||
public int SortOrder { get; set; }
|
||||
}
|
||||
@@ -94,6 +94,22 @@ public static class DbSeeder
|
||||
("pastor", Modules.AuditLogs, true, false, false, false),
|
||||
("finance", Modules.AuditLogs, true, false, false, false),
|
||||
("board_member", Modules.AuditLogs, true, false, false, false),
|
||||
|
||||
// Ministries — secretary maintains the list; coworker_chair edits; ministry
|
||||
// leaders and pastor read.
|
||||
("secretary", Modules.Ministries, true, true, true, false),
|
||||
("coworker_chair", Modules.Ministries, true, true, false, false),
|
||||
("ministry_leader", Modules.Ministries, true, false, false, false),
|
||||
("pastor", Modules.Ministries, true, false, false, false),
|
||||
|
||||
// Meal attendance — secretary and coworkers record; finance and pastor read.
|
||||
("secretary", Modules.MealAttendance, true, true, false, false),
|
||||
("coworker", Modules.MealAttendance, true, true, false, false),
|
||||
("finance", Modules.MealAttendance, true, false, false, false),
|
||||
("pastor", Modules.MealAttendance, true, false, false, false),
|
||||
|
||||
// Users, Permissions, and Settings are intentionally super_admin-only:
|
||||
// super_admin bypasses all checks, so no seed rows are needed here.
|
||||
];
|
||||
|
||||
public static async Task SeedRolePermissionsAsync(AppDbContext db)
|
||||
|
||||
@@ -4,4 +4,7 @@ namespace ROLAC.API.Services;
|
||||
public interface IMinistryService
|
||||
{
|
||||
Task<List<MinistryDto>> GetAllAsync(bool includeInactive);
|
||||
Task<int> CreateAsync(CreateMinistryRequest request);
|
||||
Task UpdateAsync(int id, UpdateMinistryRequest request);
|
||||
Task DeactivateAsync(int id); // soft-disable: IsActive = false
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ROLAC.API.Data;
|
||||
using ROLAC.API.DTOs.Ministry;
|
||||
using ROLAC.API.Entities;
|
||||
|
||||
namespace ROLAC.API.Services;
|
||||
|
||||
@@ -18,8 +19,40 @@ public class MinistryService : IMinistryService
|
||||
.Select(m => new MinistryDto
|
||||
{
|
||||
Id = m.Id, Name_en = m.Name_en, Name_zh = m.Name_zh,
|
||||
Description_en = m.Description_en, Description_zh = m.Description_zh,
|
||||
SortOrder = m.SortOrder, IsActive = m.IsActive,
|
||||
})
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<int> CreateAsync(CreateMinistryRequest r)
|
||||
{
|
||||
var entity = new Ministry
|
||||
{
|
||||
Name_en = r.Name_en, Name_zh = r.Name_zh,
|
||||
Description_en = r.Description_en, Description_zh = r.Description_zh,
|
||||
SortOrder = r.SortOrder, IsActive = true,
|
||||
};
|
||||
_db.Ministries.Add(entity);
|
||||
await _db.SaveChangesAsync();
|
||||
return entity.Id;
|
||||
}
|
||||
|
||||
public async Task UpdateAsync(int id, UpdateMinistryRequest r)
|
||||
{
|
||||
var m = await _db.Ministries.FindAsync(id)
|
||||
?? throw new KeyNotFoundException($"Ministry {id} not found.");
|
||||
m.Name_en = r.Name_en; m.Name_zh = r.Name_zh;
|
||||
m.Description_en = r.Description_en; m.Description_zh = r.Description_zh;
|
||||
m.IsActive = r.IsActive; m.SortOrder = r.SortOrder;
|
||||
await _db.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task DeactivateAsync(int id)
|
||||
{
|
||||
var m = await _db.Ministries.FindAsync(id)
|
||||
?? throw new KeyNotFoundException($"Ministry {id} not found.");
|
||||
m.IsActive = false;
|
||||
await _db.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user