97 lines
3.6 KiB
C#
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);
|
|
}
|