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> 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>> GetMembers() { var ctx = User.GetRequestContext(); var members = await _orgMemberRepository.GetByOrgIdAsync(ctx.OrgId); var result = new List(); 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>> 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> 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>> 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> CreateNotificationTarget([FromBody] CreateNotificationTargetRequest request) { var ctx = User.GetRequestContext(); if (!Enum.TryParse(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 )); } }