150 lines
5.6 KiB
C#
150 lines
5.6 KiB
C#
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 });
|
|
}
|
|
}
|