chore(codebase): full cleanup pass

This commit is contained in:
2025-06-21 01:58:48 -04:00
parent 8323477cd0
commit 81b5db34ef
92 changed files with 529 additions and 452 deletions

View File

@@ -29,11 +29,11 @@ public static class ChangeBanner
Request request,
CancellationToken ct)
{
var creator = await context
Creator? creator = await context
.Creators
.SingleOrDefaultAsync(
c => c.Id == request.CreatorId,
cancellationToken: ct);
ct);
if (creator is null)
{
@@ -41,7 +41,7 @@ public static class ChangeBanner
return;
}
var blobUrl = await blobStorage.UploadFileAsync(
string blobUrl = await blobStorage.UploadFileAsync(
ContainerNames.Creators,
$"{request.CreatorId}/{SubDirectoryNames.Profile}/{CommonFileNames.BannerPicture}",
request.File.OpenReadStream(),

View File

@@ -38,12 +38,12 @@ public class ChangeEmailHandler(
ChangeEmailRequest request,
CancellationToken ct)
{
var creator = await context
Creator? creator = await context
.Creators
.Include(c => c.Presentation)
.SingleOrDefaultAsync(
c => c.Id == request.CreatorId,
cancellationToken: ct);
ct);
if (creator is null)
{
@@ -59,9 +59,9 @@ public class ChangeEmailHandler(
}
creator.Presentation.Email = request.Email?.Trim();
await context.SaveChangesAsync(ct);
await SendOkAsync(ct);
}
}
}

View File

@@ -44,11 +44,11 @@ public class ChangeLogoHandler(
ChangeLogoRequest request,
CancellationToken ct)
{
var creator = await context
Creator? creator = await context
.Creators
.SingleOrDefaultAsync(
c => c.Id == request.CreatorId,
cancellationToken: ct);
ct);
if (creator is null)
{
@@ -56,7 +56,7 @@ public class ChangeLogoHandler(
return;
}
var blobUrl = await blobStorage.UploadFileAsync(
string blobUrl = await blobStorage.UploadFileAsync(
ContainerNames.Creators,
$"{request.CreatorId}/{SubDirectoryNames.Profile}/{CommonFileNames.ProfilePicture}",
request.File.OpenReadStream(),

View File

@@ -34,11 +34,11 @@ public class ChangeNameHandler(
ChangeNameRequest request,
CancellationToken ct)
{
var creator = await context
Creator creator = await context
.Creators
.SingleAsync(
c => c.Id == request.CreatorId,
cancellationToken: ct);
ct);
creator.Name = request.Name;

View File

@@ -38,12 +38,12 @@ public class ChangePhoneNumberHandler(
ChangePhoneNumberRequest request,
CancellationToken ct)
{
var creator = await context
Creator? creator = await context
.Creators
.Include(c => c.Presentation)
.SingleOrDefaultAsync(
c => c.Id == request.CreatorId,
cancellationToken: ct);
ct);
if (creator is null)
{
@@ -59,9 +59,9 @@ public class ChangePhoneNumberHandler(
}
creator.Presentation.PhoneNumber = request.PhoneNumber?.Trim();
await context.SaveChangesAsync(ct);
await SendOkAsync(ct);
}
}
}

View File

@@ -45,12 +45,12 @@ public class ChangePresentationInfosHandler(
ChangePresentationInfosRequest request,
CancellationToken ct)
{
var creator = await context
Creator? creator = await context
.Creators
.Include(c => c.Presentation)
.SingleOrDefaultAsync(
c => c.Id == request.CreatorId,
cancellationToken: ct);
ct);
if (creator is null)
{
@@ -60,12 +60,12 @@ public class ChangePresentationInfosHandler(
// Update the presentation info with the new values
creator.Presentation.Description = request.Description.Trim();
creator.Presentation.VideoUrl = request.VideoUrl != null
creator.Presentation.VideoUrl = request.VideoUrl != null
? YouTubeUrlHelper.ExtractVideoId(request.VideoUrl.Trim())
: null;
await context.SaveChangesAsync(ct);
await SendOkAsync(ct);
}
}

View File

@@ -1,5 +1,6 @@
using Hutopy.Infrastructure.Security;
using Hutopy.Modules.Creators.Data;
using Microsoft.EntityFrameworkCore.Storage;
namespace Hutopy.Modules.Creators.Features;
@@ -17,7 +18,7 @@ internal sealed class ChangeSlugRequestValidator
RuleFor(r => r.CreatorId)
.NotNull().WithMessage("You should specify the CreatorId")
.NotEmpty().WithMessage("You should specify a valid/not empty CreatorId");
RuleFor(r => r.SlugReservationId)
.NotNull().WithMessage("You should specify the SlugReservationId")
.NotEmpty().WithMessage("You should specify a valid/not empty SlugReservationId");
@@ -39,15 +40,15 @@ public class ChangeSlugHandler(
ChangeSlugRequest request,
CancellationToken ct)
{
await using var transaction = await context.Database.BeginTransactionAsync(ct);
await using IDbContextTransaction transaction = await context.Database.BeginTransactionAsync(ct);
try
{
var creator = await context
Creator creator = await context
.Creators
.SingleAsync(
c => c.Id == request.CreatorId,
cancellationToken: ct);
ct);
if (creator.CreatedBy != User.GetUserId())
{
@@ -55,7 +56,7 @@ public class ChangeSlugHandler(
return;
}
var reservation = await context
Slugs? reservation = await context
.Slugs
.FirstOrDefaultAsync(
s => s.Id == request.SlugReservationId,
@@ -67,7 +68,7 @@ public class ChangeSlugHandler(
return;
}
var previousReservation = await context
Slugs? previousReservation = await context
.Slugs
.FirstOrDefaultAsync(
s => s.UsedBy == request.CreatorId,

View File

@@ -27,12 +27,12 @@ public class ChangeSocialsHandler(
public override async Task HandleAsync(ChangeSocialsRequest request, CancellationToken ct)
{
var creator = await context
Creator creator = await context
.Creators
.Include(c => c.Socials)
.SingleAsync(
c => c.Id == request.CreatorId,
cancellationToken: ct);
ct);
creator.Socials.FacebookUrl = request.FacebookUrl;
creator.Socials.InstagramUrl = request.InstagramUrl;

View File

@@ -19,14 +19,14 @@ public class ChangeTitleHandler(
}
public override async Task HandleAsync(
ChangeTitleRequest request,
ChangeTitleRequest request,
CancellationToken ct)
{
var creator = await context
Creator creator = await context
.Creators
.SingleAsync(
c => c.Id == request.CreatorId,
cancellationToken: ct);
ct);
creator.Title = request.Title;

View File

@@ -1,5 +1,6 @@
using Hutopy.Infrastructure.Security;
using Hutopy.Modules.Creators.Data;
using Microsoft.EntityFrameworkCore.Storage;
namespace Hutopy.Modules.Creators.Features;
@@ -17,7 +18,7 @@ public sealed class CreateCreatorRequestValidator : Validator<CreateCreatorReque
.NotNull()
.NotEmpty()
.WithMessage("You should specify a valid SlugReservationId");
RuleFor(r => r.CreatorId)
.NotNull()
.NotEmpty()
@@ -40,11 +41,11 @@ public sealed class CreateCreatorHandler(
CreateCreatorRequest req,
CancellationToken ct)
{
await using var transaction = await context.Database.BeginTransactionAsync(ct);
await using IDbContextTransaction transaction = await context.Database.BeginTransactionAsync(ct);
try
{
var slug = await context
Slugs slug = await context
.Slugs
.SingleAsync(s => s.Id == req.SlugReservationId, ct);
@@ -55,23 +56,20 @@ public sealed class CreateCreatorHandler(
await SendErrorsAsync(500, ct);
return;
}
slug.UsedBy = req.CreatorId;
await context.Creators.AddAsync(
new Creator
{
Id = req.CreatorId,
CreatedBy = User.GetUserId(),
Name = slug.Name,
Slug = slug.NormalizedName
Id = req.CreatorId, CreatedBy = User.GetUserId(), Name = slug.Name, Slug = slug.NormalizedName
},
ct);
await context.SaveChangesAsync(ct);
await transaction.CommitAsync(ct);
await SendOkAsync(ct);
}
catch (Exception)

View File

@@ -28,7 +28,7 @@ public class GetCreatorByIdHandler(
public override void Configure()
{
Get("/api/creators/{CreatorId}");
Options((o => o.WithTags("Creators")));
Options(o => o.WithTags("Creators"));
AllowAnonymous();
}
@@ -36,13 +36,19 @@ public class GetCreatorByIdHandler(
GetCreatorByIdRequest req,
CancellationToken ct)
{
var creator = await context
Creator? creator = await context
.Creators
.FindAsync(
[req.CreatorId],
cancellationToken: ct);
ct);
if (creator is null) await SendNotFoundAsync(ct);
else await SendAsync(creator, cancellation: ct);
if (creator is null)
{
await SendNotFoundAsync(ct);
}
else
{
await SendAsync(creator, cancellation: ct);
}
}
}

View File

@@ -49,7 +49,7 @@ public class GetCreatorBySlugHandler(
public override void Configure()
{
Get("/api/creators/@{Name}");
Options((o => o.WithTags("Creators")));
Options(o => o.WithTags("Creators"));
AllowAnonymous();
}
@@ -57,9 +57,9 @@ public class GetCreatorBySlugHandler(
GetCreatorBySlugRequest req,
CancellationToken ct)
{
var creatorName = req.Name.ToLower();
string creatorName = req.Name.ToLower();
var response = await context
GetCreatorBySlugResponse? response = await context
.Creators
.IgnoreQueryFilters()
.Where(c => EF.Functions.ILike(c.Slug, creatorName))

View File

@@ -34,12 +34,12 @@ public sealed class RemoveCreatorHandler(
RemoveCreatorRequest req,
CancellationToken ct)
{
var creatorSlug = req.CreatorSlug.ToLower();
string creatorSlug = req.CreatorSlug.ToLower();
var creator = await context
Creator? creator = await context
.Creators
.Where(c => EF.Functions.ILike(c.Slug, creatorSlug))
.SingleOrDefaultAsync(cancellationToken: ct);
.SingleOrDefaultAsync(ct);
if (creator is null)
{

View File

@@ -4,6 +4,7 @@ using Hutopy.Infrastructure.Security;
using Hutopy.Modules.Creators.Configuration;
using Hutopy.Modules.Creators.Data;
using Hutopy.Modules.Creators.Services;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.Extensions.Options;
using Npgsql;
@@ -45,33 +46,31 @@ public sealed class ReserveSlug(
ReserveSlugRequest req,
CancellationToken ct)
{
await using var transaction = await context.Database.BeginTransactionAsync(ct);
await using IDbContextTransaction transaction = await context.Database.BeginTransactionAsync(ct);
try
{
// First, purge any expired slugs
await slugPurger.PurgeExpiredSlugsAsync(ct);
var reservation = await context.Slugs.FirstOrDefaultAsync(
s => s.Id == req.ReservationId && s.CreatedBy == User.GetUserId(),
cancellationToken: ct);
Slugs? reservation = await context.Slugs.FirstOrDefaultAsync(
s => s.Id == req.ReservationId && s.CreatedBy == User.GetUserId(),
ct);
if (reservation == null)
{
reservation = new Slugs
{
Id = req.ReservationId,
CreatedBy = User.GetUserId(),
CreatedAt = DateTimeOffset.UtcNow,
Id = req.ReservationId, CreatedBy = User.GetUserId(), CreatedAt = DateTimeOffset.UtcNow
};
context.Slugs.Attach(reservation);
context.Entry(reservation).State = EntityState.Added;
}
reservation.Name = req.Slug;
reservation.ReservedUntil = DateTimeOffset.UtcNow + opts.Value.SlugReservationDuration;
await context.SaveChangesAsync(ct);
await transaction.CommitAsync(ct);
@@ -81,7 +80,7 @@ public sealed class ReserveSlug(
catch (Exception e)
{
await transaction.RollbackAsync(ct);
Logger.LogError("Transaction failed: {Message}", e.Message);
if (e.InnerException is PostgresException innerException)

View File

@@ -34,13 +34,13 @@ public sealed class RestoreCreatorHandler(
RestoreCreatorRequest req,
CancellationToken ct)
{
var creatorSlug = req.CreatorSlug.ToLower();
string creatorSlug = req.CreatorSlug.ToLower();
var creator = await context
Creator? creator = await context
.Creators
.IgnoreQueryFilters()
.Where(c => EF.Functions.ILike(c.Slug, creatorSlug))
.SingleOrDefaultAsync(cancellationToken: ct);
.SingleOrDefaultAsync(ct);
if (creator is null)
{