From f2c4ead2743a5c69d57610c1667aa5998677e822 Mon Sep 17 00:00:00 2001 From: dorisjenny27 Date: Sat, 31 Aug 2024 09:56:49 +0100 Subject: [PATCH 01/22] feat: implement blog management in graphql --- src/Hng.Graphql/Mutations.BillingPlans.cs | 1 - src/Hng.Graphql/Mutations.Blog.cs | 32 +++++++++++++++++++++++ src/Hng.Graphql/Queries.Blog.cs | 25 ++++++++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 src/Hng.Graphql/Mutations.Blog.cs create mode 100644 src/Hng.Graphql/Queries.Blog.cs diff --git a/src/Hng.Graphql/Mutations.BillingPlans.cs b/src/Hng.Graphql/Mutations.BillingPlans.cs index f650b59c..e739d65e 100644 --- a/src/Hng.Graphql/Mutations.BillingPlans.cs +++ b/src/Hng.Graphql/Mutations.BillingPlans.cs @@ -1,6 +1,5 @@ using Hng.Application.Features.BillingPlans.Commands; using Hng.Application.Features.BillingPlans.Dtos; -using Hng.Application.Features.BillingPlans.Queries; using Hng.Application.Shared.Dtos; using HotChocolate.Authorization; using MediatR; diff --git a/src/Hng.Graphql/Mutations.Blog.cs b/src/Hng.Graphql/Mutations.Blog.cs new file mode 100644 index 00000000..15d12aa3 --- /dev/null +++ b/src/Hng.Graphql/Mutations.Blog.cs @@ -0,0 +1,32 @@ +using Hng.Application.Features.Blogs.Commands; +using Hng.Application.Features.Blogs.Dtos; +using HotChocolate.Authorization; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace Hng.Graphql +{ + public partial class Mutations + { + [Authorize] + public async Task CreateBlog(CreateBlogDto body, [FromServices] IMediator mediator) + { + var command = new CreateBlogCommand(body); + return await mediator.Send(command); + } + + [Authorize] + public async Task DeleteBlogById(Guid id, [FromServices] IMediator mediator) + { + var command = (new DeleteBlogByIdCommand(id)); + return await mediator.Send(command); + } + + [Authorize] + public async Task UpdateBlog(Guid id, UpdateBlogDto updateBlogDto, [FromServices] IMediator mediator) + { + var command = new UpdateBlogCommand(updateBlogDto, id); + return await mediator.Send(command); + } + } +} \ No newline at end of file diff --git a/src/Hng.Graphql/Queries.Blog.cs b/src/Hng.Graphql/Queries.Blog.cs new file mode 100644 index 00000000..17d2214c --- /dev/null +++ b/src/Hng.Graphql/Queries.Blog.cs @@ -0,0 +1,25 @@ +using Hng.Application.Features.Blogs.Dtos; +using Hng.Application.Features.Blogs.Queries; +using HotChocolate.Authorization; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace Hng.Graphql +{ + public partial class Queries + { + [Authorize] + public async Task GetBlogById(Guid id, [FromServices] IMediator mediator) + { + var query = new GetBlogByIdQuery(id); + return await mediator.Send(query); + } + + [Authorize] + public async Task> GetBlogs([FromServices] IMediator mediator) + { + var blogs = new GetBlogsQuery(); + return await mediator.Send(blogs); + } + } +} \ No newline at end of file From 8b16fd41df15e186650213cca19ede2f07981874 Mon Sep 17 00:00:00 2001 From: dorisjenny27 Date: Sat, 31 Aug 2024 11:14:15 +0100 Subject: [PATCH 02/22] feat: implement category management in graphql --- src/Hng.Graphql/Mutations.Categories.cs | 27 +++++++++++++++++++++++++ src/Hng.Graphql/Queries.Categories.cs | 26 ++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 src/Hng.Graphql/Mutations.Categories.cs create mode 100644 src/Hng.Graphql/Queries.Categories.cs diff --git a/src/Hng.Graphql/Mutations.Categories.cs b/src/Hng.Graphql/Mutations.Categories.cs new file mode 100644 index 00000000..676c6381 --- /dev/null +++ b/src/Hng.Graphql/Mutations.Categories.cs @@ -0,0 +1,27 @@ +using Hng.Application.Features.Categories.Commands; +using Hng.Application.Features.Categories.Dtos; +using Hng.Application.Shared.Dtos; +using HotChocolate.Authorization; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace Hng.Graphql +{ + public partial class Mutations + { + [Authorize] + public async Task> CreateCategory(CreateCategoryDto createCategoryDto, [FromServices] IMediator mediator) + { + var command = new CreateCategoryCommand(createCategoryDto.Name,createCategoryDto.Description, createCategoryDto.Slug); + return await mediator.Send(command); + } + + [Authorize] + public async Task> DeleteCategory(Guid id, [FromServices] IMediator mediator) + { + var command = new DeleteCategoryCommand(id); + return await mediator.Send(command); + } + + } +} \ No newline at end of file diff --git a/src/Hng.Graphql/Queries.Categories.cs b/src/Hng.Graphql/Queries.Categories.cs new file mode 100644 index 00000000..93192bf8 --- /dev/null +++ b/src/Hng.Graphql/Queries.Categories.cs @@ -0,0 +1,26 @@ +using Hng.Application.Features.Categories.Dtos; +using Hng.Application.Features.Categories.Queries; +using Hng.Application.Shared.Dtos; +using HotChocolate.Authorization; +using Microsoft.AspNetCore.Mvc; +using MediatR; + +namespace Hng.Graphql +{ + public partial class Queries + { + [Authorize] + public async Task> GetCategory(Guid id, [FromServices] IMediator mediator) + { + var query = new GetCategoryByIdQuery(id); + return await mediator.Send(query); + } + + [Authorize] + public async Task>> GetAllCategories(GetAllCategoriesQueryParams queryParams, [FromServices] IMediator mediator) + { + var query = new GetAllCategoriesQuery(queryParams); + return await mediator.Send(query); + } + } +} From ad3c9e49cd09a3f05bd7e79e931ff5581459e718 Mon Sep 17 00:00:00 2001 From: dorisjenny27 Date: Sat, 31 Aug 2024 11:21:30 +0100 Subject: [PATCH 03/22] feat: implement category management in graphql --- src/Hng.Graphql/Mutations.Categories.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Hng.Graphql/Mutations.Categories.cs b/src/Hng.Graphql/Mutations.Categories.cs index 676c6381..4baed271 100644 --- a/src/Hng.Graphql/Mutations.Categories.cs +++ b/src/Hng.Graphql/Mutations.Categories.cs @@ -12,7 +12,7 @@ public partial class Mutations [Authorize] public async Task> CreateCategory(CreateCategoryDto createCategoryDto, [FromServices] IMediator mediator) { - var command = new CreateCategoryCommand(createCategoryDto.Name,createCategoryDto.Description, createCategoryDto.Slug); + var command = new CreateCategoryCommand(createCategoryDto.Name, createCategoryDto.Description, createCategoryDto.Slug); return await mediator.Send(command); } From 96d4b4472157a059bd2f2b667c10d30b09112079 Mon Sep 17 00:00:00 2001 From: dorisjenny27 Date: Sat, 31 Aug 2024 11:47:19 +0100 Subject: [PATCH 04/22] feat: implement comment management in graphql --- src/Hng.Graphql/Mutations.Comment.cs | 18 ++++++++++++++++++ src/Hng.Graphql/Queries.Comment.cs | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 src/Hng.Graphql/Mutations.Comment.cs create mode 100644 src/Hng.Graphql/Queries.Comment.cs diff --git a/src/Hng.Graphql/Mutations.Comment.cs b/src/Hng.Graphql/Mutations.Comment.cs new file mode 100644 index 00000000..39e806f8 --- /dev/null +++ b/src/Hng.Graphql/Mutations.Comment.cs @@ -0,0 +1,18 @@ +using Hng.Application.Features.Comments.Commands; +using Hng.Application.Features.Comments.Dtos; +using HotChocolate.Authorization; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace Hng.Graphql +{ + public partial class Mutations + { + [Authorize] + public async Task CreateComment(Guid blogId, CreateCommentDto body, [FromServices] IMediator mediator) + { + var command = new CreateCommentCommand(body, blogId); + return await mediator.Send(command); + } + } +} \ No newline at end of file diff --git a/src/Hng.Graphql/Queries.Comment.cs b/src/Hng.Graphql/Queries.Comment.cs new file mode 100644 index 00000000..a6b024bc --- /dev/null +++ b/src/Hng.Graphql/Queries.Comment.cs @@ -0,0 +1,18 @@ +using Hng.Application.Features.Comments.Dtos; +using Hng.Application.Features.Comments.Queries; +using HotChocolate.Authorization; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace Hng.Graphql +{ + public partial class Queries + { + [Authorize] + public async Task> GetCommentsByBlogId(Guid blogId, [FromServices] IMediator mediator) + { + var query = new GetCommentsByBlogIdQuery(blogId); + return await mediator.Send(query); + } + } +} \ No newline at end of file From ae58b59ca56bd96e5fbad6c784103d701d317abf Mon Sep 17 00:00:00 2001 From: dorisjenny27 Date: Sat, 31 Aug 2024 12:35:15 +0100 Subject: [PATCH 05/22] feat: implement contact us endpoints in graphql --- src/Hng.Graphql/Mutations.ContactUs.cs | 25 +++++++++++++++++++++++++ src/Hng.Graphql/Queries.ContactUs.cs | 18 ++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 src/Hng.Graphql/Mutations.ContactUs.cs create mode 100644 src/Hng.Graphql/Queries.ContactUs.cs diff --git a/src/Hng.Graphql/Mutations.ContactUs.cs b/src/Hng.Graphql/Mutations.ContactUs.cs new file mode 100644 index 00000000..9f47242b --- /dev/null +++ b/src/Hng.Graphql/Mutations.ContactUs.cs @@ -0,0 +1,25 @@ +using Hng.Application.Features.ContactsUs.Command; +using Hng.Application.Features.ContactsUs.Dtos; +using HotChocolate.Authorization; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace Hng.Graphql +{ + public partial class Mutations + { + [Authorize] + public async Task> CreateContactMessage(ContactUsRequestDto contactUsRequest, [FromServices] IMediator mediator) + { + var command = new CreateContactUsCommand(contactUsRequest); + return await mediator.Send(command); + } + + [Authorize] + public async Task> DeleteContactMessage(Guid id, [FromServices] IMediator mediator) + { + var command = new DeleteContactUsCommand(id); + return await mediator.Send(command); + } + } +} \ No newline at end of file diff --git a/src/Hng.Graphql/Queries.ContactUs.cs b/src/Hng.Graphql/Queries.ContactUs.cs new file mode 100644 index 00000000..eda96d65 --- /dev/null +++ b/src/Hng.Graphql/Queries.ContactUs.cs @@ -0,0 +1,18 @@ +using Hng.Application.Features.ContactsUs.Dtos; +using Hng.Application.Features.ContactsUs.Queries; +using HotChocolate.Authorization; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace Hng.Graphql +{ + public partial class Queries + { + [Authorize] + public async Task>> GetAllContactMessages([FromServices] IMediator mediator) + { + var query = new GetAllContactUsQuery(); + return await mediator.Send(query); + } + } +} \ No newline at end of file From bbadf0854b1de3af8a32f757f372c9a8c721d30f Mon Sep 17 00:00:00 2001 From: dorisjenny27 Date: Sat, 31 Aug 2024 12:51:25 +0100 Subject: [PATCH 06/22] feat: implement contact us endpoints in graphql --- src/Hng.Graphql/Mutations.Subscriptions.cs | 12 ++++++++++++ src/Hng.Graphql/Queries.Subscriptions.cs | 12 ++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 src/Hng.Graphql/Mutations.Subscriptions.cs create mode 100644 src/Hng.Graphql/Queries.Subscriptions.cs diff --git a/src/Hng.Graphql/Mutations.Subscriptions.cs b/src/Hng.Graphql/Mutations.Subscriptions.cs new file mode 100644 index 00000000..51dc1355 --- /dev/null +++ b/src/Hng.Graphql/Mutations.Subscriptions.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Hng.Graphql +{ + public class Mutations + { + } +} diff --git a/src/Hng.Graphql/Queries.Subscriptions.cs b/src/Hng.Graphql/Queries.Subscriptions.cs new file mode 100644 index 00000000..66243c0e --- /dev/null +++ b/src/Hng.Graphql/Queries.Subscriptions.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Hng.Graphql +{ + public class Queries + { + } +} From 0d2e3ea6473055cd8d218a3b00037ccf9208a2ef Mon Sep 17 00:00:00 2001 From: dorisjenny27 Date: Sat, 31 Aug 2024 13:26:59 +0100 Subject: [PATCH 07/22] feat: implement subscription endpoints in graphql --- src/Hng.Graphql/Mutations.Subscriptions.cs | 30 +++++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/src/Hng.Graphql/Mutations.Subscriptions.cs b/src/Hng.Graphql/Mutations.Subscriptions.cs index 51dc1355..6bd055af 100644 --- a/src/Hng.Graphql/Mutations.Subscriptions.cs +++ b/src/Hng.Graphql/Mutations.Subscriptions.cs @@ -1,12 +1,28 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using Hng.Application.Features.Subscriptions.Commands; +using Hng.Application.Features.Subscriptions.Dtos.Requests; +using Hng.Application.Features.Subscriptions.Dtos.Responses; +using HotChocolate.Authorization; +using MediatR; +using Microsoft.AspNetCore.Mvc; + namespace Hng.Graphql { - public class Mutations + public partial class Mutations { + [Authorize] + public async Task SubscribeFreePlan(SubscribeFreePlan command, [FromServices] IMediator mediator) + { + + + return await mediator.Send(command); + } + + [Authorize] + public async Task ActivateSubscription(Guid subscriptionId, [FromServices] IMediator mediator) + { + var command = new ActivateSubscriptionCommand(subscriptionId); + return await mediator.Send(command); + } } -} +} \ No newline at end of file From 92a893bce35b52f820929deda4053add9332310a Mon Sep 17 00:00:00 2001 From: dorisjenny27 Date: Sat, 31 Aug 2024 13:30:41 +0100 Subject: [PATCH 08/22] feat: implement subscription endpoints in graphql --- src/Hng.Graphql/Mutations.Subscriptions.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Hng.Graphql/Mutations.Subscriptions.cs b/src/Hng.Graphql/Mutations.Subscriptions.cs index 6bd055af..481b79c7 100644 --- a/src/Hng.Graphql/Mutations.Subscriptions.cs +++ b/src/Hng.Graphql/Mutations.Subscriptions.cs @@ -10,13 +10,15 @@ namespace Hng.Graphql { public partial class Mutations { - [Authorize] - public async Task SubscribeFreePlan(SubscribeFreePlan command, [FromServices] IMediator mediator) - { + //[Authorize] + //public async Task SubscribeFreePlan(SubscribeFreePlan command, [FromServices] IMediator mediator) + //{ + // //var command = new SubscribeFreePlan(); + // // return await mediator.Send(command); - return await mediator.Send(command); - } + // // return await mediator.Send(command); + //} [Authorize] public async Task ActivateSubscription(Guid subscriptionId, [FromServices] IMediator mediator) From 3780c7aa37171f980a1e2c2062ea523e7cf87cc9 Mon Sep 17 00:00:00 2001 From: dorisjenny27 Date: Sat, 31 Aug 2024 13:42:42 +0100 Subject: [PATCH 09/22] subscriptions --- src/Hng.Graphql/Queries.Subscriptions.cs | 37 +++++++++++++++++++----- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/src/Hng.Graphql/Queries.Subscriptions.cs b/src/Hng.Graphql/Queries.Subscriptions.cs index 66243c0e..c389a173 100644 --- a/src/Hng.Graphql/Queries.Subscriptions.cs +++ b/src/Hng.Graphql/Queries.Subscriptions.cs @@ -1,12 +1,35 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using Hng.Application.Features.Subscriptions.Dtos.Requests; +using Hng.Application.Features.Subscriptions.Dtos.Responses; +using Hng.Application.Features.Subscriptions.Queries; +using Hng.Application.Shared.Dtos; +using HotChocolate.Authorization; +using MediatR; +using Microsoft.AspNetCore.Mvc; + namespace Hng.Graphql { - public class Queries + public partial class Queries { + [Authorize] + public async Task GetSubscriptionByOrganizationId(Guid organizationId, [FromServices] IMediator mediator) + { + var response = new GetSubscriptionByOrganizationIdQuery(organizationId); + return await mediator.Send(response); + } + + [Authorize] + public async Task GetSubscriptionByUserId(Guid userId, [FromServices] IMediator mediator) + { + var response = new GetSubscriptionByUserIdQuery(userId); + return await mediator.Send(response); + } + + [Authorize] + public async Task> GetSubscriptions(GetSubscriptionsQueryParameters parameters, [FromServices] IMediator mediator) + { + var subscriptions = new GetSubscriptionsQuery(parameters); + return await mediator.Send(subscriptions); + } } -} +} \ No newline at end of file From 17bb394896d05a48bf2cc862e726eabac776619e Mon Sep 17 00:00:00 2001 From: dorisjenny27 Date: Sat, 31 Aug 2024 13:44:44 +0100 Subject: [PATCH 10/22] feat: implement admin endpoints in graphql --- src/Hng.Graphql/Queries.Admin.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/Hng.Graphql/Queries.Admin.cs diff --git a/src/Hng.Graphql/Queries.Admin.cs b/src/Hng.Graphql/Queries.Admin.cs new file mode 100644 index 00000000..66243c0e --- /dev/null +++ b/src/Hng.Graphql/Queries.Admin.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Hng.Graphql +{ + public class Queries + { + } +} From fd9fab465e55ce01b143b523e565d4a9d1aeea90 Mon Sep 17 00:00:00 2001 From: dorisjenny27 Date: Sat, 31 Aug 2024 13:52:05 +0100 Subject: [PATCH 11/22] feat: implement admin endpoints in graphql --- src/Hng.Graphql/Queries.Admin.cs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/Hng.Graphql/Queries.Admin.cs b/src/Hng.Graphql/Queries.Admin.cs index 66243c0e..65b09c17 100644 --- a/src/Hng.Graphql/Queries.Admin.cs +++ b/src/Hng.Graphql/Queries.Admin.cs @@ -1,12 +1,17 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using Hng.Application.Features.SuperAdmin.Dto; +using Hng.Application.Features.SuperAdmin.Queries; +using Hng.Application.Shared.Dtos; +using MediatR; +using Microsoft.AspNetCore.Mvc; namespace Hng.Graphql { - public class Queries + public partial class Queries { + public async Task> GetUsersBySearch(UsersQueryParameters parameters, [FromServices] IMediator mediator) + { + var users = new GetUsersBySearchQuery(parameters); + return await mediator.Send(users); + } } -} +} \ No newline at end of file From 6b9a8fd03311278e393ab262a7bfcc9a8bbb8053 Mon Sep 17 00:00:00 2001 From: Godand Date: Sat, 31 Aug 2024 17:46:19 +0200 Subject: [PATCH 12/22] feat(graphql):Implement Authentication resolvers --- .../Mutations/Mutations.Authentication.cs | 73 +++++++++++++++++++ .../Mutations}/Mutations.BillingPlans.cs | 0 .../Mutations}/Mutations.Blog.cs | 0 .../Mutations}/Mutations.Categories.cs | 0 .../Mutations}/Mutations.EmailTemplate.cs | 0 .../{ => Features/Mutations}/Mutations.Faq.cs | 0 .../Queries/Queries.Authentication.cs | 20 +++++ .../Queries}/Queries.BillingPlans.cs | 0 .../{ => Features/Queries}/Queries.Blog.cs | 0 .../Queries}/Queries.Categories.cs | 0 .../Queries}/Queries.Dashboard.cs | 0 .../Queries}/Queries.EmailTemplate.cs | 0 .../{ => Features/Queries}/Queries.Faq.cs | 0 src/Hng.Graphql/Mutations.cs | 12 --- src/Hng.Graphql/Queries.cs | 7 +- 15 files changed, 94 insertions(+), 18 deletions(-) create mode 100644 src/Hng.Graphql/Features/Mutations/Mutations.Authentication.cs rename src/Hng.Graphql/{ => Features/Mutations}/Mutations.BillingPlans.cs (100%) rename src/Hng.Graphql/{ => Features/Mutations}/Mutations.Blog.cs (100%) rename src/Hng.Graphql/{ => Features/Mutations}/Mutations.Categories.cs (100%) rename src/Hng.Graphql/{ => Features/Mutations}/Mutations.EmailTemplate.cs (100%) rename src/Hng.Graphql/{ => Features/Mutations}/Mutations.Faq.cs (100%) create mode 100644 src/Hng.Graphql/Features/Queries/Queries.Authentication.cs rename src/Hng.Graphql/{ => Features/Queries}/Queries.BillingPlans.cs (100%) rename src/Hng.Graphql/{ => Features/Queries}/Queries.Blog.cs (100%) rename src/Hng.Graphql/{ => Features/Queries}/Queries.Categories.cs (100%) rename src/Hng.Graphql/{ => Features/Queries}/Queries.Dashboard.cs (100%) rename src/Hng.Graphql/{ => Features/Queries}/Queries.EmailTemplate.cs (100%) rename src/Hng.Graphql/{ => Features/Queries}/Queries.Faq.cs (100%) diff --git a/src/Hng.Graphql/Features/Mutations/Mutations.Authentication.cs b/src/Hng.Graphql/Features/Mutations/Mutations.Authentication.cs new file mode 100644 index 00000000..2564ee32 --- /dev/null +++ b/src/Hng.Graphql/Features/Mutations/Mutations.Authentication.cs @@ -0,0 +1,73 @@ +using Hng.Application.Features.UserManagement.Commands; +using Hng.Application.Features.UserManagement.Dtos; +using HotChocolate.Authorization; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace Hng.Graphql +{ + public partial class Mutations + { + public async Task> Login(UserLoginRequestDto loginRequest, [FromServices] IMediator mediator) + { + var command = new CreateUserLoginCommand(loginRequest); + return await mediator.Send(command); + } + + public async Task> GoogleLogin(GoogleLoginRequestDto googleLoginRequest, [FromServices] IMediator mediator) + { + var command = new GoogleLoginCommand(googleLoginRequest.IdToken); + return await mediator.Send(command); + } + + public async Task UserSignUp(UserSignUpDto body, [FromServices] IMediator mediator) + { + var command = new UserSignUpCommand(body); + return await mediator.Send(command); + } + + [Authorize] + public async Task ChangePassword([FromBody] ChangePasswordCommand command, [FromServices] IMediator mediator) + { + var response= await mediator.Send(command); + return response.Value; + } + + public async Task ForgotPassword([FromBody] ForgotPasswordRequestDto request, [FromServices] IMediator mediator) + { + var response= await mediator.Send(new ForgotPasswordDto(request.Email, false)); + return response.Value; + } + + public async Task ForgotPasswordMobile([FromBody] ForgotPasswordRequestDto request, [FromServices] IMediator mediator) + { + var response= await mediator.Send(new ForgotPasswordDto(request.Email, true)); + return response.Value; + } + + public async Task VerifyForgotPasswordCode([FromBody] VerifyForgotPasswordCodeDto request, [FromServices] IMediator mediator) + { + var response= await mediator.Send(request); + return response.Value; + } + + public async Task PasswordResetMobile([FromBody] PasswordResetMobileDto request, [FromServices] IMediator mediator) + { + var respone= await mediator.Send(new PasswordResetMobileCommand(request)); + return respone.Value; + } + + [Authorize] + public async Task PasswordReset([FromBody] PasswordResetDto request, [FromServices] IMediator mediator) + { + var response= await mediator.Send(request); + return response.Value; + } + + public async Task> FacebookLogin([FromBody] FacebookLoginRequestDto request, [FromServices] IMediator mediator) + { + var command = new FacebookLoginCommand(request.AccessToken); + return await mediator.Send(command); + } + } +} \ No newline at end of file diff --git a/src/Hng.Graphql/Mutations.BillingPlans.cs b/src/Hng.Graphql/Features/Mutations/Mutations.BillingPlans.cs similarity index 100% rename from src/Hng.Graphql/Mutations.BillingPlans.cs rename to src/Hng.Graphql/Features/Mutations/Mutations.BillingPlans.cs diff --git a/src/Hng.Graphql/Mutations.Blog.cs b/src/Hng.Graphql/Features/Mutations/Mutations.Blog.cs similarity index 100% rename from src/Hng.Graphql/Mutations.Blog.cs rename to src/Hng.Graphql/Features/Mutations/Mutations.Blog.cs diff --git a/src/Hng.Graphql/Mutations.Categories.cs b/src/Hng.Graphql/Features/Mutations/Mutations.Categories.cs similarity index 100% rename from src/Hng.Graphql/Mutations.Categories.cs rename to src/Hng.Graphql/Features/Mutations/Mutations.Categories.cs diff --git a/src/Hng.Graphql/Mutations.EmailTemplate.cs b/src/Hng.Graphql/Features/Mutations/Mutations.EmailTemplate.cs similarity index 100% rename from src/Hng.Graphql/Mutations.EmailTemplate.cs rename to src/Hng.Graphql/Features/Mutations/Mutations.EmailTemplate.cs diff --git a/src/Hng.Graphql/Mutations.Faq.cs b/src/Hng.Graphql/Features/Mutations/Mutations.Faq.cs similarity index 100% rename from src/Hng.Graphql/Mutations.Faq.cs rename to src/Hng.Graphql/Features/Mutations/Mutations.Faq.cs diff --git a/src/Hng.Graphql/Features/Queries/Queries.Authentication.cs b/src/Hng.Graphql/Features/Queries/Queries.Authentication.cs new file mode 100644 index 00000000..a0af88a9 --- /dev/null +++ b/src/Hng.Graphql/Features/Queries/Queries.Authentication.cs @@ -0,0 +1,20 @@ +using Hng.Application.Features.UserManagement.Dtos; +using Hng.Application.Features.UserManagement.Queries; +using HotChocolate.Authorization; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace Hng.Graphql +{ + public partial class Queries + { + [Authorize] + public async Task GetLoggedInUsersDetails([FromServices] IMediator mediator) + { + var query = new GetLoggedInUserDetailsQuery(); + return await mediator.Send(query); + } + + + } +} diff --git a/src/Hng.Graphql/Queries.BillingPlans.cs b/src/Hng.Graphql/Features/Queries/Queries.BillingPlans.cs similarity index 100% rename from src/Hng.Graphql/Queries.BillingPlans.cs rename to src/Hng.Graphql/Features/Queries/Queries.BillingPlans.cs diff --git a/src/Hng.Graphql/Queries.Blog.cs b/src/Hng.Graphql/Features/Queries/Queries.Blog.cs similarity index 100% rename from src/Hng.Graphql/Queries.Blog.cs rename to src/Hng.Graphql/Features/Queries/Queries.Blog.cs diff --git a/src/Hng.Graphql/Queries.Categories.cs b/src/Hng.Graphql/Features/Queries/Queries.Categories.cs similarity index 100% rename from src/Hng.Graphql/Queries.Categories.cs rename to src/Hng.Graphql/Features/Queries/Queries.Categories.cs diff --git a/src/Hng.Graphql/Queries.Dashboard.cs b/src/Hng.Graphql/Features/Queries/Queries.Dashboard.cs similarity index 100% rename from src/Hng.Graphql/Queries.Dashboard.cs rename to src/Hng.Graphql/Features/Queries/Queries.Dashboard.cs diff --git a/src/Hng.Graphql/Queries.EmailTemplate.cs b/src/Hng.Graphql/Features/Queries/Queries.EmailTemplate.cs similarity index 100% rename from src/Hng.Graphql/Queries.EmailTemplate.cs rename to src/Hng.Graphql/Features/Queries/Queries.EmailTemplate.cs diff --git a/src/Hng.Graphql/Queries.Faq.cs b/src/Hng.Graphql/Features/Queries/Queries.Faq.cs similarity index 100% rename from src/Hng.Graphql/Queries.Faq.cs rename to src/Hng.Graphql/Features/Queries/Queries.Faq.cs diff --git a/src/Hng.Graphql/Mutations.cs b/src/Hng.Graphql/Mutations.cs index b7dfc234..cd6299a9 100644 --- a/src/Hng.Graphql/Mutations.cs +++ b/src/Hng.Graphql/Mutations.cs @@ -1,7 +1,5 @@ using Hng.Application.Features.Roles.Command; using Hng.Application.Features.Roles.Dto; -using Hng.Application.Features.UserManagement.Commands; -using Hng.Application.Features.UserManagement.Dtos; using HotChocolate.Authorization; using MediatR; using Microsoft.AspNetCore.Mvc; @@ -10,17 +8,7 @@ namespace Hng.Graphql { public partial class Mutations { - public async Task> Login(UserLoginRequestDto loginRequest, [FromServices] IMediator mediator) - { - var command = new CreateUserLoginCommand(loginRequest); - return await mediator.Send(command); - } - public async Task> GoogleLogin(GoogleLoginRequestDto googleLoginRequest, [FromServices] IMediator mediator) - { - var command = new GoogleLoginCommand(googleLoginRequest.IdToken); - return await mediator.Send(command); - } [Authorize] public async Task CreateRoleInOrganisation(Guid orgId, CreateRoleRequestDto request, [FromServices] IMediator mediator) diff --git a/src/Hng.Graphql/Queries.cs b/src/Hng.Graphql/Queries.cs index 76c1357b..f5bc18ac 100644 --- a/src/Hng.Graphql/Queries.cs +++ b/src/Hng.Graphql/Queries.cs @@ -10,12 +10,7 @@ namespace Hng.Graphql { public partial class Queries { - [Authorize] - public async Task GetLoggedInUsersDetails([FromServices] IMediator mediator) - { - var query = new GetLoggedInUserDetailsQuery(); - return await mediator.Send(query); - } + [Authorize] public async Task> GetRolesInOrganisation(Guid orgId, [FromServices] IMediator mediator) From 644f4563c6b4708d9f723d71923affbeb364743f Mon Sep 17 00:00:00 2001 From: Godand Date: Sat, 31 Aug 2024 18:06:37 +0200 Subject: [PATCH 13/22] feat(graphql): Implement HelpCenterTopics Resolvers --- .../Mutations/Mutations.Authentication.cs | 12 +++---- .../Mutations/Mutations.HelpCenterTopics.cs | 32 +++++++++++++++++++ .../Queries/Queries.HelpCenterTopics.cs | 28 ++++++++++++++++ src/Hng.Graphql/Queries.cs | 2 +- .../Controllers/HelpCenterTopicController.cs | 2 ++ 5 files changed, 69 insertions(+), 7 deletions(-) create mode 100644 src/Hng.Graphql/Features/Mutations/Mutations.HelpCenterTopics.cs create mode 100644 src/Hng.Graphql/Features/Queries/Queries.HelpCenterTopics.cs diff --git a/src/Hng.Graphql/Features/Mutations/Mutations.Authentication.cs b/src/Hng.Graphql/Features/Mutations/Mutations.Authentication.cs index 2564ee32..8db56968 100644 --- a/src/Hng.Graphql/Features/Mutations/Mutations.Authentication.cs +++ b/src/Hng.Graphql/Features/Mutations/Mutations.Authentication.cs @@ -29,38 +29,38 @@ public async Task UserSignUp(UserSignUpDto body, [FromServices] [Authorize] public async Task ChangePassword([FromBody] ChangePasswordCommand command, [FromServices] IMediator mediator) { - var response= await mediator.Send(command); + var response = await mediator.Send(command); return response.Value; } public async Task ForgotPassword([FromBody] ForgotPasswordRequestDto request, [FromServices] IMediator mediator) { - var response= await mediator.Send(new ForgotPasswordDto(request.Email, false)); + var response = await mediator.Send(new ForgotPasswordDto(request.Email, false)); return response.Value; } public async Task ForgotPasswordMobile([FromBody] ForgotPasswordRequestDto request, [FromServices] IMediator mediator) { - var response= await mediator.Send(new ForgotPasswordDto(request.Email, true)); + var response = await mediator.Send(new ForgotPasswordDto(request.Email, true)); return response.Value; } public async Task VerifyForgotPasswordCode([FromBody] VerifyForgotPasswordCodeDto request, [FromServices] IMediator mediator) { - var response= await mediator.Send(request); + var response = await mediator.Send(request); return response.Value; } public async Task PasswordResetMobile([FromBody] PasswordResetMobileDto request, [FromServices] IMediator mediator) { - var respone= await mediator.Send(new PasswordResetMobileCommand(request)); + var respone = await mediator.Send(new PasswordResetMobileCommand(request)); return respone.Value; } [Authorize] public async Task PasswordReset([FromBody] PasswordResetDto request, [FromServices] IMediator mediator) { - var response= await mediator.Send(request); + var response = await mediator.Send(request); return response.Value; } diff --git a/src/Hng.Graphql/Features/Mutations/Mutations.HelpCenterTopics.cs b/src/Hng.Graphql/Features/Mutations/Mutations.HelpCenterTopics.cs new file mode 100644 index 00000000..6dcb9f69 --- /dev/null +++ b/src/Hng.Graphql/Features/Mutations/Mutations.HelpCenterTopics.cs @@ -0,0 +1,32 @@ +using Hng.Application.Features.HelpCenter.Command; +using Hng.Application.Features.HelpCenter.Dtos; +using HotChocolate.Authorization; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace Hng.Graphql +{ + public partial class Mutations + { + [Authorize] + public async Task> CreateHelpCenterTopic([FromBody] CreateHelpCenterTopicRequestDto request, [FromServices] IMediator mediator) + { + var command = new CreateHelpCenterTopicCommand(request); + return await mediator.Send(command); + } + + [Authorize] + public async Task> UpdateHelpCenterTopic(Guid id, UpdateHelpCenterTopicRequestDto request, [FromServices] IMediator mediator) + { + var command = new UpdateHelpCenterTopicCommand(id, request); + return await mediator.Send(command); + } + + [Authorize] + public async Task> DeleteHelpCenterTopic(Guid id, [FromServices] IMediator mediator) + { + var command = new DeleteHelpCenterTopicCommand(id); + return await mediator.Send(command); + } + } +} diff --git a/src/Hng.Graphql/Features/Queries/Queries.HelpCenterTopics.cs b/src/Hng.Graphql/Features/Queries/Queries.HelpCenterTopics.cs new file mode 100644 index 00000000..5d75ba5b --- /dev/null +++ b/src/Hng.Graphql/Features/Queries/Queries.HelpCenterTopics.cs @@ -0,0 +1,28 @@ +using Hng.Application.Features.HelpCenter.Dtos; +using Hng.Application.Features.HelpCenter.Queries; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace Hng.Graphql +{ + public partial class Queries + { + public async Task> GetHelpCenterTopicById(Guid id, [FromServices] IMediator mediator) + { + var query = new GetHelpCenterTopicByIdQuery(id); + return await mediator.Send(query); + } + + public async Task>> GetHelpCenterTopics([FromServices] IMediator mediator) + { + var query = new GetHelpCenterTopicsQuery(); + return await mediator.Send(query); + } + + public async Task>> SearchTopics(SearchHelpCenterTopicsRequestDto request, [FromServices] IMediator mediator) + { + var query = new SearchHelpCenterTopicsQuery(request); + return await mediator.Send(query); + } + } +} diff --git a/src/Hng.Graphql/Queries.cs b/src/Hng.Graphql/Queries.cs index f5bc18ac..d1de871e 100644 --- a/src/Hng.Graphql/Queries.cs +++ b/src/Hng.Graphql/Queries.cs @@ -10,7 +10,7 @@ namespace Hng.Graphql { public partial class Queries { - + [Authorize] public async Task> GetRolesInOrganisation(Guid orgId, [FromServices] IMediator mediator) diff --git a/src/Hng.Web/Controllers/HelpCenterTopicController.cs b/src/Hng.Web/Controllers/HelpCenterTopicController.cs index 98fc1d05..ae5f6c60 100644 --- a/src/Hng.Web/Controllers/HelpCenterTopicController.cs +++ b/src/Hng.Web/Controllers/HelpCenterTopicController.cs @@ -2,6 +2,7 @@ using Hng.Application.Features.HelpCenter.Dtos; using Hng.Application.Features.HelpCenter.Queries; using Hng.Application.Shared.Dtos; +using HotChocolate.Authorization; using MediatR; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; @@ -25,6 +26,7 @@ public HelpCenterTopicController(IMediator mediator) /// The details of the Help Center topic to create. /// A response with the creation result or an error message. [HttpPost] + [Authorize] [ProducesResponseType(typeof(HelpCenterResponseDto), StatusCodes.Status201Created)] [ProducesResponseType(typeof(FailureResponseDto), StatusCodes.Status400BadRequest)] public async Task CreateHelpCenterTopic([FromBody] CreateHelpCenterTopicRequestDto request) From ce24adec83801ba89379e9158c19202121f483f5 Mon Sep 17 00:00:00 2001 From: Godand Date: Sat, 31 Aug 2024 18:07:15 +0200 Subject: [PATCH 14/22] chore(graphql): Cleanup --- src/Hng.Graphql/Queries.cs | 2 -- src/Hng.Web/Controllers/HelpCenterTopicController.cs | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Hng.Graphql/Queries.cs b/src/Hng.Graphql/Queries.cs index d1de871e..a2481c02 100644 --- a/src/Hng.Graphql/Queries.cs +++ b/src/Hng.Graphql/Queries.cs @@ -1,7 +1,5 @@ using Hng.Application.Features.Roles.Dto; using Hng.Application.Features.Roles.Queries; -using Hng.Application.Features.UserManagement.Dtos; -using Hng.Application.Features.UserManagement.Queries; using HotChocolate.Authorization; using MediatR; using Microsoft.AspNetCore.Mvc; diff --git a/src/Hng.Web/Controllers/HelpCenterTopicController.cs b/src/Hng.Web/Controllers/HelpCenterTopicController.cs index ae5f6c60..9148289c 100644 --- a/src/Hng.Web/Controllers/HelpCenterTopicController.cs +++ b/src/Hng.Web/Controllers/HelpCenterTopicController.cs @@ -2,9 +2,8 @@ using Hng.Application.Features.HelpCenter.Dtos; using Hng.Application.Features.HelpCenter.Queries; using Hng.Application.Shared.Dtos; -using HotChocolate.Authorization; using MediatR; -using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace Hng.Web.Controllers From 3e10b8dc1313692800db35e3d26b808272b50e23 Mon Sep 17 00:00:00 2001 From: Godand Date: Sat, 31 Aug 2024 18:14:57 +0200 Subject: [PATCH 15/22] Update Mutations.ContactUs.cs Signed-off-by: Godand --- src/Hng.Graphql/Mutations.ContactUs.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Hng.Graphql/Mutations.ContactUs.cs b/src/Hng.Graphql/Mutations.ContactUs.cs index 9f47242b..ca651b2f 100644 --- a/src/Hng.Graphql/Mutations.ContactUs.cs +++ b/src/Hng.Graphql/Mutations.ContactUs.cs @@ -8,7 +8,6 @@ namespace Hng.Graphql { public partial class Mutations { - [Authorize] public async Task> CreateContactMessage(ContactUsRequestDto contactUsRequest, [FromServices] IMediator mediator) { var command = new CreateContactUsCommand(contactUsRequest); @@ -22,4 +21,4 @@ public async Task> DeleteContactMessage(Guid id, [FromSe return await mediator.Send(command); } } -} \ No newline at end of file +} From 83f2098a18ae142f1c02151690bcd270609f7641 Mon Sep 17 00:00:00 2001 From: Godand Date: Sat, 31 Aug 2024 19:07:46 +0200 Subject: [PATCH 16/22] feat(graphql): implement newsletter subscription resolver --- .../{ => Features/Mutations}/Mutations.Comment.cs | 0 .../Mutations}/Mutations.ContactUs.cs | 0 .../Features/Mutations/Mutations.NewsLetter.cs | 15 +++++++++++++++ .../Mutations}/Mutations.Subscriptions.cs | 15 ++++++--------- .../{ => Features/Queries}/Queries.Admin.cs | 2 ++ .../{ => Features/Queries}/Queries.Comment.cs | 0 .../{ => Features/Queries}/Queries.ContactUs.cs | 0 .../Queries}/Queries.Subscriptions.cs | 0 8 files changed, 23 insertions(+), 9 deletions(-) rename src/Hng.Graphql/{ => Features/Mutations}/Mutations.Comment.cs (100%) rename src/Hng.Graphql/{ => Features/Mutations}/Mutations.ContactUs.cs (100%) create mode 100644 src/Hng.Graphql/Features/Mutations/Mutations.NewsLetter.cs rename src/Hng.Graphql/{ => Features/Mutations}/Mutations.Subscriptions.cs (64%) rename src/Hng.Graphql/{ => Features/Queries}/Queries.Admin.cs (90%) rename src/Hng.Graphql/{ => Features/Queries}/Queries.Comment.cs (100%) rename src/Hng.Graphql/{ => Features/Queries}/Queries.ContactUs.cs (100%) rename src/Hng.Graphql/{ => Features/Queries}/Queries.Subscriptions.cs (100%) diff --git a/src/Hng.Graphql/Mutations.Comment.cs b/src/Hng.Graphql/Features/Mutations/Mutations.Comment.cs similarity index 100% rename from src/Hng.Graphql/Mutations.Comment.cs rename to src/Hng.Graphql/Features/Mutations/Mutations.Comment.cs diff --git a/src/Hng.Graphql/Mutations.ContactUs.cs b/src/Hng.Graphql/Features/Mutations/Mutations.ContactUs.cs similarity index 100% rename from src/Hng.Graphql/Mutations.ContactUs.cs rename to src/Hng.Graphql/Features/Mutations/Mutations.ContactUs.cs diff --git a/src/Hng.Graphql/Features/Mutations/Mutations.NewsLetter.cs b/src/Hng.Graphql/Features/Mutations/Mutations.NewsLetter.cs new file mode 100644 index 00000000..132291f5 --- /dev/null +++ b/src/Hng.Graphql/Features/Mutations/Mutations.NewsLetter.cs @@ -0,0 +1,15 @@ +using Hng.Application.Features.NewsLetterSubscription.Commands; +using Hng.Application.Features.NewsLetterSubscription.Dtos; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace Hng.Graphql +{ + public partial class Mutations + { + public async Task RegisterNewsLetterSubscriber(NewsLetterSubscriptionDto subscriber, [FromServices] IMediator mediator) + { + return await mediator.Send(new AddSubscriberCommand(subscriber)); + } + } +} diff --git a/src/Hng.Graphql/Mutations.Subscriptions.cs b/src/Hng.Graphql/Features/Mutations/Mutations.Subscriptions.cs similarity index 64% rename from src/Hng.Graphql/Mutations.Subscriptions.cs rename to src/Hng.Graphql/Features/Mutations/Mutations.Subscriptions.cs index 481b79c7..e7e99adb 100644 --- a/src/Hng.Graphql/Mutations.Subscriptions.cs +++ b/src/Hng.Graphql/Features/Mutations/Mutations.Subscriptions.cs @@ -10,15 +10,12 @@ namespace Hng.Graphql { public partial class Mutations { - //[Authorize] - //public async Task SubscribeFreePlan(SubscribeFreePlan command, [FromServices] IMediator mediator) - //{ - // //var command = new SubscribeFreePlan(); - // // return await mediator.Send(command); - - - // // return await mediator.Send(command); - //} + [Authorize] + public async Task SubscribeFreePlan(SubscribeFreePlan command, [FromServices] IMediator mediator) + { + var response= await mediator.Send(command); + return response.Value; + } [Authorize] public async Task ActivateSubscription(Guid subscriptionId, [FromServices] IMediator mediator) diff --git a/src/Hng.Graphql/Queries.Admin.cs b/src/Hng.Graphql/Features/Queries/Queries.Admin.cs similarity index 90% rename from src/Hng.Graphql/Queries.Admin.cs rename to src/Hng.Graphql/Features/Queries/Queries.Admin.cs index 65b09c17..91cdfd3e 100644 --- a/src/Hng.Graphql/Queries.Admin.cs +++ b/src/Hng.Graphql/Features/Queries/Queries.Admin.cs @@ -1,6 +1,7 @@ using Hng.Application.Features.SuperAdmin.Dto; using Hng.Application.Features.SuperAdmin.Queries; using Hng.Application.Shared.Dtos; +using HotChocolate.Authorization; using MediatR; using Microsoft.AspNetCore.Mvc; @@ -8,6 +9,7 @@ namespace Hng.Graphql { public partial class Queries { + [Authorize] public async Task> GetUsersBySearch(UsersQueryParameters parameters, [FromServices] IMediator mediator) { var users = new GetUsersBySearchQuery(parameters); diff --git a/src/Hng.Graphql/Queries.Comment.cs b/src/Hng.Graphql/Features/Queries/Queries.Comment.cs similarity index 100% rename from src/Hng.Graphql/Queries.Comment.cs rename to src/Hng.Graphql/Features/Queries/Queries.Comment.cs diff --git a/src/Hng.Graphql/Queries.ContactUs.cs b/src/Hng.Graphql/Features/Queries/Queries.ContactUs.cs similarity index 100% rename from src/Hng.Graphql/Queries.ContactUs.cs rename to src/Hng.Graphql/Features/Queries/Queries.ContactUs.cs diff --git a/src/Hng.Graphql/Queries.Subscriptions.cs b/src/Hng.Graphql/Features/Queries/Queries.Subscriptions.cs similarity index 100% rename from src/Hng.Graphql/Queries.Subscriptions.cs rename to src/Hng.Graphql/Features/Queries/Queries.Subscriptions.cs From b1902aeb0fed1bfe3b3c7ac5c3526676f49b5c1e Mon Sep 17 00:00:00 2001 From: Alexin Date: Sat, 31 Aug 2024 18:35:28 +0100 Subject: [PATCH 17/22] ci: fix configuration credential issue --- Dockerfile | 2 ++ docker-compose.prod.yml | 11 ++++++++++- docker-compose.staging.yml | 8 ++++++++ docker-compose.yml | 8 ++++++++ 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index daf11f9c..b7b29ad4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -26,6 +26,8 @@ WORKDIR /app # Copy the published output from the publish stage COPY --from=publish /app/publish . +# Copy the EmailTemplates folder +COPY src/Hng.Infrastructure/EmailTemplates /app/EmailTemplates # Command to run the application ENTRYPOINT ["dotnet", "Hng.Web.dll"] diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 9f443c37..4fb787de 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -13,6 +13,14 @@ services: - postgres - redis restart: unless-stopped + deploy: + resources: + limits: + cpus: '0.17' + memory: 170M + reservations: + cpus: '0.08' + memory: 85M nginx: image: nginx:latest @@ -22,6 +30,7 @@ services: - backend volumes: - ./nginx.conf:/etc/nginx/nginx.conf + restart: unless-stopped postgres: image: postgres:latest @@ -35,6 +44,6 @@ services: redis: image: redis:latest - + restart: unless-stopped volumes: postgres_data: diff --git a/docker-compose.staging.yml b/docker-compose.staging.yml index 5ad2922c..cac47ac3 100644 --- a/docker-compose.staging.yml +++ b/docker-compose.staging.yml @@ -13,6 +13,14 @@ services: - postgres - redis restart: unless-stopped + deploy: + resources: + limits: + cpus: '0.17' + memory: 170M + reservations: + cpus: '0.08' + memory: 85M nginx: image: nginx:latest diff --git a/docker-compose.yml b/docker-compose.yml index a119558a..b03dd947 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,6 +13,14 @@ services: - postgres - redis restart: unless-stopped + deploy: + resources: + limits: + cpus: '0.17' + memory: 170M + reservations: + cpus: '0.08' + memory: 85M nginx: image: nginx:latest From 9ad93c0515c4d196b1d18a0dcf6fece62f1ae6d0 Mon Sep 17 00:00:00 2001 From: Godand Date: Sat, 31 Aug 2024 19:59:03 +0200 Subject: [PATCH 18/22] feat(graphql): Implement Notifications resolvers --- .../Features/Blog/GetBlogByIdQueryShould.cs | 2 +- .../GetUsersBySearchQueryHandlerShould.cs | 2 +- .../Features/SuperAdmin/Dto/UserDto.cs | 2 +- .../Handlers/GetUsersBySearchQueryHandler.cs | 8 +-- .../Mappers/AdminUsersMappingProfile.cs | 2 +- .../Queries/GetUsersBySearchQuery.cs | 2 +- .../Mutations/Mutations.Notification.cs | 69 +++++++++++++++++++ .../Mutations/Mutations.Subscriptions.cs | 2 +- .../Features/Queries/Queries.Admin.cs | 2 +- .../Features/Queries/Queries.Notification.cs | 31 +++++++++ src/Hng.Web/Controllers/AdminController.cs | 2 +- 11 files changed, 112 insertions(+), 12 deletions(-) create mode 100644 src/Hng.Graphql/Features/Mutations/Mutations.Notification.cs create mode 100644 src/Hng.Graphql/Features/Queries/Queries.Notification.cs diff --git a/src/Hng.Application.Test/Features/Blog/GetBlogByIdQueryShould.cs b/src/Hng.Application.Test/Features/Blog/GetBlogByIdQueryShould.cs index 798053ce..ae4c8bed 100644 --- a/src/Hng.Application.Test/Features/Blog/GetBlogByIdQueryShould.cs +++ b/src/Hng.Application.Test/Features/Blog/GetBlogByIdQueryShould.cs @@ -4,7 +4,7 @@ using Hng.Application.Features.Blogs.Dtos; using Hng.Application.Features.Blogs.Handlers; using Hng.Application.Features.Blogs.Queries; -using Hng.Application.Features.SuperAdmin.Dto; +using Hng.Application.Features.UserManagement.Dtos; using Hng.Domain.Entities; using Hng.Domain.Enums; using Hng.Infrastructure.Repository.Interface; diff --git a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersBySearchQueryHandlerShould.cs b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersBySearchQueryHandlerShould.cs index a0557e84..ce50ed3f 100644 --- a/src/Hng.Application.Test/Features/SuperAdmin/GetUsersBySearchQueryHandlerShould.cs +++ b/src/Hng.Application.Test/Features/SuperAdmin/GetUsersBySearchQueryHandlerShould.cs @@ -22,7 +22,7 @@ public GetUsersBySearchQueryHandlerShould() var config = new MapperConfiguration(cfg => { // Add your AutoMapper profiles here - cfg.CreateMap(); + cfg.CreateMap(); }); _mapper = config.CreateMapper(); diff --git a/src/Hng.Application/Features/SuperAdmin/Dto/UserDto.cs b/src/Hng.Application/Features/SuperAdmin/Dto/UserDto.cs index f8c1bdb0..422a81b8 100644 --- a/src/Hng.Application/Features/SuperAdmin/Dto/UserDto.cs +++ b/src/Hng.Application/Features/SuperAdmin/Dto/UserDto.cs @@ -2,7 +2,7 @@ namespace Hng.Application.Features.SuperAdmin.Dto { - public class UserDto + public class UserSuperDto { [JsonPropertyName("id")] public Guid Id { get; set; } diff --git a/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersBySearchQueryHandler.cs b/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersBySearchQueryHandler.cs index 6a9eef53..d986289f 100644 --- a/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersBySearchQueryHandler.cs +++ b/src/Hng.Application/Features/SuperAdmin/Handlers/GetUsersBySearchQueryHandler.cs @@ -8,7 +8,7 @@ namespace Hng.Application.Features.SuperAdmin.Handlers { - public class GetUsersBySearchQueryHandler : IRequestHandler> + public class GetUsersBySearchQueryHandler : IRequestHandler> { private readonly IRepository _userRepository; private readonly IMapper _mapper; @@ -19,15 +19,15 @@ public GetUsersBySearchQueryHandler(IRepository userRepository, IMapper ma _mapper = mapper; } - public async Task> Handle(GetUsersBySearchQuery request, CancellationToken cancellationToken) + public async Task> Handle(GetUsersBySearchQuery request, CancellationToken cancellationToken) { var users = await _userRepository.GetAllAsync(); users = users.Where(v => request.usersQueryParameters.Email == null || v.Email.ToLower().Equals(request.usersQueryParameters.Email.ToLower())).ToList(); users = users.Where(v => request.usersQueryParameters.Firstname == null || v.FirstName.ToLower().Equals(request.usersQueryParameters.Firstname.ToLower())).ToList(); users = users.Where(v => request.usersQueryParameters.Lastname == null || v.LastName.ToLower().Equals(request.usersQueryParameters.Lastname.ToLower())).ToList(); - var mappedusers = _mapper.Map>(users); - var userSearchResult = PagedListDto.ToPagedList(mappedusers, request.usersQueryParameters.Offset, request.usersQueryParameters.Limit); + var mappedusers = _mapper.Map>(users); + var userSearchResult = PagedListDto.ToPagedList(mappedusers, request.usersQueryParameters.Offset, request.usersQueryParameters.Limit); return userSearchResult; } diff --git a/src/Hng.Application/Features/SuperAdmin/Mappers/AdminUsersMappingProfile.cs b/src/Hng.Application/Features/SuperAdmin/Mappers/AdminUsersMappingProfile.cs index 87839001..5d0cbdaf 100644 --- a/src/Hng.Application/Features/SuperAdmin/Mappers/AdminUsersMappingProfile.cs +++ b/src/Hng.Application/Features/SuperAdmin/Mappers/AdminUsersMappingProfile.cs @@ -7,7 +7,7 @@ public class AdminUsersMappingProfile : AutoMapper.Profile { public AdminUsersMappingProfile() { - CreateMap().ReverseMap(); + CreateMap().ReverseMap(); } } } diff --git a/src/Hng.Application/Features/SuperAdmin/Queries/GetUsersBySearchQuery.cs b/src/Hng.Application/Features/SuperAdmin/Queries/GetUsersBySearchQuery.cs index b207c3a3..d30eee9f 100644 --- a/src/Hng.Application/Features/SuperAdmin/Queries/GetUsersBySearchQuery.cs +++ b/src/Hng.Application/Features/SuperAdmin/Queries/GetUsersBySearchQuery.cs @@ -4,7 +4,7 @@ namespace Hng.Application.Features.SuperAdmin.Queries { - public class GetUsersBySearchQuery : IRequest> + public class GetUsersBySearchQuery : IRequest> { public GetUsersBySearchQuery(UsersQueryParameters parameters) { diff --git a/src/Hng.Graphql/Features/Mutations/Mutations.Notification.cs b/src/Hng.Graphql/Features/Mutations/Mutations.Notification.cs new file mode 100644 index 00000000..4e483064 --- /dev/null +++ b/src/Hng.Graphql/Features/Mutations/Mutations.Notification.cs @@ -0,0 +1,69 @@ +using Hng.Application.Features.Notifications.Commands; +using Hng.Application.Features.Notifications.Dtos; +using HotChocolate.Authorization; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace Hng.Graphql.Features.Mutations +{ + public partial class Mutations + { + /// + /// Notification Settings - Create User notification + /// + [Authorize] + public async Task CreateNotification(CreateNotificationDto command, [FromServices] IMediator mediator) + { + var createCommand = new CreateNotificationCommand(command); + return await mediator.Send(createCommand); + } + + + /// + /// Mark a single notification as read + /// + /// The ID of the notification + /// The request body containing is_read flag + /// Response indicating the result of the operation + [Authorize] + public async Task MarkNotificationAsRead(Guid notification_id, UpdateNotificationDto request, [FromServices] IMediator mediator) + { + var command = new UpdateNotificationCommand(notification_id, request.IsRead); + return await mediator.Send(command); + } + + /// + /// Mark all notification as read + /// + /// The request body containing is_read flag + /// Response indicating the result of the operation + [Authorize] + public async Task> MarkAllNotificationAsRead(UpdateNotificationDto request, [FromServices] IMediator mediator) + { + var command = new MarkAllCommand(request.IsRead); + return await mediator.Send(command); + + } + + /// + /// Clear all user's notifications (Read or Unread) + /// + [Authorize] + public async Task DeleteAllNotifications([FromServices] IMediator mediator) + { + var command = new DeleteAllNotificationsCommand(); + return await mediator.Send(command); + + } + + /// + /// Clear notification (Read or Unread) + /// + [Authorize] + public async Task DeleteNotificationById(Guid notification_id, [FromServices] IMediator mediator) + { + var command = new DeleteNotificationByIdCommand(notification_id); + return await mediator.Send(command); + } + } +} diff --git a/src/Hng.Graphql/Features/Mutations/Mutations.Subscriptions.cs b/src/Hng.Graphql/Features/Mutations/Mutations.Subscriptions.cs index e7e99adb..ac7e529c 100644 --- a/src/Hng.Graphql/Features/Mutations/Mutations.Subscriptions.cs +++ b/src/Hng.Graphql/Features/Mutations/Mutations.Subscriptions.cs @@ -13,7 +13,7 @@ public partial class Mutations [Authorize] public async Task SubscribeFreePlan(SubscribeFreePlan command, [FromServices] IMediator mediator) { - var response= await mediator.Send(command); + var response = await mediator.Send(command); return response.Value; } diff --git a/src/Hng.Graphql/Features/Queries/Queries.Admin.cs b/src/Hng.Graphql/Features/Queries/Queries.Admin.cs index 91cdfd3e..b9f86dfe 100644 --- a/src/Hng.Graphql/Features/Queries/Queries.Admin.cs +++ b/src/Hng.Graphql/Features/Queries/Queries.Admin.cs @@ -10,7 +10,7 @@ namespace Hng.Graphql public partial class Queries { [Authorize] - public async Task> GetUsersBySearch(UsersQueryParameters parameters, [FromServices] IMediator mediator) + public async Task> GetUsersBySearch(UsersQueryParameters parameters, [FromServices] IMediator mediator) { var users = new GetUsersBySearchQuery(parameters); return await mediator.Send(users); diff --git a/src/Hng.Graphql/Features/Queries/Queries.Notification.cs b/src/Hng.Graphql/Features/Queries/Queries.Notification.cs new file mode 100644 index 00000000..4aad328d --- /dev/null +++ b/src/Hng.Graphql/Features/Queries/Queries.Notification.cs @@ -0,0 +1,31 @@ +using Hng.Application.Features.Notifications.Dtos; +using Hng.Application.Features.Notifications.Queries; +using HotChocolate.Authorization; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace Hng.Graphql.Features.Queries +{ + public partial class Queries + { + /// + /// Retrieve user's notifications (Read + Unread) + /// + [Authorize] + public async Task GetAllNotifications([FromServices] IMediator mediator) + { + var query = new GetAllNotificationsQuery(); + return await mediator.Send(query); + } + + /// + /// Retrieve user's notifications (Read or Unread) + /// + [Authorize] + public async Task GetNotifications(bool? is_read, [FromServices] IMediator mediator) + { + var query = new GetNotificationsQuery(is_read); + return await mediator.Send(query); + } + } +} diff --git a/src/Hng.Web/Controllers/AdminController.cs b/src/Hng.Web/Controllers/AdminController.cs index cb97b6ef..163c5d6b 100644 --- a/src/Hng.Web/Controllers/AdminController.cs +++ b/src/Hng.Web/Controllers/AdminController.cs @@ -27,7 +27,7 @@ public AdminController(IMediator mediator) public async Task GetUsersBySearch([FromQuery] UsersQueryParameters parameters) { var users = await _mediator.Send(new GetUsersBySearchQuery(parameters)); - return Ok(new PaginatedResponseDto> { Data = users, Metadata = users.MetaData }); + return Ok(new PaginatedResponseDto> { Data = users, Metadata = users.MetaData }); } } } From ffecfb6cde28378631153cd1eaa7f19c019014c9 Mon Sep 17 00:00:00 2001 From: Godand Date: Sat, 31 Aug 2024 20:23:05 +0200 Subject: [PATCH 19/22] feat(graphql): setup notification setting resolvers --- .../Mutations.NotificationSettings.cs | 23 ++++++++++++++++ .../Queries/Queries.NotificationSetting.cs | 27 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 src/Hng.Graphql/Features/Mutations/Mutations.NotificationSettings.cs create mode 100644 src/Hng.Graphql/Features/Queries/Queries.NotificationSetting.cs diff --git a/src/Hng.Graphql/Features/Mutations/Mutations.NotificationSettings.cs b/src/Hng.Graphql/Features/Mutations/Mutations.NotificationSettings.cs new file mode 100644 index 00000000..b80f919b --- /dev/null +++ b/src/Hng.Graphql/Features/Mutations/Mutations.NotificationSettings.cs @@ -0,0 +1,23 @@ +using Hng.Application.Features.Notifications.Commands; +using Hng.Application.Features.Notifications.Dtos; +using HotChocolate.Authorization; +using MediatR; +using Microsoft.AspNetCore.Mvc; + +namespace Hng.Graphql +{ + public partial class Mutations + { + /// + /// Notification Settings - User notification settings + /// + [Authorize] + public async Task CreateNotificationSettings([FromBody] CreateNotificationSettingsDto command, [FromServices] IMediator mediator) + { + { + var createCommand = new CreateNotificationSettingsCommand(command); + return await mediator.Send(createCommand); + } + } + } +} diff --git a/src/Hng.Graphql/Features/Queries/Queries.NotificationSetting.cs b/src/Hng.Graphql/Features/Queries/Queries.NotificationSetting.cs new file mode 100644 index 00000000..a9be2be2 --- /dev/null +++ b/src/Hng.Graphql/Features/Queries/Queries.NotificationSetting.cs @@ -0,0 +1,27 @@ +using Hng.Application.Features.Notifications.Dtos; +using Hng.Application.Features.Notifications.Queries; +using HotChocolate.Authorization; +using MediatR; +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Hng.Graphql +{ + public partial class Queries + { + /// + /// Get Notification Settings by User ID + /// + [Authorize] + public async Task GetNotificationSettings(Guid user_id, [FromServices] IMediator mediator) + { + var query = new GetNotificationSettingsQuery(user_id); + return await mediator.Send(query); + + } + } +} From c77dec6b48578c6c36ab635db0792fbe80bf3f51 Mon Sep 17 00:00:00 2001 From: Godand Date: Sat, 31 Aug 2024 21:52:21 +0200 Subject: [PATCH 20/22] partialfix(Tests): fix login test --- .../UserManagement/LoginUserCommandShould.cs | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/Hng.Application.Test/Features/UserManagement/LoginUserCommandShould.cs b/src/Hng.Application.Test/Features/UserManagement/LoginUserCommandShould.cs index 814ccba2..23606999 100644 --- a/src/Hng.Application.Test/Features/UserManagement/LoginUserCommandShould.cs +++ b/src/Hng.Application.Test/Features/UserManagement/LoginUserCommandShould.cs @@ -1,9 +1,15 @@ using AutoMapper; +using Hng.Application.Features.UserManagement.Commands; using Hng.Application.Features.UserManagement.Dtos; +using Hng.Application.Features.UserManagement.Handlers; using Hng.Domain.Entities; using Hng.Infrastructure.Repository.Interface; using Hng.Infrastructure.Services.Interfaces; +using Microsoft.AspNetCore.Http; +using Microsoft.EntityFrameworkCore; using Moq; +using System.Linq.Expressions; +using Xunit; namespace Hng.Application.Test.Features.UserManagement { @@ -11,6 +17,7 @@ public class LoginUserCommandShould { private readonly IMapper _mapper; private readonly Mock> _userRepositoryMock; + private readonly Mock> _lastLoginMock; private readonly Mock _passwordServiceMock; private readonly Mock _tokenServiceMock; private readonly User _user; @@ -27,6 +34,7 @@ public LoginUserCommandShould() _userRepositoryMock = new Mock>(); _passwordServiceMock = new Mock(); _tokenServiceMock = new Mock(); + _lastLoginMock= new Mock>(); _user = new User { @@ -35,7 +43,8 @@ public LoginUserCommandShould() FirstName = "John", LastName = "Doe", Password = "hashedpassword", - PasswordSalt = "salt" + PasswordSalt = "salt", + }; } @@ -43,16 +52,19 @@ public LoginUserCommandShould() //public async Task ReturnLoginResponseDtoForValidCredentials() //{ // // Arrange - // _userRepositoryMock.Setup(repo => repo.GetBySpec(It.IsAny>>(), It.IsAny>[]>())) - // .ReturnsAsync(_user); + // _userRepositoryMock.Setup(repo => repo.GetQueryableBySpec(It.IsAny>>()) + // .Include(It.IsAny>>>()) + // .ThenInclude(It.IsAny>>>()) + // .ThenInclude(It.IsAny>>()) + // .Include(It.IsAny>>>()).FirstOrDefaultAsync(CancellationToken.None)).ReturnsAsync(_user); // _passwordServiceMock.Setup(service => service.IsPasswordEqual("password", _user.PasswordSalt, _user.Password)) // .Returns(true); - // _tokenServiceMock.Setup(service => service.GenerateJwt(It.IsAny())) + // _tokenServiceMock.Setup(service => service.GenerateJwt(It.IsAny(), 5)) // .Returns("token"); - // var handler = new LoginUserCommandHandler(_userRepositoryMock.Object, _mapper, _passwordServiceMock.Object, _tokenServiceMock.Object); + // var handler = new LoginUserCommandHandler(_userRepositoryMock.Object,_lastLoginMock.Object, _mapper, _passwordServiceMock.Object, _tokenServiceMock.Object,new HttpContextAccessor()); // var command = new CreateUserLoginCommand(new UserLoginRequestDto // { From 41229ddaa822a7578eb6a49e8f08a9b6271812ba Mon Sep 17 00:00:00 2001 From: Godand Date: Sat, 31 Aug 2024 22:09:57 +0200 Subject: [PATCH 21/22] chore(tests): code formatting --- .../Features/UserManagement/LoginUserCommandShould.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Hng.Application.Test/Features/UserManagement/LoginUserCommandShould.cs b/src/Hng.Application.Test/Features/UserManagement/LoginUserCommandShould.cs index 23606999..ee5bc68e 100644 --- a/src/Hng.Application.Test/Features/UserManagement/LoginUserCommandShould.cs +++ b/src/Hng.Application.Test/Features/UserManagement/LoginUserCommandShould.cs @@ -34,7 +34,7 @@ public LoginUserCommandShould() _userRepositoryMock = new Mock>(); _passwordServiceMock = new Mock(); _tokenServiceMock = new Mock(); - _lastLoginMock= new Mock>(); + _lastLoginMock = new Mock>(); _user = new User { From 067df4370b4e0f899bdf5032da2177a4435d373e Mon Sep 17 00:00:00 2001 From: Godand Date: Fri, 6 Sep 2024 16:29:23 +0100 Subject: [PATCH 22/22] Revert "Added C-sharp Run Postman Tests" --- .github/workflows/c-sharp-postman-test.yaml | 33 --------------------- 1 file changed, 33 deletions(-) delete mode 100644 .github/workflows/c-sharp-postman-test.yaml diff --git a/.github/workflows/c-sharp-postman-test.yaml b/.github/workflows/c-sharp-postman-test.yaml deleted file mode 100644 index 95855467..00000000 --- a/.github/workflows/c-sharp-postman-test.yaml +++ /dev/null @@ -1,33 +0,0 @@ -name: C-sharp Run Postman Tests Every 15 Minutes - -on: - workflow_dispatch: - schedule: - - cron: "*/15 * * * *" # Every 15 minutes - -jobs: - run-postman-tests: - runs-on: self-hosted - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up Node.js - uses: actions/setup-node@v4 - with: - node-version: "20" - - - name: Install Newman - run: npm install -g newman - - - name: Run Newman tests - id: newman - run: | - newman run status/postman/telex_postmancollection_v1.json --reporters cli,json --reporter-json-export report.json - - - name: Upload newman report to API - run: | - curl -X POST "${{ vars.API_URL }}/api/v1/api-status" \ - -H "Content-Type: multipart/form-data" \ - -F "result_file=@report.json"