#27 added userTransactions
This commit is contained in:
@@ -5,5 +5,6 @@ namespace Hutopy.Application.Common.Interfaces;
|
||||
public interface IApplicationDbContext
|
||||
{
|
||||
DbSet<FutureCreator> FutureCreators { get; }
|
||||
DbSet<UserTransaction> UserTransactions { get; }
|
||||
Task<int> SaveChangesAsync(CancellationToken cancellationToken);
|
||||
}
|
||||
|
||||
@@ -1,25 +1,31 @@
|
||||
using Hutopy.Application.Common.Interfaces;
|
||||
|
||||
using Hutopy.Domain.Entities;
|
||||
|
||||
namespace Hutopy.Application.Stripe.Commands;
|
||||
public abstract record CreateSessionCheckoutCommand : IRequest<string>
|
||||
public record CreateSessionCheckoutCommand : IRequest<string>
|
||||
{
|
||||
public required string CreatorId { get; init; }
|
||||
public required int Price { get; init; }
|
||||
|
||||
public string Currency { get; init; } = "cad";
|
||||
public string Currency { get; init; } = "CAD";
|
||||
public string TipMessage { get; init; } = string.Empty;
|
||||
}
|
||||
|
||||
|
||||
public class CreateSessionCheckoutCommandHandler(
|
||||
IApplicationDbContext context,
|
||||
IStripeService stripeService)
|
||||
IApplicationDbContext dbContext,
|
||||
IStripeService stripeService
|
||||
)
|
||||
: IRequestHandler<CreateSessionCheckoutCommand, string>
|
||||
{
|
||||
private readonly IApplicationDbContext _context = context;
|
||||
|
||||
public async Task<string> Handle(CreateSessionCheckoutCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var stripeSecret = await stripeService.CreateCheckoutSession(request.Price, request.Currency);
|
||||
|
||||
var userTransaction = new UserTransaction
|
||||
{
|
||||
Currency = request.Currency, Amount = request.Price, TipMessage = request.TipMessage, ApplicationUserId = request.CreatorId
|
||||
};
|
||||
|
||||
await dbContext.UserTransactions.AddAsync(userTransaction, cancellationToken);
|
||||
|
||||
return stripeSecret;
|
||||
}
|
||||
|
||||
37
src/Application/Users/Queries/GetCurrentUser.cs
Normal file
37
src/Application/Users/Queries/GetCurrentUser.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using Hutopy.Application.Common.Interfaces;
|
||||
using Hutopy.Domain.Interfaces;
|
||||
|
||||
namespace Hutopy.Application.Users.Queries;
|
||||
|
||||
public record GetCurrentUserQuery : IRequest<UserDto>;
|
||||
|
||||
public class GetCurrentUserQueryHandler(
|
||||
IApplicationDbContext context,
|
||||
IMapper mapper,
|
||||
IUserService userService
|
||||
)
|
||||
: IRequestHandler<GetCurrentUserQuery, UserDto>
|
||||
{
|
||||
public async Task<UserDto> Handle(GetCurrentUserQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var identityUser = await userService.GetCurrentUserAsync();
|
||||
var currentUserId = new Guid(identityUser?.Id ?? "");
|
||||
|
||||
var transactions = await context.UserTransactions
|
||||
.Where(x => x.Id == currentUserId)
|
||||
.OrderBy(x => x.LastModified)
|
||||
.ProjectTo<UserTransactionDto>(mapper.ConfigurationProvider)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
|
||||
var user = new UserDto()
|
||||
{
|
||||
Id = currentUserId,
|
||||
FirstName = identityUser?.FirstName ?? "",
|
||||
LastName = identityUser?.LastName ?? "",
|
||||
UserTransactions = transactions
|
||||
};
|
||||
|
||||
return user;
|
||||
}
|
||||
}
|
||||
12
src/Application/Users/Queries/UserDto.cs
Normal file
12
src/Application/Users/Queries/UserDto.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace Hutopy.Application.Users.Queries;
|
||||
|
||||
public class UserDto
|
||||
{
|
||||
public Guid Id { get; init; }
|
||||
|
||||
public required string FirstName { get; init; }
|
||||
|
||||
public required string LastName { get; init; }
|
||||
|
||||
public List<UserTransactionDto> UserTransactions { get; init; } = [];
|
||||
}
|
||||
20
src/Application/Users/Queries/UserTransactionDto.cs
Normal file
20
src/Application/Users/Queries/UserTransactionDto.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using Hutopy.Domain.Entities;
|
||||
|
||||
namespace Hutopy.Application.Users.Queries;
|
||||
|
||||
public class UserTransactionDto
|
||||
{
|
||||
public required decimal Amount { get; init; }
|
||||
|
||||
public string Currency { get; init; } = "cad";
|
||||
|
||||
public string TipMessage { get; init; } = string.Empty;
|
||||
|
||||
private class Mapping : Profile
|
||||
{
|
||||
public Mapping()
|
||||
{
|
||||
CreateMap<UserTransaction, UserTransactionDto>();
|
||||
}
|
||||
}
|
||||
}
|
||||
11
src/Domain/Entities/UserTransaction.cs
Normal file
11
src/Domain/Entities/UserTransaction.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace Hutopy.Domain.Entities;
|
||||
|
||||
public class UserTransaction : BaseAuditableEntity
|
||||
{
|
||||
public decimal Amount { get; set; }
|
||||
public string Currency { get; set; } = "CAD";
|
||||
public string TipMessage { get; set; } = string.Empty;
|
||||
|
||||
// Foreign key to ApplicationUser
|
||||
public string ApplicationUserId { get; set; } = string.Empty;
|
||||
}
|
||||
@@ -7,6 +7,7 @@ public interface IUserService
|
||||
Task CreateUserAsync(string email, string userName, string firstName, string lastName, string password);
|
||||
|
||||
Task<UserModel?> FindUserByIdAsync(string id);
|
||||
Task<UserModel?> GetCurrentUserAsync();
|
||||
|
||||
Task<UserModel?> FindUserByEmailAsync(string id);
|
||||
}
|
||||
|
||||
@@ -12,10 +12,19 @@ public class ApplicationDbContext(
|
||||
: IdentityDbContext<ApplicationUser>(options), IApplicationDbContext
|
||||
{
|
||||
public DbSet<FutureCreator> FutureCreators => Set<FutureCreator>();
|
||||
public DbSet<UserTransaction> UserTransactions => Set<UserTransaction>();
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder builder)
|
||||
{
|
||||
base.OnModelCreating(builder);
|
||||
|
||||
// Relationship between ApplicationUser and UserTransaction
|
||||
builder.Entity<UserTransaction>()
|
||||
.HasOne<ApplicationUser>()
|
||||
.WithMany()
|
||||
.HasForeignKey(ut => ut.ApplicationUserId)
|
||||
.IsRequired();
|
||||
|
||||
builder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,4 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Application\Application.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Data\Migrations\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
383
src/Infrastructure/Migrations/20240422173330_AddUserTransactions.Designer.cs
generated
Normal file
383
src/Infrastructure/Migrations/20240422173330_AddUserTransactions.Designer.cs
generated
Normal file
@@ -0,0 +1,383 @@
|
||||
// <auto-generated />
|
||||
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("20240422173330_AddUserTransactions")]
|
||||
partial class AddUserTransactions
|
||||
{
|
||||
/// <inheritdoc />
|
||||
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<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<DateTimeOffset>("Created")
|
||||
.HasColumnType("datetimeoffset");
|
||||
|
||||
b.Property<string>("CreatedBy")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("EmailAddress")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("FirstName")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<DateTimeOffset>("LastModified")
|
||||
.HasColumnType("datetimeoffset");
|
||||
|
||||
b.Property<string>("LastModifiedBy")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("LastName")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("PhoneNumber")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("ReasonToJoin")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("SocialNetworkAccount")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("FutureCreators");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Hutopy.Domain.Entities.UserTransaction", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<decimal>("Amount")
|
||||
.HasColumnType("decimal(18,2)");
|
||||
|
||||
b.Property<string>("ApplicationUserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<DateTimeOffset>("Created")
|
||||
.HasColumnType("datetimeoffset");
|
||||
|
||||
b.Property<string>("CreatedBy")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Currency")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<DateTimeOffset>("LastModified")
|
||||
.HasColumnType("datetimeoffset");
|
||||
|
||||
b.Property<string>("LastModifiedBy")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("TipMessage")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ApplicationUserId");
|
||||
|
||||
b.ToTable("UserTransactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Hutopy.Infrastructure.Identity.ApplicationUser", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<int>("AccessFailedCount")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("nvarchar(256)");
|
||||
|
||||
b.Property<bool>("EmailConfirmed")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<string>("FirstName")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("LastName")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<bool>("LockoutEnabled")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||
.HasColumnType("datetimeoffset");
|
||||
|
||||
b.Property<string>("NormalizedEmail")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("nvarchar(256)");
|
||||
|
||||
b.Property<string>("NormalizedUserName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("nvarchar(256)");
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("PhoneNumber")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<bool>("PhoneNumberConfirmed")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<string>("SecurityStamp")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<bool>("TwoFactorEnabled")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<string>("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<string>("Id")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("nvarchar(256)");
|
||||
|
||||
b.Property<string>("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<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetRoleClaims", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserClaims", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<string>("ProviderKey")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<string>("ProviderDisplayName")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.HasKey("LoginProvider", "ProviderKey");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserLogins", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.HasKey("UserId", "RoleId");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetUserRoles", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<string>("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("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("Hutopy.Infrastructure.Identity.ApplicationUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.HasOne("Hutopy.Infrastructure.Identity.ApplicationUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", 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<string>", b =>
|
||||
{
|
||||
b.HasOne("Hutopy.Infrastructure.Identity.ApplicationUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Hutopy.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddUserTransactions : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "UserTransactions",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||
Amount = table.Column<decimal>(type: "decimal(18,2)", nullable: false),
|
||||
Currency = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
||||
TipMessage = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
||||
ApplicationUserId = table.Column<string>(type: "nvarchar(450)", nullable: false),
|
||||
Created = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: false),
|
||||
CreatedBy = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
||||
LastModified = table.Column<DateTimeOffset>(type: "datetimeoffset", nullable: false),
|
||||
LastModifiedBy = table.Column<string>(type: "nvarchar(max)", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_UserTransactions", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_UserTransactions_AspNetUsers_ApplicationUserId",
|
||||
column: x => x.ApplicationUserId,
|
||||
principalTable: "AspNetUsers",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_UserTransactions_ApplicationUserId",
|
||||
table: "UserTransactions",
|
||||
column: "ApplicationUserId");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "UserTransactions");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -69,6 +69,46 @@ namespace Hutopy.Infrastructure.Migrations
|
||||
b.ToTable("FutureCreators");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Hutopy.Domain.Entities.UserTransaction", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<decimal>("Amount")
|
||||
.HasColumnType("decimal(18,2)");
|
||||
|
||||
b.Property<string>("ApplicationUserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(450)");
|
||||
|
||||
b.Property<DateTimeOffset>("Created")
|
||||
.HasColumnType("datetimeoffset");
|
||||
|
||||
b.Property<string>("CreatedBy")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("Currency")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<DateTimeOffset>("LastModified")
|
||||
.HasColumnType("datetimeoffset");
|
||||
|
||||
b.Property<string>("LastModifiedBy")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("TipMessage")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ApplicationUserId");
|
||||
|
||||
b.ToTable("UserTransactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Hutopy.Infrastructure.Identity.ApplicationUser", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
@@ -275,6 +315,15 @@ namespace Hutopy.Infrastructure.Migrations
|
||||
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("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
using Hutopy.Domain.Interfaces;
|
||||
using System.Security.Claims;
|
||||
using Hutopy.Domain.Interfaces;
|
||||
using Hutopy.Domain.Models;
|
||||
using Hutopy.Infrastructure.Identity;
|
||||
using Microsoft.AspNetCore.Http.HttpResults;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
|
||||
namespace Hutopy.Infrastructure.Services;
|
||||
|
||||
public class UserService(UserManager<ApplicationUser> userManager) : IUserService
|
||||
public class UserService(UserManager<ApplicationUser> userManager, IHttpContextAccessor httpContextAccessor) : IUserService
|
||||
{
|
||||
private readonly UserManager<ApplicationUser> _userManager = userManager;
|
||||
|
||||
public async Task CreateUserAsync(string email, string userName, string firstName, string lastName, string password)
|
||||
{
|
||||
var applicationUser = new ApplicationUser
|
||||
@@ -21,7 +20,7 @@ public class UserService(UserManager<ApplicationUser> userManager) : IUserServic
|
||||
};
|
||||
|
||||
//todo: Need to handle errors better for the user.
|
||||
var response = await _userManager.CreateAsync(applicationUser, password);
|
||||
var response = await userManager.CreateAsync(applicationUser, password);
|
||||
|
||||
if (response.Errors.Any())
|
||||
{
|
||||
@@ -31,7 +30,7 @@ public class UserService(UserManager<ApplicationUser> userManager) : IUserServic
|
||||
|
||||
public async Task<UserModel?> FindUserByIdAsync(string id)
|
||||
{
|
||||
var response = await _userManager.FindByIdAsync(id);
|
||||
var response = await userManager.FindByIdAsync(id);
|
||||
|
||||
if (response == null) return null;
|
||||
|
||||
@@ -46,10 +45,21 @@ public class UserService(UserManager<ApplicationUser> userManager) : IUserServic
|
||||
|
||||
return userModel;
|
||||
}
|
||||
|
||||
public async Task<UserModel?> GetCurrentUserAsync()
|
||||
{
|
||||
var userId = httpContextAccessor.HttpContext?.User.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||
if (string.IsNullOrEmpty(userId))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return await FindUserByIdAsync(userId);
|
||||
}
|
||||
|
||||
public async Task<UserModel?> FindUserByEmailAsync(string email)
|
||||
{
|
||||
var response = await _userManager.FindByEmailAsync(email);
|
||||
var response = await userManager.FindByEmailAsync(email);
|
||||
|
||||
if (response == null) return null;
|
||||
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
using Stripe;
|
||||
using Stripe.Checkout;
|
||||
using Hutopy.Application.Common.Interfaces;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace Hutopy.Infrastructure.Stripe;
|
||||
|
||||
public class StripeService : IStripeService
|
||||
{
|
||||
public StripeService()
|
||||
{
|
||||
// I removed the key to push. Will need to be in config.
|
||||
StripeConfiguration.ApiKey = "";
|
||||
}
|
||||
public StripeService(IConfiguration configuration)
|
||||
{
|
||||
StripeConfiguration.ApiKey = configuration["STRIPE_API_KEY"];
|
||||
}
|
||||
|
||||
public async Task<string> CreateCheckoutSession(int price, string currency = "cad")
|
||||
{
|
||||
@@ -32,7 +32,7 @@ public class StripeService : IStripeService
|
||||
],
|
||||
Mode = "payment",
|
||||
UiMode = "embedded",
|
||||
ReturnUrl = $"http://localhost:5173/creatorfolio",
|
||||
ReturnUrl = $"https://zealous-bay-08204590f.5.azurestaticapps.net/paymentcompleted",
|
||||
};
|
||||
|
||||
var service = new SessionService();
|
||||
|
||||
17
src/Web/Endpoints/GetMyUser.cs
Normal file
17
src/Web/Endpoints/GetMyUser.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using Hutopy.Application.Users.Queries;
|
||||
|
||||
namespace Hutopy.Web.Endpoints;
|
||||
|
||||
public class GetMyUser : EndpointGroupBase
|
||||
{
|
||||
public override void Map(WebApplication app)
|
||||
{
|
||||
app.MapGroup(this)
|
||||
.MapGet(GetCurrentUser);
|
||||
}
|
||||
|
||||
private static async Task<UserDto> GetCurrentUser(ISender sender, [AsParameters] GetCurrentUserQuery query)
|
||||
{
|
||||
return await sender.Send(query);
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ public class Users : EndpointGroupBase
|
||||
.MapIdentityApi<ApplicationUser>();
|
||||
}
|
||||
|
||||
public async Task<Guid> CreateUser(ISender sender, CreateUserCommand command, IUserService userService)
|
||||
private static async Task<Guid> CreateUser(ISender sender, CreateUserCommand command, IUserService userService)
|
||||
{
|
||||
await userService.CreateUserAsync(command.EmailAddress, command.UserName, command.FirstName, command.LastName, command.Password);
|
||||
return await sender.Send(command);
|
||||
|
||||
@@ -6,6 +6,26 @@
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"paths": {
|
||||
"/api/GetMyUser": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"GetMyUser"
|
||||
],
|
||||
"operationId": "GetCurrentUser",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/UserDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/JoinUs": {
|
||||
"get": {
|
||||
"tags": [
|
||||
@@ -559,6 +579,44 @@
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"UserDto": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"format": "guid"
|
||||
},
|
||||
"firstName": {
|
||||
"type": "string"
|
||||
},
|
||||
"lastName": {
|
||||
"type": "string"
|
||||
},
|
||||
"userTransactions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/UserTransactionDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"UserTransactionDto": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"amount": {
|
||||
"type": "number",
|
||||
"format": "decimal"
|
||||
},
|
||||
"currency": {
|
||||
"type": "string"
|
||||
},
|
||||
"tipMessage": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"PaginatedListOfFutureCreatorListDto": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
@@ -631,15 +689,20 @@
|
||||
},
|
||||
"CreateSessionCheckoutCommand": {
|
||||
"type": "object",
|
||||
"x-abstract": true,
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"creatorId": {
|
||||
"type": "string"
|
||||
},
|
||||
"price": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"currency": {
|
||||
"type": "string"
|
||||
},
|
||||
"tipMessage": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user