using Hutopy.Modules.Identity.Contracts; using Hutopy.Modules.Messaging.Models; namespace Hutopy.Modules.Messaging.Data; public class MessagingDbContext( IUserLookup userLookup, DbContextOptions options) : DbContext(options) { public const string SchemaName = "Messaging"; public DbSet Messages { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.HasDefaultSchema(SchemaName); modelBuilder .Entity() .Property(c => c.CreatedAt) .ValueGeneratedOnAdd() .HasDefaultValueSql("CURRENT_TIMESTAMP"); } public async Task> GetMessagesAsync( Guid subjectId, Guid? parentId, Guid? lastId, int pageSize, CancellationToken ct = default) { IQueryable query = Messages .Where(c => c.SubjectId == subjectId) .Where(c => c.ParentId == parentId); if (lastId.HasValue) { var lastMessage = await Messages .Where(c => c.Id == lastId.Value) .Select(c => new { c.CreatedAt, c.Id }) .FirstOrDefaultAsync(ct); if (lastMessage != null) { query = query .Where(c => c.CreatedAt < lastMessage.CreatedAt || (c.CreatedAt == lastMessage.CreatedAt && c.Id < lastMessage.Id)); } } List messages = await query .OrderByDescending(c => c.CreatedAt) .ThenByDescending(c => c.Id) .Take(pageSize) .ToListAsync(ct); MessageDto[] result = await Task.WhenAll( messages.Select(async message => { UserReference? writer = await userLookup.GetUserAsync(message.CreatedBy, ct); return new MessageDto( message.Id, message.SubjectId, message.CreatedBy, writer?.Fullname ?? "Unknown User", writer?.PortraitUrl, message.CreatedAt, message.ParentId, message.Value); })); return result; } public async Task GetMessageCountAsync( Guid subjectId, Guid? parentId, int pageSize, CancellationToken ct = default) { IQueryable query = Messages .Where(c => c.SubjectId == subjectId) .Where(c => c.ParentId == parentId); int messageCount = await query .Take(pageSize) .CountAsync(ct); return messageCount; } }