From 1c277f530d1f00368fb59eed1078cab1819fbd3a Mon Sep 17 00:00:00 2001 From: PascalMarchesseault <97350299+PascalMarchesseault@users.noreply.github.com> Date: Sat, 8 Jun 2024 12:03:20 -0400 Subject: [PATCH 1/5] Ajout de PublicCreatorInfo --- .../Queries/GetCreatorInfo/CreatorInfoDto.cs | 9 ++++ .../Queries/GetCreatorInfo/GetCreatorInfo.cs | 32 +++++++++++++ src/Web/Endpoints/GetCreatorInfo.cs | 19 ++++++++ src/Web/wwwroot/api/specification.json | 47 +++++++++++++++++++ 4 files changed, 107 insertions(+) create mode 100644 src/Application/Users/Queries/GetCreatorInfo/CreatorInfoDto.cs create mode 100644 src/Application/Users/Queries/GetCreatorInfo/GetCreatorInfo.cs create mode 100644 src/Web/Endpoints/GetCreatorInfo.cs diff --git a/src/Application/Users/Queries/GetCreatorInfo/CreatorInfoDto.cs b/src/Application/Users/Queries/GetCreatorInfo/CreatorInfoDto.cs new file mode 100644 index 0000000..e03d762 --- /dev/null +++ b/src/Application/Users/Queries/GetCreatorInfo/CreatorInfoDto.cs @@ -0,0 +1,9 @@ +namespace Hutopy.Application.Users.Queries.GetCreatorInfo; + +public class CreatorInfoDto +{ + public required string FirstName { get; init; } + public required string LastName { get; init; } + public string UserName { get; init; } = String.Empty; + +} diff --git a/src/Application/Users/Queries/GetCreatorInfo/GetCreatorInfo.cs b/src/Application/Users/Queries/GetCreatorInfo/GetCreatorInfo.cs new file mode 100644 index 0000000..2f2e7d9 --- /dev/null +++ b/src/Application/Users/Queries/GetCreatorInfo/GetCreatorInfo.cs @@ -0,0 +1,32 @@ +using Hutopy.Application.Common.Interfaces; + +namespace Hutopy.Application.Users.Queries.GetCreatorInfo; + +public record GetCreatorInfoQuery : IRequest +{ + public string UserName { get; set; } = string.Empty; +}; + + +public class GetCreatorInfoHandler( + IIdentityService identityService + ) + : IRequestHandler +{ + public async Task Handle(GetCreatorInfoQuery request, CancellationToken cancellationToken) + { + + var userName = await identityService.GetUserByUserNameAsync(request.UserName); + var creatorInfo = new CreatorInfoDto + { + + FirstName = userName?.FirstName ?? "", + LastName = userName?.LastName ?? "", + UserName = userName?.UserName ?? "", + + }; + return creatorInfo; + } + + +} diff --git a/src/Web/Endpoints/GetCreatorInfo.cs b/src/Web/Endpoints/GetCreatorInfo.cs new file mode 100644 index 0000000..e31263f --- /dev/null +++ b/src/Web/Endpoints/GetCreatorInfo.cs @@ -0,0 +1,19 @@ +using Hutopy.Application.Users.Queries; +using Hutopy.Application.Users.Queries.GetCreatorInfo; + + +namespace Hutopy.Web.Endpoints; + +public class GetCreatorInfo : EndpointGroupBase +{ + public override void Map(WebApplication app) + { + app.MapGroup(this) + .MapGet(GetSelectedCreatorInfo); + } + + private static async Task GetSelectedCreatorInfo(ISender sender, [AsParameters] GetCreatorInfoQuery query) + { + return await sender.Send(query); + } +} diff --git a/src/Web/wwwroot/api/specification.json b/src/Web/wwwroot/api/specification.json index e9729d9..670f3b3 100644 --- a/src/Web/wwwroot/api/specification.json +++ b/src/Web/wwwroot/api/specification.json @@ -6,6 +6,38 @@ "version": "1.0.0" }, "paths": { + "/api/GetCreatorInfo": { + "get": { + "tags": [ + "GetCreatorInfo" + ], + "operationId": "GetSelectedCreatorInfo", + "parameters": [ + { + "name": "UserName", + "in": "query", + "required": true, + "schema": { + "type": "string", + "nullable": true + }, + "x-position": 1 + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreatorInfoDto" + } + } + } + } + } + } + }, "/api/GetMyUser": { "get": { "tags": [ @@ -688,6 +720,21 @@ }, "components": { "schemas": { + "CreatorInfoDto": { + "type": "object", + "additionalProperties": false, + "properties": { + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + }, + "userName": { + "type": "string" + } + } + }, "UserDto": { "type": "object", "additionalProperties": false, From 48dcae22a3cfd60f678f678b8b929a0c0363d3b6 Mon Sep 17 00:00:00 2001 From: PascalMarchesseault <97350299+PascalMarchesseault@users.noreply.github.com> Date: Sun, 9 Jun 2024 23:03:33 -0400 Subject: [PATCH 2/5] Merge - Geminimal & CreatorInfo --- .../Queries/GetCreatorInfo/CreatorInfoDto.cs | 9 --- .../Queries/GetCreatorInfo/GetCreatorInfo.cs | 32 ----------- .../Queries/GetMinimalUser/GetMinimalUser.cs | 28 ++++++--- .../Queries/GetMinimalUser/MinimalUserDto.cs | 2 +- src/Web/Endpoints/GetCreatorInfo.cs | 19 ------- src/Web/Endpoints/Users.cs | 4 +- src/Web/wwwroot/api/specification.json | 57 +++---------------- 7 files changed, 34 insertions(+), 117 deletions(-) delete mode 100644 src/Application/Users/Queries/GetCreatorInfo/CreatorInfoDto.cs delete mode 100644 src/Application/Users/Queries/GetCreatorInfo/GetCreatorInfo.cs delete mode 100644 src/Web/Endpoints/GetCreatorInfo.cs diff --git a/src/Application/Users/Queries/GetCreatorInfo/CreatorInfoDto.cs b/src/Application/Users/Queries/GetCreatorInfo/CreatorInfoDto.cs deleted file mode 100644 index e03d762..0000000 --- a/src/Application/Users/Queries/GetCreatorInfo/CreatorInfoDto.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Hutopy.Application.Users.Queries.GetCreatorInfo; - -public class CreatorInfoDto -{ - public required string FirstName { get; init; } - public required string LastName { get; init; } - public string UserName { get; init; } = String.Empty; - -} diff --git a/src/Application/Users/Queries/GetCreatorInfo/GetCreatorInfo.cs b/src/Application/Users/Queries/GetCreatorInfo/GetCreatorInfo.cs deleted file mode 100644 index 2f2e7d9..0000000 --- a/src/Application/Users/Queries/GetCreatorInfo/GetCreatorInfo.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Hutopy.Application.Common.Interfaces; - -namespace Hutopy.Application.Users.Queries.GetCreatorInfo; - -public record GetCreatorInfoQuery : IRequest -{ - public string UserName { get; set; } = string.Empty; -}; - - -public class GetCreatorInfoHandler( - IIdentityService identityService - ) - : IRequestHandler -{ - public async Task Handle(GetCreatorInfoQuery request, CancellationToken cancellationToken) - { - - var userName = await identityService.GetUserByUserNameAsync(request.UserName); - var creatorInfo = new CreatorInfoDto - { - - FirstName = userName?.FirstName ?? "", - LastName = userName?.LastName ?? "", - UserName = userName?.UserName ?? "", - - }; - return creatorInfo; - } - - -} diff --git a/src/Application/Users/Queries/GetMinimalUser/GetMinimalUser.cs b/src/Application/Users/Queries/GetMinimalUser/GetMinimalUser.cs index 5fd288d..e7e5940 100644 --- a/src/Application/Users/Queries/GetMinimalUser/GetMinimalUser.cs +++ b/src/Application/Users/Queries/GetMinimalUser/GetMinimalUser.cs @@ -1,10 +1,12 @@ using Hutopy.Application.Common.Interfaces; +using Hutopy.Application.Common.Models; namespace Hutopy.Application.Users.Queries.GetMinimalUser; public record GetMinimalUserQuery : IRequest { - public string UserId { get; set; } = string.Empty; + public string? UserId { get; set; } = string.Empty; + public string? UserName { get; set; } = string.Empty; }; public class GetMinimalUserQueryHandler( @@ -14,15 +16,27 @@ public class GetMinimalUserQueryHandler( { public async Task Handle(GetMinimalUserQuery request, CancellationToken cancellationToken) { - var identityUser = await identityService.FindUserByIdAsync(request.UserId); - + UserModel? identityUser = null; + + if (request.UserId != string.Empty) + { + identityUser = await identityService.FindUserByIdAsync(request.UserId); + + } + + if (request.UserName != string.Empty) + { + identityUser = await identityService.GetUserByUserNameAsync(request.UserName); + } + + var user = new MinimalUserDto { - FirstName = identityUser?.FirstName ?? "", - LastName = identityUser?.LastName ?? "", - UserName = identityUser?.UserName ?? "" + FirstName = identityUser?.FirstName ?? string.Empty, + LastName = identityUser?.LastName ?? string.Empty, + UserName = identityUser?.UserName ?? string.Empty }; return user; } -} +} \ No newline at end of file diff --git a/src/Application/Users/Queries/GetMinimalUser/MinimalUserDto.cs b/src/Application/Users/Queries/GetMinimalUser/MinimalUserDto.cs index 0b01fba..97fa6a1 100644 --- a/src/Application/Users/Queries/GetMinimalUser/MinimalUserDto.cs +++ b/src/Application/Users/Queries/GetMinimalUser/MinimalUserDto.cs @@ -4,5 +4,5 @@ public class MinimalUserDto { public required string FirstName { get; init; } public required string LastName { get; init; } - public string UserName { get; init; } = String.Empty; + public required string UserName { get; init; } = String.Empty; } diff --git a/src/Web/Endpoints/GetCreatorInfo.cs b/src/Web/Endpoints/GetCreatorInfo.cs deleted file mode 100644 index e31263f..0000000 --- a/src/Web/Endpoints/GetCreatorInfo.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Hutopy.Application.Users.Queries; -using Hutopy.Application.Users.Queries.GetCreatorInfo; - - -namespace Hutopy.Web.Endpoints; - -public class GetCreatorInfo : EndpointGroupBase -{ - public override void Map(WebApplication app) - { - app.MapGroup(this) - .MapGet(GetSelectedCreatorInfo); - } - - private static async Task GetSelectedCreatorInfo(ISender sender, [AsParameters] GetCreatorInfoQuery query) - { - return await sender.Send(query); - } -} diff --git a/src/Web/Endpoints/Users.cs b/src/Web/Endpoints/Users.cs index 32b8acc..b0b9c59 100644 --- a/src/Web/Endpoints/Users.cs +++ b/src/Web/Endpoints/Users.cs @@ -12,15 +12,17 @@ public class Users : EndpointGroupBase .MapPost(CreateUser) .MapGet(GetMinimalUser) .MapIdentityApi(); + } private static async Task CreateUser(ISender sender, CreateUserCommand command) { return await sender.Send(command); } - + private static async Task GetMinimalUser(ISender sender, [AsParameters] GetMinimalUserQuery query) { return await sender.Send(query); } + } diff --git a/src/Web/wwwroot/api/specification.json b/src/Web/wwwroot/api/specification.json index 670f3b3..ece282e 100644 --- a/src/Web/wwwroot/api/specification.json +++ b/src/Web/wwwroot/api/specification.json @@ -6,38 +6,6 @@ "version": "1.0.0" }, "paths": { - "/api/GetCreatorInfo": { - "get": { - "tags": [ - "GetCreatorInfo" - ], - "operationId": "GetSelectedCreatorInfo", - "parameters": [ - { - "name": "UserName", - "in": "query", - "required": true, - "schema": { - "type": "string", - "nullable": true - }, - "x-position": 1 - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreatorInfoDto" - } - } - } - } - } - } - }, "/api/GetMyUser": { "get": { "tags": [ @@ -283,12 +251,20 @@ { "name": "UserId", "in": "query", - "required": true, "schema": { "type": "string", "nullable": true }, "x-position": 1 + }, + { + "name": "UserName", + "in": "query", + "schema": { + "type": "string", + "nullable": true + }, + "x-position": 2 } ], "responses": { @@ -720,21 +696,6 @@ }, "components": { "schemas": { - "CreatorInfoDto": { - "type": "object", - "additionalProperties": false, - "properties": { - "firstName": { - "type": "string" - }, - "lastName": { - "type": "string" - }, - "userName": { - "type": "string" - } - } - }, "UserDto": { "type": "object", "additionalProperties": false, From 47fb3caa0df62843195f17f7852d83f825cd019e Mon Sep 17 00:00:00 2001 From: Dominic Villemure Date: Tue, 11 Jun 2024 20:14:36 -0400 Subject: [PATCH 3/5] #58 added owned entity for SocialNetworks that belongs to an ApplicationUser --- .../Data/ApplicationDbContext.cs | 39 +- .../ApplicationUserConfiguration.cs | 16 + .../UserTransactionConfiguration.cs | 21 + .../Identity/ApplicationUser.cs | 4 +- .../Identity/OwnedEntities/SocialNetworks.cs | 13 + ...000806_AddSocialNetworksToUser.Designer.cs | 469 ++++++++++++++++++ .../20240612000806_AddSocialNetworksToUser.cs | 52 ++ .../ApplicationDbContextModelSnapshot.cs | 51 ++ 8 files changed, 643 insertions(+), 22 deletions(-) create mode 100644 src/Infrastructure/Data/Configurations/ApplicationUserConfiguration.cs create mode 100644 src/Infrastructure/Data/Configurations/UserTransactionConfiguration.cs create mode 100644 src/Infrastructure/Identity/OwnedEntities/SocialNetworks.cs create mode 100644 src/Infrastructure/Migrations/20240612000806_AddSocialNetworksToUser.Designer.cs create mode 100644 src/Infrastructure/Migrations/20240612000806_AddSocialNetworksToUser.cs diff --git a/src/Infrastructure/Data/ApplicationDbContext.cs b/src/Infrastructure/Data/ApplicationDbContext.cs index cb3a247..8b4676e 100644 --- a/src/Infrastructure/Data/ApplicationDbContext.cs +++ b/src/Infrastructure/Data/ApplicationDbContext.cs @@ -1,32 +1,29 @@ -using System.Reflection; -using Hutopy.Application.Common.Interfaces; +using Hutopy.Application.Common.Interfaces; using Hutopy.Domain.Entities; +using Hutopy.Infrastructure.Data.Configurations; using Hutopy.Infrastructure.Identity; using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; -namespace Hutopy.Infrastructure.Data; - -public class ApplicationDbContext( - DbContextOptions options) - : IdentityDbContext(options), IApplicationDbContext +namespace Hutopy.Infrastructure.Data { - public DbSet FutureCreators => Set(); - public DbSet UserTransactions => Set(); - - protected override void OnModelCreating(ModelBuilder builder) + public class ApplicationDbContext : IdentityDbContext, IApplicationDbContext { - base.OnModelCreating(builder); + public ApplicationDbContext(DbContextOptions options) + : base(options) + { + } - // Relationship between ApplicationUser and UserTransaction - builder.Entity() - .HasOne() - .WithMany() - .HasForeignKey(ut => ut.ApplicationUserId) - .IsRequired(); + public DbSet FutureCreators => Set(); + public DbSet UserTransactions => Set(); - builder.Entity().Property(x => x.Amount).HasPrecision(18, 2); - - builder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly()); + protected override void OnModelCreating(ModelBuilder builder) + { + base.OnModelCreating(builder); + + // Apply configurations + builder.ApplyConfiguration(new UserTransactionConfiguration()); + builder.ApplyConfiguration(new ApplicationUserConfiguration()); + } } } diff --git a/src/Infrastructure/Data/Configurations/ApplicationUserConfiguration.cs b/src/Infrastructure/Data/Configurations/ApplicationUserConfiguration.cs new file mode 100644 index 0000000..0624b7a --- /dev/null +++ b/src/Infrastructure/Data/Configurations/ApplicationUserConfiguration.cs @@ -0,0 +1,16 @@ +using Hutopy.Infrastructure.Identity; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace Hutopy.Infrastructure.Data.Configurations; + +public class ApplicationUserConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + // Relationship between ApplicationUser and SocialNetworks + builder + .OwnsOne(u => u.SocialNetworks) + .ToTable($"{nameof(ApplicationUser)}_SocialNetworks"); + } +} diff --git a/src/Infrastructure/Data/Configurations/UserTransactionConfiguration.cs b/src/Infrastructure/Data/Configurations/UserTransactionConfiguration.cs new file mode 100644 index 0000000..f659e55 --- /dev/null +++ b/src/Infrastructure/Data/Configurations/UserTransactionConfiguration.cs @@ -0,0 +1,21 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Hutopy.Domain.Entities; +using Hutopy.Infrastructure.Identity; + +namespace Hutopy.Infrastructure.Data.Configurations +{ + public class UserTransactionConfiguration : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + // Relationship between ApplicationUser and UserTransaction + builder.HasOne() + .WithMany() + .HasForeignKey(ut => ut.ApplicationUserId) + .IsRequired(); + + builder.Property(x => x.Amount).HasPrecision(18, 2); + } + } +} diff --git a/src/Infrastructure/Identity/ApplicationUser.cs b/src/Infrastructure/Identity/ApplicationUser.cs index 0462aff..700a074 100644 --- a/src/Infrastructure/Identity/ApplicationUser.cs +++ b/src/Infrastructure/Identity/ApplicationUser.cs @@ -1,4 +1,5 @@ -using Microsoft.AspNetCore.Identity; +using Hutopy.Infrastructure.Identity.OwnedEntities; +using Microsoft.AspNetCore.Identity; namespace Hutopy.Infrastructure.Identity; @@ -6,4 +7,5 @@ public class ApplicationUser : IdentityUser { public string FirstName { get; set; } = string.Empty; public string LastName { get; set; } = string.Empty; + public SocialNetworks SocialNetworks { get; set; } = new(); } diff --git a/src/Infrastructure/Identity/OwnedEntities/SocialNetworks.cs b/src/Infrastructure/Identity/OwnedEntities/SocialNetworks.cs new file mode 100644 index 0000000..1e0d30e --- /dev/null +++ b/src/Infrastructure/Identity/OwnedEntities/SocialNetworks.cs @@ -0,0 +1,13 @@ +namespace Hutopy.Infrastructure.Identity.OwnedEntities; + +public class SocialNetworks +{ + public string FacebookUrl { get; init; } = String.Empty; + public string InstagramUrl { get; init; } = String.Empty; + public string XUrl { get; init; } = String.Empty; + public string LinkedInUrl { get; init; } = String.Empty; + public string TikTokUrl { get; init; } = String.Empty; + public string YoutubeUrl { get; init; } = String.Empty; + public string RedditUrl { get; init; } = String.Empty; + public string YourWebsiteUrl { get; init; } = String.Empty; +} diff --git a/src/Infrastructure/Migrations/20240612000806_AddSocialNetworksToUser.Designer.cs b/src/Infrastructure/Migrations/20240612000806_AddSocialNetworksToUser.Designer.cs new file mode 100644 index 0000000..2c074bc --- /dev/null +++ b/src/Infrastructure/Migrations/20240612000806_AddSocialNetworksToUser.Designer.cs @@ -0,0 +1,469 @@ +// +using System; +using Hutopy.Infrastructure.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Hutopy.Infrastructure.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20240612000806_AddSocialNetworksToUser")] + partial class AddSocialNetworksToUser + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.3") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("Hutopy.Domain.Entities.FutureCreator", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Created") + .HasColumnType("datetimeoffset"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("EmailAddress") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("LastModified") + .HasColumnType("datetimeoffset"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ReasonToJoin") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("SocialNetworkAccount") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("FutureCreators"); + }); + + modelBuilder.Entity("Hutopy.Domain.Entities.UserTransaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Amount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("ApplicationUserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.Property("Created") + .HasColumnType("datetimeoffset"); + + b.Property("CreatedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Currency") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsConfirmed") + .HasColumnType("bit"); + + b.Property("LastModified") + .HasColumnType("datetimeoffset"); + + b.Property("LastModifiedBy") + .HasColumnType("nvarchar(max)"); + + b.Property("Paid") + .HasColumnType("bit"); + + b.Property("StripeBillingDetailEmail") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("StripeBillingDetailName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("StripeChargeId") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("StripeEventId") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("StripePaymentIntent") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("StripePaymentMethod") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("StripeReceiptUrl") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("TipMessage") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationUserId"); + + b.ToTable("UserTransactions"); + }); + + modelBuilder.Entity("Hutopy.Infrastructure.Identity.ApplicationUser", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("RoleId") + .HasColumnType("nvarchar(450)"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Hutopy.Domain.Entities.UserTransaction", b => + { + b.HasOne("Hutopy.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("ApplicationUserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Hutopy.Infrastructure.Identity.ApplicationUser", b => + { + b.OwnsOne("Hutopy.Infrastructure.Identity.OwnedEntities.SocialNetworks", "SocialNetworks", b1 => + { + b1.Property("ApplicationUserId") + .HasColumnType("nvarchar(450)"); + + b1.Property("FacebookUrl") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b1.Property("InstagramUrl") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b1.Property("LinkedInUrl") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b1.Property("RedditUrl") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b1.Property("TikTokUrl") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b1.Property("XUrl") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b1.Property("YourWebsiteUrl") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b1.Property("YoutubeUrl") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b1.HasKey("ApplicationUserId"); + + b1.ToTable("ApplicationUser_SocialNetworks", (string)null); + + b1.WithOwner() + .HasForeignKey("ApplicationUserId"); + }); + + b.Navigation("SocialNetworks") + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Hutopy.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Hutopy.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Hutopy.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Hutopy.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Infrastructure/Migrations/20240612000806_AddSocialNetworksToUser.cs b/src/Infrastructure/Migrations/20240612000806_AddSocialNetworksToUser.cs new file mode 100644 index 0000000..14dfa81 --- /dev/null +++ b/src/Infrastructure/Migrations/20240612000806_AddSocialNetworksToUser.cs @@ -0,0 +1,52 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Hutopy.Infrastructure.Migrations +{ + /// + public partial class AddSocialNetworksToUser : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "ApplicationUser_SocialNetworks", + columns: table => new + { + ApplicationUserId = table.Column(type: "nvarchar(450)", nullable: false), + FacebookUrl = table.Column(type: "nvarchar(max)", nullable: false), + InstagramUrl = table.Column(type: "nvarchar(max)", nullable: false), + XUrl = table.Column(type: "nvarchar(max)", nullable: false), + LinkedInUrl = table.Column(type: "nvarchar(max)", nullable: false), + TikTokUrl = table.Column(type: "nvarchar(max)", nullable: false), + YoutubeUrl = table.Column(type: "nvarchar(max)", nullable: false), + RedditUrl = table.Column(type: "nvarchar(max)", nullable: false), + YourWebsiteUrl = table.Column(type: "nvarchar(max)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ApplicationUser_SocialNetworks", x => x.ApplicationUserId); + table.ForeignKey( + name: "FK_ApplicationUser_SocialNetworks_AspNetUsers_ApplicationUserId", + column: x => x.ApplicationUserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.Sql(@" + INSERT INTO ApplicationUser_SocialNetworks (ApplicationUserId, FacebookUrl, InstagramUrl, XUrl, LinkedInUrl, TikTokUrl, YoutubeUrl, RedditUrl, YourWebsiteUrl) + SELECT Id, '', '', '', '', '', '', '', '' + FROM AspNetUsers + "); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "ApplicationUser_SocialNetworks"); + } + } +} diff --git a/src/Infrastructure/Migrations/ApplicationDbContextModelSnapshot.cs b/src/Infrastructure/Migrations/ApplicationDbContextModelSnapshot.cs index cb3b55f..fcb6687 100644 --- a/src/Infrastructure/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/src/Infrastructure/Migrations/ApplicationDbContextModelSnapshot.cs @@ -359,6 +359,57 @@ namespace Hutopy.Infrastructure.Migrations .IsRequired(); }); + modelBuilder.Entity("Hutopy.Infrastructure.Identity.ApplicationUser", b => + { + b.OwnsOne("Hutopy.Infrastructure.Identity.OwnedEntities.SocialNetworks", "SocialNetworks", b1 => + { + b1.Property("ApplicationUserId") + .HasColumnType("nvarchar(450)"); + + b1.Property("FacebookUrl") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b1.Property("InstagramUrl") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b1.Property("LinkedInUrl") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b1.Property("RedditUrl") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b1.Property("TikTokUrl") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b1.Property("XUrl") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b1.Property("YourWebsiteUrl") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b1.Property("YoutubeUrl") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b1.HasKey("ApplicationUserId"); + + b1.ToTable("ApplicationUser_SocialNetworks", (string)null); + + b1.WithOwner() + .HasForeignKey("ApplicationUserId"); + }); + + b.Navigation("SocialNetworks") + .IsRequired(); + }); + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => { b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) From 108d5424a48fe6b0becb3b39a80ce866f9c368b6 Mon Sep 17 00:00:00 2001 From: Dominic Villemure Date: Tue, 11 Jun 2024 20:20:51 -0400 Subject: [PATCH 4/5] #58 continue using Reflection to get configurations --- src/Infrastructure/Data/ApplicationDbContext.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Infrastructure/Data/ApplicationDbContext.cs b/src/Infrastructure/Data/ApplicationDbContext.cs index 8b4676e..21b06a4 100644 --- a/src/Infrastructure/Data/ApplicationDbContext.cs +++ b/src/Infrastructure/Data/ApplicationDbContext.cs @@ -1,6 +1,6 @@ -using Hutopy.Application.Common.Interfaces; +using System.Reflection; +using Hutopy.Application.Common.Interfaces; using Hutopy.Domain.Entities; -using Hutopy.Infrastructure.Data.Configurations; using Hutopy.Infrastructure.Identity; using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; @@ -22,8 +22,7 @@ namespace Hutopy.Infrastructure.Data base.OnModelCreating(builder); // Apply configurations - builder.ApplyConfiguration(new UserTransactionConfiguration()); - builder.ApplyConfiguration(new ApplicationUserConfiguration()); + builder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly()); } } } From d4c88d2f15eaa0b0b3de8a4cd340a3d44e16f8e2 Mon Sep 17 00:00:00 2001 From: Dominic Villemure Date: Sun, 16 Jun 2024 10:00:15 -0400 Subject: [PATCH 5/5] config for stripe api key --- src/Infrastructure/Stripe/StripeService.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Infrastructure/Stripe/StripeService.cs b/src/Infrastructure/Stripe/StripeService.cs index 061f9e2..7b78fff 100644 --- a/src/Infrastructure/Stripe/StripeService.cs +++ b/src/Infrastructure/Stripe/StripeService.cs @@ -4,6 +4,7 @@ using Hutopy.Application.Common.Interfaces; using Microsoft.AspNetCore.Http; using Hutopy.Application.Common.Models; using Hutopy.Application.Stripe.Commands; +using Microsoft.Extensions.Configuration; namespace Hutopy.Infrastructure.Stripe; @@ -11,10 +12,11 @@ public class StripeService : IStripeService { private readonly IHttpContextAccessor _httpContextAccessor; - public StripeService(IHttpContextAccessor httpContextAccessor) + public StripeService(IHttpContextAccessor httpContextAccessor, IConfiguration configuration) { _httpContextAccessor = httpContextAccessor; - StripeConfiguration.ApiKey = ""; + var stripeKey = configuration["STRIPE-API-KEY"] ?? ""; + StripeConfiguration.ApiKey = stripeKey; } public async Task CreateCheckoutSession(int amount, string creatorId, string currency = "cad")