PlotDirector/PlotLine/Services/FeatureRequestService.cs

80 lines
3.3 KiB
C#

using PlotLine.Data;
using PlotLine.Models;
using PlotLine.ViewModels;
namespace PlotLine.Services;
public interface IFeatureRequestService
{
Task<FeatureRequest> CreateAsync(int userId, FeatureRequestCreateViewModel model);
Task<FeatureRequest?> GetForUserAsync(int featureRequestId, int userId);
Task<FeatureRequest?> GetForAdminAsync(int featureRequestId);
Task<IReadOnlyList<FeatureRequest>> ListForUserAsync(int userId);
Task<IReadOnlyList<FeatureRequest>> ListForAdminAsync(string? status);
Task<bool> UpdateAdminFieldsAsync(AdminFeatureRequestUpdateViewModel model);
Task<bool> AddUserReplyAsync(int featureRequestId, int userId, string messageBody);
Task<bool> AddAdminReplyAsync(int featureRequestId, int adminUserId, string messageBody);
Task<IReadOnlyList<FeatureRequestMessage>> ListMessagesAsync(int featureRequestId);
}
public sealed class FeatureRequestService(IFeatureRequestRepository featureRequests) : IFeatureRequestService
{
public Task<FeatureRequest> CreateAsync(int userId, FeatureRequestCreateViewModel model)
{
return featureRequests.CreateAsync(
userId,
Clean(model.Title),
Clean(model.Description),
CleanNullable(model.AppArea),
CleanNullable(model.Importance));
}
public Task<FeatureRequest?> GetForUserAsync(int featureRequestId, int userId) =>
featureRequests.GetForUserAsync(featureRequestId, userId);
public Task<FeatureRequest?> GetForAdminAsync(int featureRequestId) =>
featureRequests.GetForAdminAsync(featureRequestId);
public Task<IReadOnlyList<FeatureRequest>> ListForUserAsync(int userId) =>
featureRequests.ListForUserAsync(userId);
public Task<IReadOnlyList<FeatureRequest>> ListForAdminAsync(string? status) =>
featureRequests.ListForAdminAsync(FeatureRequestStatuses.IsValid(status) ? status : null);
public async Task<bool> UpdateAdminFieldsAsync(AdminFeatureRequestUpdateViewModel model)
{
if (!FeatureRequestStatuses.IsValid(model.Status))
{
return false;
}
var updated = await featureRequests.UpdateStatusAsync(model.FeatureRequestID, model.Status, model.IsPublicCandidate);
if (updated is null)
{
return false;
}
await featureRequests.UpdateAdminNotesAsync(model.FeatureRequestID, CleanNullable(model.AdminNotes));
return true;
}
public async Task<bool> AddUserReplyAsync(int featureRequestId, int userId, string messageBody)
{
var message = await featureRequests.AddMessageAsync(featureRequestId, userId, isAdmin: false, Clean(messageBody));
return message is not null;
}
public async Task<bool> AddAdminReplyAsync(int featureRequestId, int adminUserId, string messageBody)
{
var message = await featureRequests.AddMessageAsync(featureRequestId, adminUserId, isAdmin: true, Clean(messageBody));
return message is not null;
}
public Task<IReadOnlyList<FeatureRequestMessage>> ListMessagesAsync(int featureRequestId) =>
featureRequests.ListMessagesAsync(featureRequestId);
private static string Clean(string value) => value.Trim();
private static string? CleanNullable(string? value) => string.IsNullOrWhiteSpace(value) ? null : value.Trim();
}