Add read receipts and editing limits

Introduced message read tracking with a dedicated MessageReadingService, SignalR read request/response contracts, and hub notification flow for read receipts. Added configurable message edit constraints through MessageEditingOptions and a shared INowDateTimeProvider so timestamps are consistent across the app. Also fixed recipient validation in message removal and improved push token upsert behavior by matching the correct user/session record.
This commit is contained in:
Artemy
2026-08-27 18:02:47 +07:00
parent 3ec61fa2c0
commit 4603be9f71
17 changed files with 262 additions and 30 deletions
@@ -1,3 +1,4 @@
using Govor.Application.Infrastructure.Common;
using Govor.Domain;
using Govor.Domain.Common;
using Govor.Domain.Models.Users;
@@ -11,9 +12,13 @@ public class PushTokenService : IPushTokenService
{
private readonly GovorDbContext _context;
private readonly ILogger<PushTokenService> _logger;
private readonly INowDateTimeProvider _nowDateTimeProvider;
public PushTokenService(GovorDbContext context, ILogger<PushTokenService> logger)
public PushTokenService(GovorDbContext context,
INowDateTimeProvider nowDateTimeProvider,
ILogger<PushTokenService> logger)
{
_nowDateTimeProvider = nowDateTimeProvider;
_context = context;
_logger = logger;
}
@@ -139,7 +144,7 @@ public class PushTokenService : IPushTokenService
}
var existingToken = await _context.UserPushTokens
.FirstOrDefaultAsync(t => t.Token == token);
.FirstOrDefaultAsync(t => t.Platform == platform && t.UserId == userId && t.UserSessionId == sessionId);
if (existingToken is null)
{
@@ -150,18 +155,18 @@ public class PushTokenService : IPushTokenService
UserSessionId = sessionId,
Token = token,
Platform = platform,
CreatedAt = DateTime.UtcNow
CreatedAt = _nowDateTimeProvider.Now
};
await _context.UserPushTokens.AddAsync(newToken);
}
else
{
existingToken.UserId = userId;
existingToken.UserSessionId = sessionId;
existingToken.Platform = platform;
existingToken.UpdatedAt = DateTime.UtcNow;
existingToken.Token = token;
existingToken.UpdatedAt = _nowDateTimeProvider.Now;
}
await _context.SaveChangesAsync();