Refactor app architecture and clean local artifacts

This commit is contained in:
AzuTear
2026-06-24 23:43:14 +02:00
parent 17134b3b82
commit fef1d36fe8
274 changed files with 37724 additions and 6065 deletions
@@ -0,0 +1,149 @@
using Backend.Contracts;
using Backend.Common;
using Backend.Data;
using Backend.Domain;
using Backend.Services;
using Microsoft.EntityFrameworkCore;
namespace Backend.Endpoints;
public static partial class AdminSeasonManagementEndpoints
{
private static async Task<IResult> CreateCandidate(
HttpContext context,
int seasonId,
UpsertCandidateRequest request,
AwardsDbContext db,
IAdminAuditService adminAuditService)
{
var session = AdminEndpointConventions.CurrentSession(context);
var validationError = ValidateCandidateRequest(request);
if (validationError is not null)
{
return validationError;
}
var category = await db.Categories.FirstOrDefaultAsync(item => item.Id == request.CategoryId && item.SeasonId == seasonId);
if (category is null)
{
return Results.BadRequest(new { message = "The selected category does not exist in this season." });
}
var normalizedDisplayName = request.DisplayName.Trim();
var normalizedChannelSlug = request.ChannelSlug.Trim();
if (await db.Candidates.AnyAsync(item =>
item.SeasonId == seasonId
&& item.CategoryId == request.CategoryId
&& (item.DisplayName.ToLower() == normalizedDisplayName.ToLower()
|| item.ChannelSlug.ToLower() == normalizedChannelSlug.ToLower())))
{
return Results.BadRequest(new { message = "A candidate with the same display name or channel slug already exists in this category." });
}
var candidate = new Candidate
{
SeasonId = seasonId,
CategoryId = request.CategoryId,
DisplayName = normalizedDisplayName,
ChannelSlug = normalizedChannelSlug,
Platform = request.Platform.Trim(),
};
db.Candidates.Add(candidate);
adminAuditService.AddEntry(
session.TwitchUserId,
"candidate.create",
"candidate",
request.DisplayName.Trim(),
$"Kandidat {request.DisplayName.Trim()} wurde angelegt.",
new { seasonId, request.CategoryId, request.Platform },
RequestMetadataReader.Read(context));
await db.SaveChangesAsync(context.RequestAborted);
return Results.Ok(new { saved = true, candidateId = candidate.Id });
}
private static async Task<IResult> UpdateCandidate(
HttpContext context,
int candidateId,
UpsertCandidateRequest request,
AwardsDbContext db,
IAdminAuditService adminAuditService)
{
var session = AdminEndpointConventions.CurrentSession(context);
var validationError = ValidateCandidateRequest(request);
if (validationError is not null)
{
return validationError;
}
var candidate = await db.Candidates.FirstOrDefaultAsync(item => item.Id == candidateId);
if (candidate is null)
{
return Results.NotFound();
}
var targetCategory = await db.Categories.FirstOrDefaultAsync(item =>
item.Id == request.CategoryId && item.SeasonId == candidate.SeasonId);
if (targetCategory is null)
{
return Results.BadRequest(new { message = "The selected category does not exist in this season." });
}
var normalizedDisplayName = request.DisplayName.Trim();
var normalizedChannelSlug = request.ChannelSlug.Trim();
if (await db.Candidates.AnyAsync(item =>
item.SeasonId == candidate.SeasonId
&& item.CategoryId == request.CategoryId
&& item.Id != candidateId
&& (item.DisplayName.ToLower() == normalizedDisplayName.ToLower()
|| item.ChannelSlug.ToLower() == normalizedChannelSlug.ToLower())))
{
return Results.BadRequest(new { message = "A candidate with the same display name or channel slug already exists in this category." });
}
candidate.CategoryId = request.CategoryId;
candidate.DisplayName = normalizedDisplayName;
candidate.ChannelSlug = normalizedChannelSlug;
candidate.Platform = request.Platform.Trim();
adminAuditService.AddEntry(
session.TwitchUserId,
"candidate.update",
"candidate",
candidate.Id.ToString(),
$"Kandidat {request.DisplayName.Trim()} wurde aktualisiert.",
new { request.CategoryId, request.Platform },
RequestMetadataReader.Read(context));
await db.SaveChangesAsync(context.RequestAborted);
return Results.Ok(new { saved = true, candidateId = candidate.Id });
}
private static async Task<IResult> DeleteCandidate(
HttpContext context,
int candidateId,
AwardsDbContext db,
IAdminAuditService adminAuditService)
{
var session = AdminEndpointConventions.CurrentSession(context);
var candidate = await db.Candidates.FirstOrDefaultAsync(item => item.Id == candidateId);
if (candidate is null)
{
return Results.NotFound();
}
db.Candidates.Remove(candidate);
adminAuditService.AddEntry(
session.TwitchUserId,
"candidate.delete",
"candidate",
candidate.Id.ToString(),
$"Kandidat {candidate.DisplayName} wurde gelöscht.",
new { candidate.CategoryId, candidate.Platform },
RequestMetadataReader.Read(context));
await db.SaveChangesAsync(context.RequestAborted);
return Results.Ok(new { deleted = true, candidateId });
}
}