Files
nexus/backend/Controllers/NotificationsController.cs
AzuTear f5552218bc
CI - Build & Test / Backend (.NET) (push) Successful in 42s
CI - Build & Test / Frontend (Vue/TS) (push) Successful in 2m46s
CI - Build & Test / Security Check (push) Successful in 3s
CI - Build & Test / Deploy Nexus (push) Successful in 56s
feat: ship agent-first mission control v0.2.57
2026-07-31 22:39:47 +02:00

97 lines
3.6 KiB
C#

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Nexus.Api.Data;
using Nexus.Api.Models;
using Nexus.Api.Services;
namespace Nexus.Api.Controllers;
[Authorize]
[ApiController]
[Route("api/dashboard/notifications")]
public class NotificationsController(INotificationService notificationService) : ControllerBase
{
[HttpGet]
public async Task<ActionResult<List<NotificationDto>>> GetNotifications(
[FromQuery] string forUser = "bao",
[FromQuery] int limit = 50,
[FromQuery] bool unreadOnly = false,
CancellationToken ct = default)
{
var notifications = await notificationService.GetForUserAsync(forUser, limit, unreadOnly, ct);
return Ok(notifications.Select(notification => MapToDto(notification)).ToList());
}
[HttpGet("unread-count")]
public async Task<ActionResult<UnreadCountDto>> GetUnreadCount(
[FromQuery] string forUser = "bao",
CancellationToken ct = default)
{
var count = await notificationService.GetUnreadCountAsync(forUser, ct);
return Ok(new UnreadCountDto(count));
}
[HttpGet("snapshot")]
public async Task<ActionResult<NotificationSnapshotDto>> GetSnapshot(
[FromQuery] string forUser = "bao",
[FromQuery] int limit = 50,
[FromQuery] bool unreadOnly = false,
CancellationToken ct = default)
{
return Ok(await notificationService.GetSnapshotAsync(forUser, limit, unreadOnly, ct));
}
[HttpPatch("{id:guid}/read")]
[ProducesResponseType(typeof(NotificationDto), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<ActionResult<NotificationDto>> MarkAsRead(
Guid id,
CancellationToken ct = default)
{
var readResult = await notificationService.MarkAsReadAsync(id, ct);
var notification = readResult.Notification;
if (notification is null)
return NotFound(new ProblemDetails
{
Title = "Notification not found",
Detail = $"Notification '{id}' does not exist.",
Status = StatusCodes.Status404NotFound
});
var primary = new EntityRefDto(
"notification",
notification.Id.ToString(),
notification.Title);
var affected = notification.TaskId is { } taskId
? new[] { new EntityRefDto("task", taskId.ToString()) }
: [];
var operation = OperationResultFactory.FromHttpContext(
HttpContext,
readResult.Changed ? "completed" : "noop",
primary,
revision: readResult.Changed ? 1 : 0,
affectedRefs: affected);
return Ok(MapToDto(notification, operation));
}
[HttpPatch("read-all")]
[ProducesResponseType(typeof(NotificationReadAllResultDto), StatusCodes.Status200OK)]
public async Task<ActionResult<NotificationReadAllResultDto>> MarkAllAsRead(
[FromQuery] string forUser = "bao",
CancellationToken ct = default)
{
var count = await notificationService.MarkAllAsReadAsync(forUser, ct);
var operation = OperationResultFactory.FromHttpContext(
HttpContext,
count > 0 ? "completed" : "noop",
new EntityRefDto("notification", "*", "Benachrichtigungen"));
return Ok(new NotificationReadAllResultDto(count, operation));
}
private static NotificationDto MapToDto(
Notification n,
OperationResultDto? operation = null) => new(
n.Id, n.Type, n.Title, n.Message,
n.ForUser, n.TaskId, n.IsRead, n.CreatedAt, operation);
}