feat(api): add organization management endpoints
This commit is contained in:
151
src/IncidentOps.Api/Controllers/OrgController.cs
Normal file
151
src/IncidentOps.Api/Controllers/OrgController.cs
Normal file
@@ -0,0 +1,151 @@
|
||||
using IncidentOps.Api.Auth;
|
||||
using IncidentOps.Contracts.Orgs;
|
||||
using IncidentOps.Contracts.Services;
|
||||
using IncidentOps.Domain.Entities;
|
||||
using IncidentOps.Domain.Enums;
|
||||
using IncidentOps.Infrastructure.Data.Repositories;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace IncidentOps.Api.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("v1/org")]
|
||||
[Authorize]
|
||||
public class OrgController : ControllerBase
|
||||
{
|
||||
private readonly IOrgRepository _orgRepository;
|
||||
private readonly IOrgMemberRepository _orgMemberRepository;
|
||||
private readonly IUserRepository _userRepository;
|
||||
private readonly IServiceRepository _serviceRepository;
|
||||
private readonly INotificationTargetRepository _notificationTargetRepository;
|
||||
|
||||
public OrgController(
|
||||
IOrgRepository orgRepository,
|
||||
IOrgMemberRepository orgMemberRepository,
|
||||
IUserRepository userRepository,
|
||||
IServiceRepository serviceRepository,
|
||||
INotificationTargetRepository notificationTargetRepository)
|
||||
{
|
||||
_orgRepository = orgRepository;
|
||||
_orgMemberRepository = orgMemberRepository;
|
||||
_userRepository = userRepository;
|
||||
_serviceRepository = serviceRepository;
|
||||
_notificationTargetRepository = notificationTargetRepository;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<ActionResult<OrgDto>> GetCurrentOrg()
|
||||
{
|
||||
var ctx = User.GetRequestContext();
|
||||
var org = await _orgRepository.GetByIdAsync(ctx.OrgId);
|
||||
if (org == null)
|
||||
return NotFound();
|
||||
|
||||
return new OrgDto(org.Id, org.Name, org.Slug, ctx.Role.ToString().ToLowerInvariant());
|
||||
}
|
||||
|
||||
[HttpGet("members")]
|
||||
[Authorize(Policy = "Admin")]
|
||||
public async Task<ActionResult<IReadOnlyList<OrgMemberDto>>> GetMembers()
|
||||
{
|
||||
var ctx = User.GetRequestContext();
|
||||
var members = await _orgMemberRepository.GetByOrgIdAsync(ctx.OrgId);
|
||||
|
||||
var result = new List<OrgMemberDto>();
|
||||
foreach (var member in members)
|
||||
{
|
||||
var user = await _userRepository.GetByIdAsync(member.UserId);
|
||||
if (user != null)
|
||||
{
|
||||
result.Add(new OrgMemberDto(
|
||||
member.Id,
|
||||
user.Id,
|
||||
user.Email,
|
||||
user.DisplayName,
|
||||
member.Role.ToString().ToLowerInvariant(),
|
||||
member.CreatedAt
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
[HttpGet("services")]
|
||||
public async Task<ActionResult<IReadOnlyList<ServiceDto>>> GetServices()
|
||||
{
|
||||
var ctx = User.GetRequestContext();
|
||||
var services = await _serviceRepository.GetByOrgIdAsync(ctx.OrgId);
|
||||
|
||||
return services.Select(s => new ServiceDto(s.Id, s.Name, s.Slug, s.Description, s.CreatedAt)).ToList();
|
||||
}
|
||||
|
||||
[HttpPost("services")]
|
||||
[Authorize(Policy = "Member")]
|
||||
public async Task<ActionResult<ServiceDto>> CreateService([FromBody] CreateServiceRequest request)
|
||||
{
|
||||
var ctx = User.GetRequestContext();
|
||||
|
||||
var service = new Service
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
OrgId = ctx.OrgId,
|
||||
Name = request.Name,
|
||||
Slug = request.Slug,
|
||||
Description = request.Description,
|
||||
CreatedAt = DateTime.UtcNow
|
||||
};
|
||||
await _serviceRepository.CreateAsync(service);
|
||||
|
||||
return CreatedAtAction(nameof(GetServices), new ServiceDto(service.Id, service.Name, service.Slug, service.Description, service.CreatedAt));
|
||||
}
|
||||
|
||||
[HttpGet("notification-targets")]
|
||||
[Authorize(Policy = "Admin")]
|
||||
public async Task<ActionResult<IReadOnlyList<NotificationTargetDto>>> GetNotificationTargets()
|
||||
{
|
||||
var ctx = User.GetRequestContext();
|
||||
var targets = await _notificationTargetRepository.GetByOrgIdAsync(ctx.OrgId);
|
||||
|
||||
return targets.Select(t => new NotificationTargetDto(
|
||||
t.Id,
|
||||
t.Name,
|
||||
t.TargetType.ToString().ToLowerInvariant(),
|
||||
t.Configuration,
|
||||
t.IsEnabled,
|
||||
t.CreatedAt
|
||||
)).ToList();
|
||||
}
|
||||
|
||||
[HttpPost("notification-targets")]
|
||||
[Authorize(Policy = "Admin")]
|
||||
public async Task<ActionResult<NotificationTargetDto>> CreateNotificationTarget([FromBody] CreateNotificationTargetRequest request)
|
||||
{
|
||||
var ctx = User.GetRequestContext();
|
||||
|
||||
if (!Enum.TryParse<NotificationTargetType>(request.TargetType, ignoreCase: true, out var targetType))
|
||||
return BadRequest(new { message = "Invalid target type" });
|
||||
|
||||
var target = new NotificationTarget
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
OrgId = ctx.OrgId,
|
||||
Name = request.Name,
|
||||
TargetType = targetType,
|
||||
Configuration = request.Configuration,
|
||||
IsEnabled = request.IsEnabled,
|
||||
CreatedAt = DateTime.UtcNow
|
||||
};
|
||||
await _notificationTargetRepository.CreateAsync(target);
|
||||
|
||||
return CreatedAtAction(nameof(GetNotificationTargets), new NotificationTargetDto(
|
||||
target.Id,
|
||||
target.Name,
|
||||
target.TargetType.ToString().ToLowerInvariant(),
|
||||
target.Configuration,
|
||||
target.IsEnabled,
|
||||
target.CreatedAt
|
||||
));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user