Skip to content

Commit

Permalink
Initiative Dashboard and start on WorkItem Queues
Browse files Browse the repository at this point in the history
  • Loading branch information
CorruptComputer committed Dec 29, 2024
1 parent 7c2b833 commit b4e428a
Show file tree
Hide file tree
Showing 93 changed files with 1,263 additions and 620 deletions.
3 changes: 0 additions & 3 deletions Core/Bones.Database/BonesDatabaseModule.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
using Autofac;
using Bones.Database.Models;
using Bones.Shared.Backend.PipelineBehaviors;
using Bones.Shared.Exceptions;
using MediatR.Extensions.Autofac.DependencyInjection;
using MediatR.Extensions.Autofac.DependencyInjection.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

Expand Down
4 changes: 1 addition & 3 deletions Core/Bones.Database/Migrations/20241003032709_Initial.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;

#nullable disable
Expand Down
3 changes: 1 addition & 2 deletions Core/Bones.Database/Migrations/20241003042835_Rename.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using Bones.Database.DbSets.AccountManagement;

namespace Bones.Database.Operations.AccountManagement;

/// <summary>
/// Sets the email confirmed date time on the user
/// </summary>
/// <param name="User"></param>
/// <param name="ConfirmedDateTime"></param>
public sealed record SetEmailConfirmedDateTimeDbCommand(BonesUser User, DateTimeOffset ConfirmedDateTime) : IRequest<CommandResponse>;

internal sealed class SetEmailConfirmedDateTimeDbCommandValidator : AbstractValidator<SetEmailConfirmedDateTimeDbCommand>
{
public SetEmailConfirmedDateTimeDbCommandValidator()
{
RuleFor(x => x.User).NotNull().Custom((user, ctx) =>
{
if (user.EmailConfirmed)
{
ctx.AddFailure("User", "User already has email confirmed");
}
});

RuleFor(x => x.ConfirmedDateTime).NotNull();
}
}

internal sealed class SetEmailConfirmedDateTimeDbHandler(BonesDbContext dbContext) : IRequestHandler<SetEmailConfirmedDateTimeDbCommand, CommandResponse>
{
public async Task<CommandResponse> Handle(SetEmailConfirmedDateTimeDbCommand request, CancellationToken cancellationToken)
{
request.User.EmailConfirmed = true;
request.User.EmailConfirmedDateTime = request.ConfirmedDateTime;
dbContext.Users.Update(request.User);
await dbContext.SaveChangesAsync(cancellationToken);

return CommandResponse.Pass();
}
}

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using Bones.Database.DbSets.OrganizationManagement;

namespace Bones.Database.Operations.OrganizationManagement;

/// <summary>
/// DB Query to get the specified organization.
/// </summary>
/// <param name="OrganizationId"></param>
public sealed record GetOrganizationByIdDbQuery(Guid OrganizationId) : IRequest<QueryResponse<BonesOrganization>>;

internal sealed class GetOrganizationByIdDbQueryValidator : AbstractValidator<GetOrganizationByIdDbQuery>
{
public override Task<ValidationResult> ValidateAsync(ValidationContext<GetOrganizationByIdDbQuery> context, CancellationToken cancellation = new())
{
RuleFor(x => x.OrganizationId).NotNull().NotEqual(Guid.Empty);

return base.ValidateAsync(context, cancellation);
}
}

internal sealed class GetOrganizationByIdDbHandler(BonesDbContext dbContext) : IRequestHandler<GetOrganizationByIdDbQuery, QueryResponse<BonesOrganization>>
{
public async Task<QueryResponse<BonesOrganization>> Handle(GetOrganizationByIdDbQuery request, CancellationToken cancellationToken)
{
BonesOrganization? organization = await dbContext.Organizations.FirstOrDefaultAsync(x => x.Id == request.OrganizationId, cancellationToken);

if (organization is null)
{
return QueryResponse<BonesOrganization>.Fail("Organization not found");
}

return organization;
}
}

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System;
using Bones.Database.DbSets.ProjectManagement;

namespace Bones.Database.Operations.ProjectManagement.Initiatives;

/// <summary>
/// DB Query for getting an initiative
/// </summary>
/// <param name="InitiativeId">Internal ID of the initiative</param>
public record GetInitiativesByIdDbQuery(Guid InitiativeId) : IRequest<QueryResponse<Initiative>>;

internal sealed class GetInitiativesByIdQueryDbValidator : AbstractValidator<GetInitiativesByIdDbQuery>
{

}

internal sealed class GetInitiativesByIdDbHandler(BonesDbContext dbContext) : IRequestHandler<GetInitiativesByIdDbQuery, QueryResponse<Initiative>>
{
public async Task<QueryResponse<Initiative>> Handle(GetInitiativesByIdDbQuery request, CancellationToken cancellationToken)
{
return await dbContext.Initiatives
.Include(i => i.Queues)
.Include(i => i.Project)
.FirstOrDefaultAsync(i => i.Id == request.InitiativeId, cancellationToken);
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
using Bones.Database.DbSets.AccountManagement;
using Bones.Database.DbSets.OrganizationManagement;
using Bones.Database.DbSets.ProjectManagement;
using Bones.Database.Operations.OrganizationManagement.GetOrganizationByIdDb;
using Bones.Database.Operations.ProjectManagement.Projects;
using Bones.Shared.Backend.Enums;
using Bones.Shared.Consts;

namespace Bones.Database.Operations.ProjectManagement.Initiatives;

Expand All @@ -23,6 +17,9 @@ internal sealed class GetInitiativesByProjectDbHandler(BonesDbContext dbContext)
{
public async Task<QueryResponse<List<Initiative>>> Handle(GetInitiativesByProjectDbQuery request, CancellationToken cancellationToken)
{
return await dbContext.Initiatives.Where(i => i.Project.Id == request.ProjectId).ToListAsync(cancellationToken);
return await dbContext.Initiatives
.Include(i => i.Queues)
.Where(i => i.Project.Id == request.ProjectId)
.ToListAsync(cancellationToken);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using Bones.Database.DbSets.WorkItemManagement;

namespace Bones.Database.Operations.WorkItemManagement.WorkItemQueues;

/// <summary>
/// Backend query for getting work item queues that belong to an initiative.
/// </summary>
/// <param name="InitiativeId">Internal ID of the initiative</param>
public record GetWorkItemQueuesByInitiativeDbQuery(Guid InitiativeId) : IRequest<QueryResponse<List<WorkItemQueue>>>;

internal sealed class GetWorkItemQueuesByInitiativeDbQueryValidator : AbstractValidator<GetWorkItemQueuesByInitiativeDbQuery>
{

}

internal sealed class GetWorkItemQueuesByInitiativeDbHandler(BonesDbContext dbContext) : IRequestHandler<GetWorkItemQueuesByInitiativeDbQuery, QueryResponse<List<WorkItemQueue>>>
{
public async Task<QueryResponse<List<WorkItemQueue>>> Handle(GetWorkItemQueuesByInitiativeDbQuery request, CancellationToken cancellationToken)
{
return (await dbContext.Initiatives.Include(i => i.Queues).FirstOrDefaultAsync(i => i.Id == request.InitiativeId, cancellationToken))?.Queues
// Should only really happen if the initiative doesn't exist, but that would have been checked in the Logic layer before here anyways
?? [];
}
}
3 changes: 0 additions & 3 deletions Core/Bones.Logic/BonesBackendModule.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
using Autofac;
using Bones.Logic.Models;
using Bones.Shared.Backend.PipelineBehaviors;
using Bones.Shared.Exceptions;
using MediatR.Extensions.Autofac.DependencyInjection;
using MediatR.Extensions.Autofac.DependencyInjection.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,33 @@
using Bones.Database.DbSets.AccountManagement;
using Bones.Database.Operations.AccountManagement.SetEmailConfirmedDateTimeDb;
using Bones.Database.Operations.AccountManagement;
using Bones.Shared.Extensions;
using Microsoft.AspNetCore.Identity;

namespace Bones.Logic.Features.Accounts.ConfirmEmail;
namespace Bones.Logic.Features.Accounts;

/// <summary>
/// Backend request for confirming a users email
/// </summary>
/// <param name="UserId"></param>
/// <param name="Code"></param>
/// <param name="ChangedEmail"></param>
public sealed record ConfirmEmailQuery(Guid UserId, string Code, string? ChangedEmail) : IRequest<QueryResponse<IdentityResult>>;

internal class ConfirmEmailQueryValidator : AbstractValidator<ConfirmEmailQuery>
{
public ConfirmEmailQueryValidator()
{
RuleFor(x => x.UserId).NotNull().NotEmpty();
RuleFor(x => x.Code).NotNull().NotEmpty();
RuleFor(x => x.ChangedEmail).Custom(async (email, ctx) =>
{
if (email != null && !await email.IsValidEmailAsync())
{
ctx.AddFailure("ChangedEmail", "Email is not valid");
}
});
}
}

internal class ConfirmEmailHandler(UserManager<BonesUser> userManager, ISender sender) : IRequestHandler<ConfirmEmailQuery, QueryResponse<IdentityResult>>
{
Expand Down Expand Up @@ -41,7 +65,7 @@ public async Task<QueryResponse<IdentityResult>> Handle(ConfirmEmailQuery reques

if (result.Succeeded)
{
// So when we update the email, we need to update the username.
// When we update the email, we need to update the username to match.
result = await userManager.SetUserNameAsync(user, request.ChangedEmail);
}
}
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
using System.Security.Claims;
using Bones.Database.DbSets.AccountManagement;
using Microsoft.AspNetCore.Identity;

namespace Bones.Logic.Features.Accounts.GetUserByClaimsPrincipal;
namespace Bones.Logic.Features.Accounts;

/// <summary>
/// Backend request for getting a <see cref="BonesUser" /> by a <see cref="ClaimsPrincipal" />.
/// </summary>
/// <param name="ClaimsPrincipal"></param>
public sealed record GetUserByClaimsPrincipalQuery(ClaimsPrincipal? ClaimsPrincipal) : IRequest<QueryResponse<BonesUser>>;

internal sealed class GetUserByClaimsPrincipalQueryValidator : AbstractValidator<GetUserByClaimsPrincipalQuery>
{
public GetUserByClaimsPrincipalQueryValidator()
{
RuleFor(x => x.ClaimsPrincipal).NotNull();
}
}

internal sealed class GetUserByClaimsPrincipalHandler(UserManager<BonesUser> userManager) : IRequestHandler<GetUserByClaimsPrincipalQuery, QueryResponse<BonesUser>>
{
Expand Down

This file was deleted.

This file was deleted.

Loading

0 comments on commit b4e428a

Please sign in to comment.