Clean up Application layer commands/queries readability and correctness

Add missing AsNoTracking() on read-only queries, drop redundant
Update() calls on already-tracked entities, and fix inconsistent
formatting (stray spaces in generics, ternaries, and lambdas) across
the Albums/Tracks/PlayLists/Users command and query handlers.
This commit is contained in:
2026-09-20 22:23:57 +02:00
parent 11789e78fe
commit ea9bf07126
19 changed files with 46 additions and 45 deletions
@@ -7,7 +7,7 @@ using Musify.Application.Contracts;
namespace Musify.Application.Albums namespace Musify.Application.Albums
{ {
public record GetRecentlyListenedAlbumsQuery(long UserId, int Limit) public record GetRecentlyListenedAlbumsQuery(long UserId, int Limit)
: IQuery<ErrorOr<IReadOnlyList<AlbumApplicationResponse> >>; : IQuery<ErrorOr<IReadOnlyList<AlbumApplicationResponse>>>;
public class GetRecentlyListenedAlbumsQueryHandler(IDatabase database) public class GetRecentlyListenedAlbumsQueryHandler(IDatabase database)
: IQueryHandler<GetRecentlyListenedAlbumsQuery, ErrorOr<IReadOnlyList<AlbumApplicationResponse>>> : IQueryHandler<GetRecentlyListenedAlbumsQuery, ErrorOr<IReadOnlyList<AlbumApplicationResponse>>>
@@ -24,9 +24,9 @@ namespace Musify.Application.Albums
listenedTrackIds, listenedTrackIds,
albumTrack => albumTrack.TrackId, albumTrack => albumTrack.TrackId,
history => history.TrackId, history => history.TrackId,
(albumTrack, history) => new { albumTrack.AlbumId, history.ListenedAt } ) (albumTrack, history) => new { albumTrack.AlbumId, history.ListenedAt })
.GroupBy(entry => entry.AlbumId) .GroupBy(entry => entry.AlbumId)
.Select(group => new { AlbumId = group.Key, LastListenedAt = group.Max(entry => entry.ListenedAt) } ) .Select(group => new { AlbumId = group.Key, LastListenedAt = group.Max(entry => entry.ListenedAt) })
.OrderByDescending(entry => entry.LastListenedAt) .OrderByDescending(entry => entry.LastListenedAt)
.Take(request.Limit) .Take(request.Limit)
.ToListAsync(cancellationToken); .ToListAsync(cancellationToken);
@@ -48,7 +48,7 @@ namespace Musify.Application.Albums
.Take(AlbumApplicationResponse.CoverTrackCount) .Take(AlbumApplicationResponse.CoverTrackCount)
.Select(albumTrack => albumTrack.TrackId) .Select(albumTrack => albumTrack.TrackId)
.ToList() .ToList()
} ) })
.ToDictionaryAsync(entry => entry.Album.Id, cancellationToken); .ToDictionaryAsync(entry => entry.Album.Id, cancellationToken);
return ranked return ranked
@@ -42,7 +42,7 @@ namespace Musify.Application.Albums
var effectiveSizeBytes = request.ExpectedSizeBytes var effectiveSizeBytes = request.ExpectedSizeBytes
?? uploadIntentConfiguration.DefaultExpectedPictureSizeBytes; ?? uploadIntentConfiguration.DefaultExpectedPictureSizeBytes;
var objectName = $"{Guid.NewGuid() }.{request.FileType.TrimStart('.').ToLowerInvariant() }"; var objectName = $"{Guid.NewGuid()}.{request.FileType.TrimStart('.').ToLowerInvariant()}";
var tempKey = albumConfiguration.Routes.BuildTempPicturePath( var tempKey = albumConfiguration.Routes.BuildTempPicturePath(
uploadIntentConfiguration.TemporalRootPrefix, request.UserId, objectName); uploadIntentConfiguration.TemporalRootPrefix, request.UserId, objectName);
@@ -84,7 +84,7 @@ namespace Musify.Application.Albums
await database.SaveChangesAsync(cancellationToken); await database.SaveChangesAsync(cancellationToken);
await transaction.CommitAsync(cancellationToken); await transaction.CommitAsync(cancellationToken);
logger.LogInformation("Issued upload intent {IntentId} for user {UserId} (AlbumPicture, temp key: {Key} )", intent.Id, request.UserId, tempKey); logger.LogInformation("Issued upload intent {IntentId} for user {UserId} (AlbumPicture, temp key: {Key})", intent.Id, request.UserId, tempKey);
return new AlbumPictureUploadResponse( return new AlbumPictureUploadResponse(
intent.Id, intent.Id,
@@ -77,8 +77,6 @@ namespace Musify.Application.Albums
finalPictureKey = albumConfiguration.Routes.BuildOriginalPicturePath(request.UserId, pictureIntent.ObjectName); finalPictureKey = albumConfiguration.Routes.BuildOriginalPicturePath(request.UserId, pictureIntent.ObjectName);
} }
database.Albums.Update(album);
if (pictureIntent != null && finalPictureKey != null) if (pictureIntent != null && finalPictureKey != null)
{ {
var publishResult = await PublishUpdateAlbumPictureSourceEventAsync( var publishResult = await PublishUpdateAlbumPictureSourceEventAsync(
@@ -55,7 +55,7 @@ namespace Musify.Application.PlayLists
UserId = request.UserId, UserId = request.UserId,
Name = request.Name, Name = request.Name,
NormalizedName = request.Name.Trim().ToUpperInvariant(), NormalizedName = request.Name.Trim().ToUpperInvariant(),
Description = string.IsNullOrWhiteSpace(request.Description)? null: request.Description.Trim(), Description = string.IsNullOrWhiteSpace(request.Description) ? null : request.Description.Trim(),
Pictures = resolvedPictures.Pictures, Pictures = resolvedPictures.Pictures,
Visibility = request.Visibility Visibility = request.Visibility
}; };
@@ -106,7 +106,7 @@ namespace Musify.Application.PlayLists
}, validation.Value); }, validation.Value);
} }
async Task<ErrorOr<Success>> PublishCreatePlayListEventAsync( private async Task<ErrorOr<Success>> PublishCreatePlayListEventAsync(
Guid playListId, Guid playListId,
UploadIntent pictureIntent, UploadIntent pictureIntent,
string finalPictureKey, string finalPictureKey,
@@ -16,9 +16,9 @@ namespace Musify.Application.PlayLists
: IQuery<ErrorOr<PaginatedResponse<TrackApplicationResponse>>>; : IQuery<ErrorOr<PaginatedResponse<TrackApplicationResponse>>>;
public class GetPlayListTracksQueryHandler(IDatabase database) public class GetPlayListTracksQueryHandler(IDatabase database)
: IQueryHandler<GetPlayListTracksQuery, ErrorOr<PaginatedResponse<TrackApplicationResponse>> > : IQueryHandler<GetPlayListTracksQuery, ErrorOr<PaginatedResponse<TrackApplicationResponse>>>
{ {
public async ValueTask<ErrorOr<PaginatedResponse<TrackApplicationResponse> >> Handle(GetPlayListTracksQuery request, CancellationToken cancellationToken) public async ValueTask<ErrorOr<PaginatedResponse<TrackApplicationResponse>>> Handle(GetPlayListTracksQuery request, CancellationToken cancellationToken)
{ {
var playListExists = await database.PlayLists var playListExists = await database.PlayLists
.AsNoTracking() .AsNoTracking()
@@ -10,12 +10,12 @@ using Musify.Application.Contracts;
namespace Musify.Application.PlayLists namespace Musify.Application.PlayLists
{ {
public record GetPlayListsQuery(int PageNumber, int PageSize) public record GetPlayListsQuery(int PageNumber, int PageSize)
: IQuery<ErrorOr<PaginatedResponse<PlayListApplicationResponse>> >; : IQuery<ErrorOr<PaginatedResponse<PlayListApplicationResponse>>>;
public class GetPlayListsQueryHandler(IDatabase database) public class GetPlayListsQueryHandler(IDatabase database)
: IQueryHandler<GetPlayListsQuery, ErrorOr<PaginatedResponse<PlayListApplicationResponse> >> : IQueryHandler<GetPlayListsQuery, ErrorOr<PaginatedResponse<PlayListApplicationResponse>>>
{ {
public async ValueTask<ErrorOr<PaginatedResponse<PlayListApplicationResponse> >> Handle(GetPlayListsQuery request, CancellationToken cancellationToken) public async ValueTask<ErrorOr<PaginatedResponse<PlayListApplicationResponse>>> Handle(GetPlayListsQuery request, CancellationToken cancellationToken)
{ {
var totalCount = await database.PlayLists.CountAsync(cancellationToken); var totalCount = await database.PlayLists.CountAsync(cancellationToken);
@@ -16,12 +16,12 @@ namespace Musify.Application.PlayLists
int PageNumber, int PageNumber,
int PageSize, int PageSize,
bool OnlyPublic = false) bool OnlyPublic = false)
: IQuery<ErrorOr<PaginatedResponse<PlayListApplicationResponse>> >; : IQuery<ErrorOr<PaginatedResponse<PlayListApplicationResponse>>>;
public class GetPlayListsByUserIdQueryHandler(IDatabase database) public class GetPlayListsByUserIdQueryHandler(IDatabase database)
: IQueryHandler<GetPlayListsByUserIdQuery, ErrorOr<PaginatedResponse<PlayListApplicationResponse> > > : IQueryHandler<GetPlayListsByUserIdQuery, ErrorOr<PaginatedResponse<PlayListApplicationResponse>>>
{ {
public async ValueTask<ErrorOr<PaginatedResponse<PlayListApplicationResponse> >> Handle(GetPlayListsByUserIdQuery request, CancellationToken cancellationToken) public async ValueTask<ErrorOr<PaginatedResponse<PlayListApplicationResponse>>> Handle(GetPlayListsByUserIdQuery request, CancellationToken cancellationToken)
{ {
var playListsQuery = database.PlayLists var playListsQuery = database.PlayLists
.AsNoTracking() .AsNoTracking()
@@ -51,7 +51,7 @@ namespace Musify.Application.PlayLists
.Take(PlayListApplicationResponse.CoverTrackCount) .Take(PlayListApplicationResponse.CoverTrackCount)
.Select(plt => plt.TrackId) .Select(plt => plt.TrackId)
.ToList() .ToList()
} ) })
.ToPagedListAsync(request.PageNumber, request.PageSize, totalCount, cancellationToken); .ToPagedListAsync(request.PageNumber, request.PageSize, totalCount, cancellationToken);
var pagedPlayLists = new StaticPagedList<PlayListApplicationResponse>( var pagedPlayLists = new StaticPagedList<PlayListApplicationResponse>(
@@ -42,7 +42,7 @@ namespace Musify.Application.PlayLists
var effectiveSizeBytes = request.ExpectedSizeBytes var effectiveSizeBytes = request.ExpectedSizeBytes
?? uploadIntentConfiguration.DefaultExpectedPictureSizeBytes; ?? uploadIntentConfiguration.DefaultExpectedPictureSizeBytes;
var objectName = $"{Guid.NewGuid() }.{request.FileType.TrimStart('.').ToLowerInvariant() }"; var objectName = $"{Guid.NewGuid()}.{request.FileType.TrimStart('.').ToLowerInvariant()}";
var tempKey = playListConfiguration.Routes.BuildTempPicturePath( var tempKey = playListConfiguration.Routes.BuildTempPicturePath(
uploadIntentConfiguration.TemporalRootPrefix, request.UserId, objectName); uploadIntentConfiguration.TemporalRootPrefix, request.UserId, objectName);
@@ -84,7 +84,7 @@ namespace Musify.Application.PlayLists
await database.SaveChangesAsync(cancellationToken); await database.SaveChangesAsync(cancellationToken);
await transaction.CommitAsync(cancellationToken); await transaction.CommitAsync(cancellationToken);
logger.LogInformation("Issued upload intent {IntentId} for user {UserId} (PlayListPicture, temp key: {Key} )", intent.Id, request.UserId, tempKey); logger.LogInformation("Issued upload intent {IntentId} for user {UserId} (PlayListPicture, temp key: {Key})", intent.Id, request.UserId, tempKey);
return new PlayListPictureUploadResponse( return new PlayListPictureUploadResponse(
intent.Id, intent.Id,
@@ -85,9 +85,7 @@ namespace Musify.Application.PlayLists
finalPictureKey = playListConfiguration.Routes.BuildOriginalPicturePath(request.UserId, pictureIntent.ObjectName); finalPictureKey = playListConfiguration.Routes.BuildOriginalPicturePath(request.UserId, pictureIntent.ObjectName);
} }
database.PlayLists.Update(playListEntity); if (pictureIntent != null && finalPictureKey != null)
if (pictureIntent != null&& finalPictureKey != null)
{ {
var publishResult = await PublishUpdatePlayListPictureSourceEventAsync( var publishResult = await PublishUpdatePlayListPictureSourceEventAsync(
playListEntity.Id, pictureIntent, finalPictureKey, cancellationToken); playListEntity.Id, pictureIntent, finalPictureKey, cancellationToken);
@@ -117,7 +115,7 @@ namespace Musify.Application.PlayLists
return PlayListApplicationResponse.FromEntity(playListEntity, coverTrackIds); return PlayListApplicationResponse.FromEntity(playListEntity, coverTrackIds);
} }
async Task<ErrorOr<Success>> PublishUpdatePlayListPictureSourceEventAsync( private async Task<ErrorOr<Success>> PublishUpdatePlayListPictureSourceEventAsync(
Guid playListId, Guid playListId,
UploadIntent pictureIntent, UploadIntent pictureIntent,
string finalPictureKey, string finalPictureKey,
@@ -14,6 +14,7 @@ namespace Musify.Application.Tracks
public async ValueTask<ErrorOr<TrackApplicationResponse>> Handle(GetLastTrackListenedByUserIdQuery query, CancellationToken cancellationToken) public async ValueTask<ErrorOr<TrackApplicationResponse>> Handle(GetLastTrackListenedByUserIdQuery query, CancellationToken cancellationToken)
{ {
var track = await database.ListeningHistories var track = await database.ListeningHistories
.AsNoTracking()
.Include(t => t.Track.Owner) .Include(t => t.Track.Owner)
.Include(t => t.Track.Tags) .Include(t => t.Track.Tags)
.Where(t => t.UserId == query.UserId) .Where(t => t.UserId == query.UserId)
@@ -16,6 +16,7 @@ namespace Musify.Application.Tracks
public async ValueTask<IEnumerable<TrackApplicationResponse>> Handle(GetListeningHistoryQuery query, CancellationToken cancellationToken) public async ValueTask<IEnumerable<TrackApplicationResponse>> Handle(GetListeningHistoryQuery query, CancellationToken cancellationToken)
{ {
var recentTrackIds = await database.ListeningHistories var recentTrackIds = await database.ListeningHistories
.AsNoTracking()
.Where(l => l.UserId == query.UserId) .Where(l => l.UserId == query.UserId)
.GroupBy(l => l.TrackId) .GroupBy(l => l.TrackId)
.OrderByDescending(g => g.Max(l => l.ListenedAt)) .OrderByDescending(g => g.Max(l => l.ListenedAt))
@@ -24,14 +25,15 @@ namespace Musify.Application.Tracks
.ToListAsync(cancellationToken); .ToListAsync(cancellationToken);
var tracksById = await database.Tracks var tracksById = await database.Tracks
.AsNoTracking()
.Include(t => t.Owner) .Include(t => t.Owner)
.Include(t => t.Tags) .Include(t => t.Tags)
.Where(t => recentTrackIds.Contains(t.Id)) .Where(t => recentTrackIds.Contains(t.Id))
.Select(t => new { t.Id, Track = t, ListensCount = t.ListeningHistories.Count } ) .Select(t => new { t.Id, Track = t, ListensCount = t.ListeningHistories.Count })
.ToDictionaryAsync(t => t.Id, cancellationToken); .ToDictionaryAsync(t => t.Id, cancellationToken);
return recentTrackIds return recentTrackIds
.Select(id => tracksById[id] ) .Select(id => tracksById[id])
.Select(t => TrackApplicationResponse.FromEntity(t.Track, t.ListensCount)); .Select(t => TrackApplicationResponse.FromEntity(t.Track, t.ListensCount));
} }
} }
@@ -10,7 +10,7 @@ namespace Musify.Application.Tracks
: IQuery<ErrorOr<TrackApplicationResponse>>; : IQuery<ErrorOr<TrackApplicationResponse>>;
public class GetTrackByIdQueryHandler(IDatabase database) public class GetTrackByIdQueryHandler(IDatabase database)
: IQueryHandler<GetTrackByIdQuery, ErrorOr<TrackApplicationResponse> > : IQueryHandler<GetTrackByIdQuery, ErrorOr<TrackApplicationResponse>>
{ {
public async ValueTask<ErrorOr<TrackApplicationResponse>> Handle(GetTrackByIdQuery request, CancellationToken cancellationToken) public async ValueTask<ErrorOr<TrackApplicationResponse>> Handle(GetTrackByIdQuery request, CancellationToken cancellationToken)
{ {
@@ -48,6 +48,6 @@ namespace Musify.Application.Tracks
} }
private static string? BuildKey(Func<string, string> builder, string? name) private static string? BuildKey(Func<string, string> builder, string? name)
=> string.IsNullOrEmpty(name)? null: builder(name); => string.IsNullOrEmpty(name) ? null : builder(name);
} }
} }
@@ -33,7 +33,7 @@ namespace Musify.Application.Tracks
var pagedEntities = await tracksQuery var pagedEntities = await tracksQuery
.OrderByDescending(t => t.Track.CreatedAt) .OrderByDescending(t => t.Track.CreatedAt)
.ThenBy(t => t.Id) .ThenBy(t => t.Id)
.Select(t => new { t.Track, ListensCount = t.Track.ListeningHistories.Count } ) .Select(t => new { t.Track, ListensCount = t.Track.ListeningHistories.Count })
.ToPagedListAsync(request.PageNumber, request.PageSize, totalCount, cancellationToken); .ToPagedListAsync(request.PageNumber, request.PageSize, totalCount, cancellationToken);
var items = pagedEntities var items = pagedEntities
@@ -14,12 +14,12 @@ namespace Musify.Application.Tracks
string? Name, string? Name,
int PageNumber, int PageNumber,
int PageSize) int PageSize)
: IQuery<ErrorOr<PaginatedResponse<TrackApplicationResponse> > >; : IQuery<ErrorOr<PaginatedResponse<TrackApplicationResponse>>>;
public class GetTracksByUserIdQueryHandler(IDatabase database) public class GetTracksByUserIdQueryHandler(IDatabase database)
: IQueryHandler<GetTracksByUserIdQuery, ErrorOr<PaginatedResponse<TrackApplicationResponse>> > : IQueryHandler<GetTracksByUserIdQuery, ErrorOr<PaginatedResponse<TrackApplicationResponse>>>
{ {
public async ValueTask<ErrorOr<PaginatedResponse<TrackApplicationResponse> >> Handle(GetTracksByUserIdQuery request, CancellationToken cancellationToken) public async ValueTask<ErrorOr<PaginatedResponse<TrackApplicationResponse>>> Handle(GetTracksByUserIdQuery request, CancellationToken cancellationToken)
{ {
var pageNumber = request.PageNumber < 1 ? 1 : request.PageNumber; var pageNumber = request.PageNumber < 1 ? 1 : request.PageNumber;
var pageSize = request.PageSize < 1 ? 10 : request.PageSize; var pageSize = request.PageSize < 1 ? 10 : request.PageSize;
@@ -28,7 +28,7 @@ namespace Musify.Application.Users
} }
public class CreateUserCommandHandler(IDatabase database, ILogger<CreateUserCommandHandler> logger) public class CreateUserCommandHandler(IDatabase database, ILogger<CreateUserCommandHandler> logger)
: ICommandHandler<CreateUserCommand, ErrorOr<UserApplicationResponse> > : ICommandHandler<CreateUserCommand, ErrorOr<UserApplicationResponse>>
{ {
public async ValueTask<ErrorOr<UserApplicationResponse>> Handle(CreateUserCommand request, CancellationToken cancellationToken) public async ValueTask<ErrorOr<UserApplicationResponse>> Handle(CreateUserCommand request, CancellationToken cancellationToken)
{ {
@@ -16,6 +16,7 @@ namespace Musify.Application.Users
var weekAgo = DateTime.UtcNow.AddDays(-7); var weekAgo = DateTime.UtcNow.AddDays(-7);
var thisWeekHistory = database.ListeningHistories var thisWeekHistory = database.ListeningHistories
.AsNoTracking()
.Where(l => l.UserId == request.UserId && l.ListenedAt >= weekAgo); .Where(l => l.UserId == request.UserId && l.ListenedAt >= weekAgo);
var tracksThisWeek = await thisWeekHistory var tracksThisWeek = await thisWeekHistory
@@ -24,10 +25,11 @@ namespace Musify.Application.Users
.CountAsync(cancellationToken); .CountAsync(cancellationToken);
var secondsThisWeek = await thisWeekHistory var secondsThisWeek = await thisWeekHistory
.Join(database.Tracks, l => l.TrackId, t => t.Id, (l, t) => t.DurationSeconds) .Join(database.Tracks.AsNoTracking(), l => l.TrackId, t => t.Id, (l, t) => t.DurationSeconds)
.SumAsync(cancellationToken); .SumAsync(cancellationToken);
var listenedDates = await database.ListeningHistories var listenedDates = await database.ListeningHistories
.AsNoTracking()
.Where(l => l.UserId == request.UserId) .Where(l => l.UserId == request.UserId)
.Select(l => l.ListenedAt.Date) .Select(l => l.ListenedAt.Date)
.Distinct() .Distinct()
@@ -7,10 +7,10 @@ using Musify.Application.Users.Responses;
namespace Musify.Application.Users namespace Musify.Application.Users
{ {
public record GetUserByIdQuery(long Id) public record GetUserByIdQuery(long Id)
: IQuery<ErrorOr<UserApplicationResponse> >; : IQuery<ErrorOr<UserApplicationResponse>>;
public class GetUserByIdQueryHandler(IDatabase database) public class GetUserByIdQueryHandler(IDatabase database)
: IQueryHandler<GetUserByIdQuery, ErrorOr<UserApplicationResponse> > : IQueryHandler<GetUserByIdQuery, ErrorOr<UserApplicationResponse>>
{ {
public async ValueTask<ErrorOr<UserApplicationResponse>> Handle(GetUserByIdQuery request, CancellationToken cancellationToken) public async ValueTask<ErrorOr<UserApplicationResponse>> Handle(GetUserByIdQuery request, CancellationToken cancellationToken)
{ {
@@ -9,29 +9,29 @@ using Musify.Application.Contracts;
namespace Musify.Application.Users namespace Musify.Application.Users
{ {
public record GetUsersQuery(int PageNumber, int PageSize, string? UsernameSearch) public record GetUsersQuery(int PageNumber, int PageSize, string? UsernameSearch)
: IQuery<ErrorOr<PaginatedResponse<UserApplicationResponse> >>; : IQuery<ErrorOr<PaginatedResponse<UserApplicationResponse>>>;
public class GetUsersQueryHandler(IDatabase database) public class GetUsersQueryHandler(IDatabase database)
: IQueryHandler<GetUsersQuery, ErrorOr<PaginatedResponse<UserApplicationResponse> > > : IQueryHandler<GetUsersQuery, ErrorOr<PaginatedResponse<UserApplicationResponse>>>
{ {
public async ValueTask<ErrorOr<PaginatedResponse<UserApplicationResponse> >> Handle(GetUsersQuery request, CancellationToken cancellationToken) public async ValueTask<ErrorOr<PaginatedResponse<UserApplicationResponse>>> Handle(GetUsersQuery request, CancellationToken cancellationToken)
{ {
var user = database.Users var usersQuery = database.Users
.AsNoTracking() .AsNoTracking()
.AsQueryable(); .AsQueryable();
if (!string.IsNullOrEmpty(request.UsernameSearch)) if (!string.IsNullOrEmpty(request.UsernameSearch))
{ {
var normalizedUsername = request.UsernameSearch.Trim().ToUpperInvariant(); var normalizedUsername = request.UsernameSearch.Trim().ToUpperInvariant();
user = user.Where(u => u.NormalizedName.Contains(normalizedUsername)); usersQuery = usersQuery.Where(u => u.NormalizedName.Contains(normalizedUsername));
} }
var totalCount = await user.CountAsync(cancellationToken); var totalCount = await usersQuery.CountAsync(cancellationToken);
var pagedUser = await user var pagedUsers = await usersQuery
.Select(u => UserApplicationResponse.FromEntity(u)) .Select(u => UserApplicationResponse.FromEntity(u))
.ToPagedListAsync(request.PageNumber, request.PageSize, totalCount, cancellationToken); .ToPagedListAsync(request.PageNumber, request.PageSize, totalCount, cancellationToken);
return PaginatedResponse<UserApplicationResponse>.FromPagedList(pagedUser); return PaginatedResponse<UserApplicationResponse>.FromPagedList(pagedUsers);
} }
} }
} }