Add general app feedback reporting
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Bson.Serialization.Attributes;
|
||||
|
||||
namespace QuestionsApi.Models;
|
||||
|
||||
public static class AppFeedbackCategory
|
||||
{
|
||||
public const string Bug = "bug";
|
||||
public const string Usability = "usability";
|
||||
public const string FeatureRequest = "feature_request";
|
||||
public const string Account = "account";
|
||||
public const string Other = "other";
|
||||
public static readonly HashSet<string> All = [Bug, Usability, FeatureRequest, Account, Other];
|
||||
}
|
||||
|
||||
public sealed class AppFeedbackContext
|
||||
{
|
||||
public string Screen { get; set; } = "";
|
||||
public string SessionType { get; set; } = "";
|
||||
public string Platform { get; set; } = "";
|
||||
public int ViewportWidth { get; set; }
|
||||
public int ViewportHeight { get; set; }
|
||||
public string AppVersion { get; set; } = "";
|
||||
public string BuildRevision { get; set; } = "";
|
||||
public DateTime? ClientUtc { get; set; }
|
||||
}
|
||||
|
||||
public sealed class AppFeedback
|
||||
{
|
||||
[BsonId, BsonRepresentation(BsonType.ObjectId)] public string? Id { get; set; }
|
||||
public string UserId { get; set; } = "";
|
||||
public string Category { get; set; } = "";
|
||||
public string Details { get; set; } = "";
|
||||
public AppFeedbackContext Context { get; set; } = new();
|
||||
public string Status { get; set; } = QuestionReportStatus.Open;
|
||||
public string ReviewedByUserId { get; set; } = "";
|
||||
public string ReviewerNote { get; set; } = "";
|
||||
public DateTime? ReviewedUtc { get; set; }
|
||||
public DateTime CreatedUtc { get; set; } = DateTime.UtcNow;
|
||||
public DateTime UpdatedUtc { get; set; } = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
public sealed class CreateAppFeedbackRequest
|
||||
{
|
||||
public string Category { get; set; } = "";
|
||||
public string Details { get; set; } = "";
|
||||
public AppFeedbackContext Context { get; set; } = new();
|
||||
}
|
||||
|
||||
public sealed class AppFeedbackListResponse
|
||||
{
|
||||
public List<AppFeedback> Items { get; set; } = [];
|
||||
public long Total { get; set; }
|
||||
public int Skip { get; set; }
|
||||
public int Limit { get; set; }
|
||||
}
|
||||
|
||||
public static class AppFeedbackValidator
|
||||
{
|
||||
public const int MinDetailsLength = 10;
|
||||
public const int MaxDetailsLength = 4000;
|
||||
public const int MaxContextLength = 120;
|
||||
|
||||
public static string? Validate(CreateAppFeedbackRequest request)
|
||||
{
|
||||
var category = (request.Category ?? "").Trim().ToLowerInvariant();
|
||||
var details = (request.Details ?? "").Trim();
|
||||
if (!AppFeedbackCategory.All.Contains(category)) return "category is invalid";
|
||||
if (details.Length is < MinDetailsLength or > MaxDetailsLength)
|
||||
return $"details must be between {MinDetailsLength} and {MaxDetailsLength} characters";
|
||||
var context = request.Context ?? new AppFeedbackContext();
|
||||
if (context.ViewportWidth < 0 || context.ViewportHeight < 0) return "viewport dimensions cannot be negative";
|
||||
if (new[] { context.Screen, context.SessionType, context.Platform, context.AppVersion, context.BuildRevision }
|
||||
.Any(value => (value ?? "").Length > MaxContextLength))
|
||||
return $"context values must be {MaxContextLength} characters or fewer";
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user