using Dapper; using Npgsql; namespace Kbx.Shared.Runtime; public sealed class KbxNotificationRepository(NpgsqlDataSource dataSource) { public async Task> GetRecentAsync(Guid tenantId, Guid userId, int limit, CancellationToken ct) { const string sql = """ select id, severity, title, message, created_at as CreatedAt, read_at as ReadAt, screen_id as ScreenId, entity_type as EntityType, entity_id as EntityId, action::text as ActionJson from kbx.user_notifications where tenant_id=@tenantId and user_id=@userId and (expires_at is null or expires_at > now()) order by created_at desc limit @limit; """; await using var connection = await dataSource.OpenConnectionAsync(ct); var rows = await connection.QueryAsync(new CommandDefinition(sql, new { tenantId, userId, limit = Math.Clamp(limit, 1, 100) }, cancellationToken: ct)); return rows.AsList(); } public async Task MarkReadAsync(Guid tenantId, Guid userId, Guid id, CancellationToken ct) { const string sql = "update kbx.user_notifications set read_at=coalesce(read_at, now()) where tenant_id=@tenantId and user_id=@userId and id=@id"; await using var connection = await dataSource.OpenConnectionAsync(ct); await connection.ExecuteAsync(new CommandDefinition(sql, new { tenantId, userId, id }, cancellationToken: ct)); } }