订单微服务实体实现

This commit is contained in:
hello 2024-08-29 23:07:14 +08:00
parent b0b9491dfe
commit 2201f36422
69 changed files with 1042 additions and 67 deletions

View File

@ -3,7 +3,7 @@
var builder = DistributedApplication.CreateBuilder(args); var builder = DistributedApplication.CreateBuilder(args);
var cache = builder.AddRedis("cache", port:6379); var cache = builder.AddRedis("cache", port: 6379);
var identityService = builder.AddProject<Projects.HelloShop_IdentityService>("identityservice"); var identityService = builder.AddProject<Projects.HelloShop_IdentityService>("identityservice");

View File

@ -1,7 +1,7 @@
// Copyright (c) HelloShop Corporation. All rights reserved. // Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information. // See the license file in the project root for more information.
namespace HelloShop.IdentityService; namespace HelloShop.IdentityService.Authentication;
public class CustomJwtBearerDefaults public class CustomJwtBearerDefaults
{ {

View File

@ -5,7 +5,7 @@ using HelloShop.IdentityService.Entities;
using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
namespace HelloShop.IdentityService; namespace HelloShop.IdentityService.Authentication;
public static class CustomJwtBearerExtensions public static class CustomJwtBearerExtensions
{ {

View File

@ -10,7 +10,7 @@ using System.Security.Claims;
using System.Text; using System.Text;
using System.Text.Encodings.Web; using System.Text.Encodings.Web;
namespace HelloShop.IdentityService; namespace HelloShop.IdentityService.Authentication;
public class CustomJwtBearerHandler(IOptionsMonitor<CustomJwtBearerOptions> options, ILoggerFactory logger, UrlEncoder encoder) : SignInAuthenticationHandler<CustomJwtBearerOptions>(options, logger, encoder) public class CustomJwtBearerHandler(IOptionsMonitor<CustomJwtBearerOptions> options, ILoggerFactory logger, UrlEncoder encoder) : SignInAuthenticationHandler<CustomJwtBearerOptions>(options, logger, encoder)
{ {

View File

@ -4,7 +4,7 @@
using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
namespace HelloShop.IdentityService; namespace HelloShop.IdentityService.Authentication;
public class CustomJwtBearerOptions : AuthenticationSchemeOptions public class CustomJwtBearerOptions : AuthenticationSchemeOptions
{ {

View File

@ -6,7 +6,7 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using System.Security.Claims; using System.Security.Claims;
namespace HelloShop.IdentityService; namespace HelloShop.IdentityService.Authentication;
public class CustomUserClaimsPrincipalFactory<TUser, TRole>(UserManager<TUser> userManager, RoleManager<TRole> roleManager, IOptions<IdentityOptions> options) : UserClaimsPrincipalFactory<TUser, TRole>(userManager, roleManager, options) where TUser : IdentityUser<int> where TRole : IdentityRole<int> public class CustomUserClaimsPrincipalFactory<TUser, TRole>(UserManager<TUser> userManager, RoleManager<TRole> roleManager, IOptions<IdentityOptions> options) : UserClaimsPrincipalFactory<TUser, TRole>(userManager, roleManager, options) where TUser : IdentityUser<int> where TRole : IdentityRole<int>
{ {

View File

@ -2,7 +2,7 @@
// See the license file in the project root for more information. // See the license file in the project root for more information.
using HelloShop.IdentityService.Entities; using HelloShop.IdentityService.Entities;
using HelloShop.IdentityService.EntityFrameworks; using HelloShop.IdentityService.Infrastructure;
using HelloShop.ServiceDefaults.Authorization; using HelloShop.ServiceDefaults.Authorization;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Caching.Distributed;

View File

@ -1,7 +1,9 @@
// Copyright (c) HelloShop Corporation. All rights reserved. // Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information. // See the license file in the project root for more information.
using HelloShop.IdentityService.Authentication;
using HelloShop.IdentityService.Entities; using HelloShop.IdentityService.Entities;
using HelloShop.IdentityService.Models.Accounts;
using Microsoft.AspNetCore.Authentication.BearerToken; using Microsoft.AspNetCore.Authentication.BearerToken;
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Http.HttpResults; using Microsoft.AspNetCore.Http.HttpResults;
@ -13,7 +15,7 @@ using System.Diagnostics;
using System.IdentityModel.Tokens.Jwt; using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims; using System.Security.Claims;
namespace HelloShop.IdentityService; namespace HelloShop.IdentityService.Controllers;
[Route("api/[controller]")] [Route("api/[controller]")]
[ApiController] [ApiController]

View File

@ -2,7 +2,7 @@
// See the license file in the project root for more information. // See the license file in the project root for more information.
using HelloShop.IdentityService.Entities; using HelloShop.IdentityService.Entities;
using HelloShop.IdentityService.EntityFrameworks; using HelloShop.IdentityService.Infrastructure;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;

View File

@ -4,8 +4,9 @@
using AutoMapper; using AutoMapper;
using FluentValidation; using FluentValidation;
using HelloShop.IdentityService.Entities; using HelloShop.IdentityService.Entities;
using HelloShop.IdentityService.EntityFrameworks; using HelloShop.IdentityService.Infrastructure;
using HelloShop.IdentityService.Models.Users; using HelloShop.IdentityService.Models.Users;
using HelloShop.IdentityService.PermissionProviders;
using HelloShop.ServiceDefaults.Authorization; using HelloShop.ServiceDefaults.Authorization;
using HelloShop.ServiceDefaults.Extensions; using HelloShop.ServiceDefaults.Extensions;
using HelloShop.ServiceDefaults.Models.Paging; using HelloShop.ServiceDefaults.Models.Paging;

View File

@ -10,9 +10,9 @@ namespace HelloShop.IdentityService.DataSeeding
{ {
public class UserDataSeedingProvider(UserManager<User> userManager, RoleManager<Role> roleManager) : IDataSeedingProvider public class UserDataSeedingProvider(UserManager<User> userManager, RoleManager<Role> roleManager) : IDataSeedingProvider
{ {
public async Task SeedingAsync(IServiceProvider ServiceProvider) public async Task SeedingAsync(IServiceProvider ServiceProvider, CancellationToken cancellationToken = default)
{ {
var adminRole = await roleManager.Roles.SingleOrDefaultAsync(x => x.Name == "AdminRole"); var adminRole = await roleManager.Roles.SingleOrDefaultAsync(x => x.Name == "AdminRole", cancellationToken);
if (adminRole == null) if (adminRole == null)
{ {
@ -20,7 +20,7 @@ namespace HelloShop.IdentityService.DataSeeding
await roleManager.CreateAsync(adminRole); await roleManager.CreateAsync(adminRole);
} }
var guestRole = await roleManager.Roles.SingleOrDefaultAsync(x => x.Name == "GuestRole"); var guestRole = await roleManager.Roles.SingleOrDefaultAsync(x => x.Name == "GuestRole", cancellationToken: cancellationToken);
if (guestRole == null) if (guestRole == null)
{ {

View File

@ -4,7 +4,7 @@
using HelloShop.IdentityService.Entities; using HelloShop.IdentityService.Entities;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
namespace HelloShop.IdentityService.EntityFrameworks.EntityConfigurations; namespace HelloShop.IdentityService.Infrastructure.EntityConfigurations;
public class PermissionGrantedEntityTypeConfiguration : IEntityTypeConfiguration<PermissionGranted> public class PermissionGrantedEntityTypeConfiguration : IEntityTypeConfiguration<PermissionGranted>
{ {

View File

@ -5,7 +5,7 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace HelloShop.IdentityService.EntityFrameworks.EntityConfigurations namespace HelloShop.IdentityService.Infrastructure.EntityConfigurations
{ {
public class RoleClaimEntityTypeConfiguration : IEntityTypeConfiguration<IdentityRoleClaim<int>> public class RoleClaimEntityTypeConfiguration : IEntityTypeConfiguration<IdentityRoleClaim<int>>
{ {

View File

@ -5,7 +5,7 @@ using HelloShop.IdentityService.Entities;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace HelloShop.IdentityService.EntityFrameworks.EntityConfigurations namespace HelloShop.IdentityService.Infrastructure.EntityConfigurations
{ {
public class RoleEntityTypeConfiguration : IEntityTypeConfiguration<Role> public class RoleEntityTypeConfiguration : IEntityTypeConfiguration<Role>
{ {

View File

@ -5,7 +5,7 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace HelloShop.IdentityService.EntityFrameworks.EntityConfigurations namespace HelloShop.IdentityService.Infrastructure.EntityConfigurations
{ {
public class UserClaimEntityTypeConfiguration : IEntityTypeConfiguration<IdentityUserClaim<int>> public class UserClaimEntityTypeConfiguration : IEntityTypeConfiguration<IdentityUserClaim<int>>
{ {

View File

@ -5,7 +5,7 @@ using HelloShop.IdentityService.Entities;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace HelloShop.IdentityService.EntityFrameworks.EntityConfigurations namespace HelloShop.IdentityService.Infrastructure.EntityConfigurations
{ {
public class UserEntityTypeConfiguration : IEntityTypeConfiguration<User> public class UserEntityTypeConfiguration : IEntityTypeConfiguration<User>
{ {

View File

@ -5,7 +5,7 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace HelloShop.IdentityService.EntityFrameworks.EntityConfigurations namespace HelloShop.IdentityService.Infrastructure.EntityConfigurations
{ {
public class UserLoginEntityTypeConfiguration : IEntityTypeConfiguration<IdentityUserLogin<int>> public class UserLoginEntityTypeConfiguration : IEntityTypeConfiguration<IdentityUserLogin<int>>
{ {

View File

@ -4,7 +4,7 @@
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
namespace HelloShop.IdentityService.EntityFrameworks.EntityConfigurations namespace HelloShop.IdentityService.Infrastructure.EntityConfigurations
{ {
public class UserRoleEntityTypeConfiguration : IEntityTypeConfiguration<IdentityUserRole<int>> public class UserRoleEntityTypeConfiguration : IEntityTypeConfiguration<IdentityUserRole<int>>
{ {

View File

@ -5,7 +5,7 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace HelloShop.IdentityService.EntityFrameworks.EntityConfigurations namespace HelloShop.IdentityService.Infrastructure.EntityConfigurations
{ {
public class UserTokenEntityTypeConfiguration : IEntityTypeConfiguration<IdentityUserToken<int>> public class UserTokenEntityTypeConfiguration : IEntityTypeConfiguration<IdentityUserToken<int>>
{ {

View File

@ -6,7 +6,7 @@ using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System.Reflection; using System.Reflection;
namespace HelloShop.IdentityService.EntityFrameworks namespace HelloShop.IdentityService.Infrastructure
{ {
public class IdentityServiceDbContext(DbContextOptions<IdentityServiceDbContext> options) : IdentityDbContext<User, Role, int>(options) public class IdentityServiceDbContext(DbContextOptions<IdentityServiceDbContext> options) : IdentityDbContext<User, Role, int>(options)
{ {

View File

@ -1,6 +1,6 @@
// <auto-generated /> // <auto-generated />
using System; using System;
using HelloShop.IdentityService.EntityFrameworks; using HelloShop.IdentityService.Infrastructure;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;

View File

@ -1,6 +1,6 @@
// <auto-generated /> // <auto-generated />
using System; using System;
using HelloShop.IdentityService.EntityFrameworks; using HelloShop.IdentityService.Infrastructure;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Storage.ValueConversion;

View File

@ -1,6 +1,6 @@
```shell ```shell
dotnet ef database drop --force dotnet ef database drop --force
dotnet ef migrations remove dotnet ef migrations remove
dotnet ef migrations add InitialCreate --output-dir EntityFrameworks/Migrations dotnet ef migrations add InitialCreate --output-dir Infrastructure/Migrations
dotnet ef database update dotnet ef database update
``` ```

View File

@ -3,7 +3,7 @@
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace HelloShop.IdentityService; namespace HelloShop.IdentityService.Models.Accounts;
public class AccountLoginRequest public class AccountLoginRequest
{ {

View File

@ -1,7 +1,7 @@
// Copyright (c) HelloShop Corporation. All rights reserved. // Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information. // See the license file in the project root for more information.
namespace HelloShop.IdentityService; namespace HelloShop.IdentityService.Models.Accounts;
public class AccountRefreshRequest public class AccountRefreshRequest
{ {

View File

@ -1,7 +1,7 @@
// Copyright (c) HelloShop Corporation. All rights reserved. // Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information. // See the license file in the project root for more information.
namespace HelloShop.IdentityService; namespace HelloShop.IdentityService.Models.Accounts;
public class AccountRegisterRequest public class AccountRegisterRequest
{ {

View File

@ -1,7 +1,7 @@
// Copyright (c) HelloShop Corporation. All rights reserved. // Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information. // See the license file in the project root for more information.
namespace HelloShop.IdentityService; namespace HelloShop.IdentityService.Models.Users;
public class UserListItem public class UserListItem
{ {

View File

@ -3,7 +3,7 @@
using HelloShop.ServiceDefaults.Permissions; using HelloShop.ServiceDefaults.Permissions;
namespace HelloShop.IdentityService; namespace HelloShop.IdentityService.PermissionProviders;
public class IdentityPermissionDefinitionProvider : IPermissionDefinitionProvider public class IdentityPermissionDefinitionProvider : IPermissionDefinitionProvider
{ {

View File

@ -1,7 +1,7 @@
// Copyright (c) HelloShop Corporation. All rights reserved. // Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information. // See the license file in the project root for more information.
namespace HelloShop.IdentityService; namespace HelloShop.IdentityService.PermissionProviders;
public static class IdentityPermissions public static class IdentityPermissions
{ {

View File

@ -1,11 +1,11 @@
// Copyright (c) HelloShop Corporation. All rights reserved. // Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information. // See the license file in the project root for more information.
using HelloShop.IdentityService; using HelloShop.IdentityService.Authentication;
using HelloShop.IdentityService.Authorization; using HelloShop.IdentityService.Authorization;
using HelloShop.IdentityService.Constants; using HelloShop.IdentityService.Constants;
using HelloShop.IdentityService.Entities; using HelloShop.IdentityService.Entities;
using HelloShop.IdentityService.EntityFrameworks; using HelloShop.IdentityService.Infrastructure;
using HelloShop.ServiceDefaults.Authorization; using HelloShop.ServiceDefaults.Authorization;
using HelloShop.ServiceDefaults.Extensions; using HelloShop.ServiceDefaults.Extensions;
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authentication.JwtBearer;

View File

@ -3,7 +3,7 @@
using FluentValidation; using FluentValidation;
using HelloShop.IdentityService.Entities; using HelloShop.IdentityService.Entities;
using HelloShop.IdentityService.EntityFrameworks; using HelloShop.IdentityService.Infrastructure;
using HelloShop.IdentityService.Models.Users; using HelloShop.IdentityService.Models.Users;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization; using Microsoft.Extensions.Localization;

View File

@ -3,7 +3,7 @@
using FluentValidation; using FluentValidation;
using HelloShop.IdentityService.Entities; using HelloShop.IdentityService.Entities;
using HelloShop.IdentityService.EntityFrameworks; using HelloShop.IdentityService.Infrastructure;
using HelloShop.IdentityService.Models.Users; using HelloShop.IdentityService.Models.Users;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;

View File

@ -0,0 +1,12 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
namespace HelloShop.OrderingService.Constants
{
public class DbConstants
{
public const string MasterConnectionStringName = "OrderingDatabaseMaster";
public const string SlaveConnectionStringName = "OrderingDatabaseSlave";
}
}

View File

@ -0,0 +1,16 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
using HelloShop.OrderingService.Infrastructure;
using HelloShop.ServiceDefaults.Infrastructure;
namespace HelloShop.OrderingService.DataSeeding
{
public class OrderingDataSeedingProvider(OrderingServiceDbContext dbContext) : IDataSeedingProvider
{
public async Task SeedingAsync(IServiceProvider serviceProvider, CancellationToken cancellationToken = default)
{
await dbContext.Database.EnsureCreatedAsync(cancellationToken);
}
}
}

View File

@ -0,0 +1,14 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
namespace HelloShop.OrderingService.Entities.Buyers
{
public class Buyer
{
public int Id { get; set; }
public required string Name { get; set; }
public List<PaymentMethod>? PaymentMethods { get; set; }
}
}

View File

@ -0,0 +1,22 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
namespace HelloShop.OrderingService.Entities.Buyers
{
public class PaymentMethod
{
public int Id { get; set; }
public int BuyerId { get; set; }
public required string Alias { get; set; }
public required string CardNumber { get; set; }
public required string CardHolderName { get; set; }
public string? SecurityNumber { get; set; }
public DateTimeOffset? Expiration { get; set; }
}
}

View File

@ -0,0 +1,33 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
namespace HelloShop.OrderingService.Entities.Orders
{
public record Address
{
/// <summary>
/// 国家
/// </summary>
public required string Country { get; set; }
/// <summary>
/// 省份
/// </summary>
public required string State { get; set; }
/// <summary>
/// 城市
/// </summary>
public required string City { get; set; }
/// <summary>
/// 街道
/// </summary>
public required string Street { get; set; }
/// <summary>
/// 邮编
/// </summary>
public required string ZipCode { get; set; }
}
}

View File

@ -0,0 +1,40 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
using System.Diagnostics.CodeAnalysis;
namespace HelloShop.OrderingService.Entities.Orders
{
public class Order
{
public int Id { get; set; }
public DateTimeOffset OrderDate { get; private set; } = DateTimeOffset.UtcNow;
public required Address Address { get; init; }
public OrderStatus OrderStatus { get; set; } = OrderStatus.Submitted;
public int BuyerId { get; set; }
public int? PaymentMethodId { get; set; }
public required IReadOnlyCollection<OrderItem> OrderItems { get; init; }
public string? Description { get; set; }
/// <summary>
/// EF Core cannot set navigation properties using a constructor.
/// The constructor can be public, private, or have any other accessibility.
/// </summary>
private Order() { }
[SetsRequiredMembers]
public Order(int buyerId, Address address, IEnumerable<OrderItem> orderItems)
{
Address = address;
BuyerId = buyerId;
OrderItems = orderItems.ToList();
}
}
}

View File

@ -0,0 +1,22 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
namespace HelloShop.OrderingService.Entities.Orders
{
public class OrderItem
{
public int Id { get; set; }
public int OrderId { get; set; }
public int ProductId { get; set; }
public required string ProductName { get; set; }
public required string PictureUrl { get; set; }
public decimal UnitPrice { get; set; }
public int Units { get; set; }
}
}

View File

@ -0,0 +1,15 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
namespace HelloShop.OrderingService.Entities.Orders
{
public enum OrderStatus
{
Submitted = 1,
AwaitingValidation = 2,
StockConfirmed = 3,
Paid = 4,
Shipped = 5,
Cancelled = 6
}
}

View File

@ -0,0 +1,30 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
using HelloShop.OrderingService.Constants;
using HelloShop.OrderingService.Infrastructure;
using HelloShop.ServiceDefaults.Extensions;
using Microsoft.EntityFrameworkCore;
namespace HelloShop.OrderingService.Extensions
{
public static class Extensions
{
public static void AddApplicationServices(this IHostApplicationBuilder builder)
{
builder.Services.AddDataSeedingProviders();
builder.Services.AddDbContext<OrderingServiceDbContext>(options =>
{
options.UseNpgsql(builder.Configuration.GetConnectionString(DbConstants.MasterConnectionStringName));
});
}
public static WebApplication MapApplicationEndpoints(this WebApplication app)
{
app.UseDataSeedingProviders();
return app;
}
}
}

View File

@ -7,4 +7,12 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\HelloShop.ServiceDefaults\HelloShop.ServiceDefaults.csproj" /> <ProjectReference Include="..\HelloShop.ServiceDefaults\HelloShop.ServiceDefaults.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.8" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.8">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.4" />
</ItemGroup>
</Project> </Project>

View File

@ -0,0 +1,19 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
using HelloShop.OrderingService.Entities.Buyers;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace HelloShop.OrderingService.Infrastructure.EntityConfigurations.Buyers
{
public class BuyerEntityTypeConfiguration : IEntityTypeConfiguration<Buyer>
{
public void Configure(EntityTypeBuilder<Buyer> builder)
{
builder.ToTable("Buyer");
builder.Property(x => x.Name).HasMaxLength(16).IsRequired();
builder.HasMany(b => b.PaymentMethods).WithOne().HasForeignKey(x => x.BuyerId).OnDelete(DeleteBehavior.Cascade);
}
}
}

View File

@ -0,0 +1,22 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
using HelloShop.OrderingService.Entities.Buyers;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace HelloShop.OrderingService.Infrastructure.EntityConfigurations.Buyers
{
public class PaymentMethodEntityTypeConfiguration : IEntityTypeConfiguration<PaymentMethod>
{
public void Configure(EntityTypeBuilder<PaymentMethod> builder)
{
builder.ToTable("PaymentMethods");
builder.Property(x => x.Alias).HasMaxLength(16);
builder.Property(x => x.CardNumber).HasMaxLength(16);
builder.Property(x => x.CardHolderName).HasMaxLength(16);
builder.Property(x => x.SecurityNumber).HasMaxLength(6);
}
}
}

View File

@ -0,0 +1,34 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
using HelloShop.OrderingService.Entities.Buyers;
using HelloShop.OrderingService.Entities.Orders;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace HelloShop.OrderingService.Infrastructure.EntityConfigurations.Orders
{
public class OrderEntityTypeConfiguration : IEntityTypeConfiguration<Order>
{
public void Configure(EntityTypeBuilder<Order> builder)
{
builder.ToTable("Orders");
builder.Property(x => x.Description).HasMaxLength(64);
builder.Property(x => x.OrderStatus).HasConversion<string>();
builder.OwnsOne(x => x.Address, ownedAddress =>
{
ownedAddress.Property(x => x.Country).HasColumnName(nameof(Address.Country)).HasMaxLength(8).IsRequired();
ownedAddress.Property(x => x.State).HasColumnName(nameof(Address.State)).HasMaxLength(16).IsRequired();
ownedAddress.Property(x => x.City).HasColumnName(nameof(Address.City)).HasMaxLength(16).IsRequired();
ownedAddress.Property(x => x.Street).HasColumnName(nameof(Address.Street)).HasMaxLength(32).IsRequired();
ownedAddress.Property(x => x.ZipCode).HasColumnName(nameof(Address.ZipCode)).HasMaxLength(6).IsRequired();
});
builder.HasOne<Buyer>().WithMany().HasForeignKey(x => x.BuyerId).OnDelete(DeleteBehavior.Cascade);
builder.HasMany(x => x.OrderItems).WithOne().HasForeignKey(x => x.OrderId).OnDelete(DeleteBehavior.Cascade);
builder.HasOne<PaymentMethod>().WithMany().HasForeignKey(x => x.PaymentMethodId).OnDelete(DeleteBehavior.Restrict);
}
}
}

View File

@ -0,0 +1,20 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
using HelloShop.OrderingService.Entities.Orders;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace HelloShop.OrderingService.Infrastructure.EntityConfigurations.Orders
{
public class OrderItemEntityTypeConfiguration : IEntityTypeConfiguration<OrderItem>
{
public void Configure(EntityTypeBuilder<OrderItem> builder)
{
builder.ToTable("OrderItems");
builder.Property(x => x.ProductName).HasMaxLength(16);
builder.Property(x => x.PictureUrl).HasMaxLength(256);
}
}
}

View File

@ -0,0 +1,247 @@
// <auto-generated />
using System;
using HelloShop.OrderingService.Infrastructure;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace HelloShop.OrderingService.Infrastructure.Migrations
{
[DbContext(typeof(OrderingServiceDbContext))]
[Migration("20240829142135_InitialCreate")]
partial class InitialCreate
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.8")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("HelloShop.OrderingService.Entities.Buyers.Buyer", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(16)
.HasColumnType("character varying(16)");
b.HasKey("Id");
b.ToTable("Buyer", (string)null);
});
modelBuilder.Entity("HelloShop.OrderingService.Entities.Buyers.PaymentMethod", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Alias")
.IsRequired()
.HasMaxLength(16)
.HasColumnType("character varying(16)");
b.Property<int>("BuyerId")
.HasColumnType("integer");
b.Property<string>("CardHolderName")
.IsRequired()
.HasMaxLength(16)
.HasColumnType("character varying(16)");
b.Property<string>("CardNumber")
.IsRequired()
.HasMaxLength(16)
.HasColumnType("character varying(16)");
b.Property<DateTimeOffset?>("Expiration")
.HasColumnType("timestamp with time zone");
b.Property<string>("SecurityNumber")
.HasMaxLength(6)
.HasColumnType("character varying(6)");
b.HasKey("Id");
b.HasIndex("BuyerId");
b.ToTable("PaymentMethods", (string)null);
});
modelBuilder.Entity("HelloShop.OrderingService.Entities.Orders.Order", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("BuyerId")
.HasColumnType("integer");
b.Property<string>("Description")
.HasMaxLength(64)
.HasColumnType("character varying(64)");
b.Property<DateTimeOffset>("OrderDate")
.HasColumnType("timestamp with time zone");
b.Property<string>("OrderStatus")
.IsRequired()
.HasColumnType("text");
b.Property<int?>("PaymentMethodId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("BuyerId");
b.HasIndex("PaymentMethodId");
b.ToTable("Orders", (string)null);
});
modelBuilder.Entity("HelloShop.OrderingService.Entities.Orders.OrderItem", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("OrderId")
.HasColumnType("integer");
b.Property<string>("PictureUrl")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.Property<int>("ProductId")
.HasColumnType("integer");
b.Property<string>("ProductName")
.IsRequired()
.HasMaxLength(16)
.HasColumnType("character varying(16)");
b.Property<decimal>("UnitPrice")
.HasColumnType("numeric");
b.Property<int>("Units")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("OrderId");
b.ToTable("OrderItems", (string)null);
});
modelBuilder.Entity("HelloShop.OrderingService.Entities.Buyers.PaymentMethod", b =>
{
b.HasOne("HelloShop.OrderingService.Entities.Buyers.Buyer", null)
.WithMany("PaymentMethods")
.HasForeignKey("BuyerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("HelloShop.OrderingService.Entities.Orders.Order", b =>
{
b.HasOne("HelloShop.OrderingService.Entities.Buyers.Buyer", null)
.WithMany()
.HasForeignKey("BuyerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("HelloShop.OrderingService.Entities.Buyers.PaymentMethod", null)
.WithMany()
.HasForeignKey("PaymentMethodId")
.OnDelete(DeleteBehavior.Restrict);
b.OwnsOne("HelloShop.OrderingService.Entities.Orders.Address", "Address", b1 =>
{
b1.Property<int>("OrderId")
.HasColumnType("integer");
b1.Property<string>("City")
.IsRequired()
.HasMaxLength(16)
.HasColumnType("character varying(16)")
.HasColumnName("City");
b1.Property<string>("Country")
.IsRequired()
.HasMaxLength(8)
.HasColumnType("character varying(8)")
.HasColumnName("Country");
b1.Property<string>("State")
.IsRequired()
.HasMaxLength(16)
.HasColumnType("character varying(16)")
.HasColumnName("State");
b1.Property<string>("Street")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("character varying(32)")
.HasColumnName("Street");
b1.Property<string>("ZipCode")
.IsRequired()
.HasMaxLength(6)
.HasColumnType("character varying(6)")
.HasColumnName("ZipCode");
b1.HasKey("OrderId");
b1.ToTable("Orders");
b1.WithOwner()
.HasForeignKey("OrderId");
});
b.Navigation("Address")
.IsRequired();
});
modelBuilder.Entity("HelloShop.OrderingService.Entities.Orders.OrderItem", b =>
{
b.HasOne("HelloShop.OrderingService.Entities.Orders.Order", null)
.WithMany("OrderItems")
.HasForeignKey("OrderId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("HelloShop.OrderingService.Entities.Buyers.Buyer", b =>
{
b.Navigation("PaymentMethods");
});
modelBuilder.Entity("HelloShop.OrderingService.Entities.Orders.Order", b =>
{
b.Navigation("OrderItems");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,149 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace HelloShop.OrderingService.Infrastructure.Migrations
{
/// <inheritdoc />
public partial class InitialCreate : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Buyer",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(type: "character varying(16)", maxLength: 16, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Buyer", x => x.Id);
});
migrationBuilder.CreateTable(
name: "PaymentMethods",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
BuyerId = table.Column<int>(type: "integer", nullable: false),
Alias = table.Column<string>(type: "character varying(16)", maxLength: 16, nullable: false),
CardNumber = table.Column<string>(type: "character varying(16)", maxLength: 16, nullable: false),
CardHolderName = table.Column<string>(type: "character varying(16)", maxLength: 16, nullable: false),
SecurityNumber = table.Column<string>(type: "character varying(6)", maxLength: 6, nullable: true),
Expiration = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_PaymentMethods", x => x.Id);
table.ForeignKey(
name: "FK_PaymentMethods_Buyer_BuyerId",
column: x => x.BuyerId,
principalTable: "Buyer",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "Orders",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
OrderDate = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false),
Country = table.Column<string>(type: "character varying(8)", maxLength: 8, nullable: false),
State = table.Column<string>(type: "character varying(16)", maxLength: 16, nullable: false),
City = table.Column<string>(type: "character varying(16)", maxLength: 16, nullable: false),
Street = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
ZipCode = table.Column<string>(type: "character varying(6)", maxLength: 6, nullable: false),
OrderStatus = table.Column<string>(type: "text", nullable: false),
BuyerId = table.Column<int>(type: "integer", nullable: false),
PaymentMethodId = table.Column<int>(type: "integer", nullable: true),
Description = table.Column<string>(type: "character varying(64)", maxLength: 64, nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Orders", x => x.Id);
table.ForeignKey(
name: "FK_Orders_Buyer_BuyerId",
column: x => x.BuyerId,
principalTable: "Buyer",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_Orders_PaymentMethods_PaymentMethodId",
column: x => x.PaymentMethodId,
principalTable: "PaymentMethods",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "OrderItems",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
OrderId = table.Column<int>(type: "integer", nullable: false),
ProductId = table.Column<int>(type: "integer", nullable: false),
ProductName = table.Column<string>(type: "character varying(16)", maxLength: 16, nullable: false),
PictureUrl = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: false),
UnitPrice = table.Column<decimal>(type: "numeric", nullable: false),
Units = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_OrderItems", x => x.Id);
table.ForeignKey(
name: "FK_OrderItems_Orders_OrderId",
column: x => x.OrderId,
principalTable: "Orders",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_OrderItems_OrderId",
table: "OrderItems",
column: "OrderId");
migrationBuilder.CreateIndex(
name: "IX_Orders_BuyerId",
table: "Orders",
column: "BuyerId");
migrationBuilder.CreateIndex(
name: "IX_Orders_PaymentMethodId",
table: "Orders",
column: "PaymentMethodId");
migrationBuilder.CreateIndex(
name: "IX_PaymentMethods_BuyerId",
table: "PaymentMethods",
column: "BuyerId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "OrderItems");
migrationBuilder.DropTable(
name: "Orders");
migrationBuilder.DropTable(
name: "PaymentMethods");
migrationBuilder.DropTable(
name: "Buyer");
}
}
}

View File

@ -0,0 +1,244 @@
// <auto-generated />
using System;
using HelloShop.OrderingService.Infrastructure;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace HelloShop.OrderingService.Infrastructure.Migrations
{
[DbContext(typeof(OrderingServiceDbContext))]
partial class OrderingServiceDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.8")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("HelloShop.OrderingService.Entities.Buyers.Buyer", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(16)
.HasColumnType("character varying(16)");
b.HasKey("Id");
b.ToTable("Buyer", (string)null);
});
modelBuilder.Entity("HelloShop.OrderingService.Entities.Buyers.PaymentMethod", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Alias")
.IsRequired()
.HasMaxLength(16)
.HasColumnType("character varying(16)");
b.Property<int>("BuyerId")
.HasColumnType("integer");
b.Property<string>("CardHolderName")
.IsRequired()
.HasMaxLength(16)
.HasColumnType("character varying(16)");
b.Property<string>("CardNumber")
.IsRequired()
.HasMaxLength(16)
.HasColumnType("character varying(16)");
b.Property<DateTimeOffset?>("Expiration")
.HasColumnType("timestamp with time zone");
b.Property<string>("SecurityNumber")
.HasMaxLength(6)
.HasColumnType("character varying(6)");
b.HasKey("Id");
b.HasIndex("BuyerId");
b.ToTable("PaymentMethods", (string)null);
});
modelBuilder.Entity("HelloShop.OrderingService.Entities.Orders.Order", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("BuyerId")
.HasColumnType("integer");
b.Property<string>("Description")
.HasMaxLength(64)
.HasColumnType("character varying(64)");
b.Property<DateTimeOffset>("OrderDate")
.HasColumnType("timestamp with time zone");
b.Property<string>("OrderStatus")
.IsRequired()
.HasColumnType("text");
b.Property<int?>("PaymentMethodId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("BuyerId");
b.HasIndex("PaymentMethodId");
b.ToTable("Orders", (string)null);
});
modelBuilder.Entity("HelloShop.OrderingService.Entities.Orders.OrderItem", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("OrderId")
.HasColumnType("integer");
b.Property<string>("PictureUrl")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("character varying(256)");
b.Property<int>("ProductId")
.HasColumnType("integer");
b.Property<string>("ProductName")
.IsRequired()
.HasMaxLength(16)
.HasColumnType("character varying(16)");
b.Property<decimal>("UnitPrice")
.HasColumnType("numeric");
b.Property<int>("Units")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("OrderId");
b.ToTable("OrderItems", (string)null);
});
modelBuilder.Entity("HelloShop.OrderingService.Entities.Buyers.PaymentMethod", b =>
{
b.HasOne("HelloShop.OrderingService.Entities.Buyers.Buyer", null)
.WithMany("PaymentMethods")
.HasForeignKey("BuyerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("HelloShop.OrderingService.Entities.Orders.Order", b =>
{
b.HasOne("HelloShop.OrderingService.Entities.Buyers.Buyer", null)
.WithMany()
.HasForeignKey("BuyerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("HelloShop.OrderingService.Entities.Buyers.PaymentMethod", null)
.WithMany()
.HasForeignKey("PaymentMethodId")
.OnDelete(DeleteBehavior.Restrict);
b.OwnsOne("HelloShop.OrderingService.Entities.Orders.Address", "Address", b1 =>
{
b1.Property<int>("OrderId")
.HasColumnType("integer");
b1.Property<string>("City")
.IsRequired()
.HasMaxLength(16)
.HasColumnType("character varying(16)")
.HasColumnName("City");
b1.Property<string>("Country")
.IsRequired()
.HasMaxLength(8)
.HasColumnType("character varying(8)")
.HasColumnName("Country");
b1.Property<string>("State")
.IsRequired()
.HasMaxLength(16)
.HasColumnType("character varying(16)")
.HasColumnName("State");
b1.Property<string>("Street")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("character varying(32)")
.HasColumnName("Street");
b1.Property<string>("ZipCode")
.IsRequired()
.HasMaxLength(6)
.HasColumnType("character varying(6)")
.HasColumnName("ZipCode");
b1.HasKey("OrderId");
b1.ToTable("Orders");
b1.WithOwner()
.HasForeignKey("OrderId");
});
b.Navigation("Address")
.IsRequired();
});
modelBuilder.Entity("HelloShop.OrderingService.Entities.Orders.OrderItem", b =>
{
b.HasOne("HelloShop.OrderingService.Entities.Orders.Order", null)
.WithMany("OrderItems")
.HasForeignKey("OrderId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("HelloShop.OrderingService.Entities.Buyers.Buyer", b =>
{
b.Navigation("PaymentMethods");
});
modelBuilder.Entity("HelloShop.OrderingService.Entities.Orders.Order", b =>
{
b.Navigation("OrderItems");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,18 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
using Microsoft.EntityFrameworkCore;
using System.Reflection;
namespace HelloShop.OrderingService.Infrastructure
{
public partial class OrderingServiceDbContext(DbContextOptions<OrderingServiceDbContext> options) : DbContext(options)
{
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
}
}
}

View File

@ -0,0 +1,6 @@
```shell
dotnet ef database drop --force
dotnet ef migrations remove
dotnet ef migrations add InitialCreate --output-dir Infrastructure/Migrations
dotnet ef database update
```

View File

@ -1,27 +1,22 @@
// Copyright (c) HelloShop Corporation. All rights reserved. // Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information. // See the license file in the project root for more information.
using HelloShop.ServiceDefaults.Extensions; using HelloShop.OrderingService.Extensions;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
builder.AddServiceDefaults();
// Add services to the container. // Add services to the container.
builder.AddServiceDefaults();
builder.AddApplicationServices();
builder.Services.AddControllers(); builder.Services.AddControllers();
builder.Services.AddOpenApi();
var app = builder.Build(); var app = builder.Build();
// Configure the HTTP request pipeline.
app.MapDefaultEndpoints(); app.MapDefaultEndpoints();
app.UseAuthorization(); app.MapApplicationEndpoints();
app.UseCors(options => options.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
app.MapControllers(); app.MapControllers();
app.UseOpenApi();
app.Run(); app.Run();

View File

@ -5,5 +5,9 @@
"Microsoft.AspNetCore": "Warning" "Microsoft.AspNetCore": "Warning"
} }
}, },
"AllowedHosts": "*" "AllowedHosts": "*",
"ConnectionStrings": {
"OrderingDatabaseMaster": "Host=localhost;Port=5432;Database=OrderingService;Username=postgres;Password=postgres",
"OrderingDatabaseSlave": "Host=localhost;Port=5432;Database=OrderingService;Username=postgres;Password=postgres"
}
} }

View File

@ -3,7 +3,7 @@
using AutoMapper; using AutoMapper;
using HelloShop.ProductService.Entities.Products; using HelloShop.ProductService.Entities.Products;
using HelloShop.ProductService.EntityFrameworks; using HelloShop.ProductService.Infrastructure;
using HelloShop.ProductService.Models.Products; using HelloShop.ProductService.Models.Products;
using HelloShop.ProductService.PermissionProviders; using HelloShop.ProductService.PermissionProviders;
using HelloShop.ServiceDefaults.Extensions; using HelloShop.ServiceDefaults.Extensions;
@ -12,7 +12,7 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
namespace HelloShop.ProductService; namespace HelloShop.ProductService.Controllers;
[Route("api/[controller]")] [Route("api/[controller]")]
[ApiController] [ApiController]
public class BrandsController(ProductServiceDbContext dbContext, IMapper mapper) : ControllerBase public class BrandsController(ProductServiceDbContext dbContext, IMapper mapper) : ControllerBase

View File

@ -3,7 +3,7 @@
using AutoMapper; using AutoMapper;
using HelloShop.ProductService.Entities.Products; using HelloShop.ProductService.Entities.Products;
using HelloShop.ProductService.EntityFrameworks; using HelloShop.ProductService.Infrastructure;
using HelloShop.ProductService.Models.Products; using HelloShop.ProductService.Models.Products;
using HelloShop.ProductService.PermissionProviders; using HelloShop.ProductService.PermissionProviders;
using HelloShop.ServiceDefaults.Extensions; using HelloShop.ServiceDefaults.Extensions;
@ -12,7 +12,7 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
namespace HelloShop.ProductService; namespace HelloShop.ProductService.Controllers;
[Route("api/[controller]")] [Route("api/[controller]")]
[ApiController] [ApiController]

View File

@ -2,14 +2,14 @@
// See the license file in the project root for more information. // See the license file in the project root for more information.
using HelloShop.ProductService.Entities.Products; using HelloShop.ProductService.Entities.Products;
using HelloShop.ProductService.EntityFrameworks; using HelloShop.ProductService.Infrastructure;
using HelloShop.ServiceDefaults.Infrastructure; using HelloShop.ServiceDefaults.Infrastructure;
namespace HelloShop.ProductService.DataSeeding namespace HelloShop.ProductService.DataSeeding
{ {
public class ProductDataSeedingProvider(ProductServiceDbContext dbContext) : IDataSeedingProvider public class ProductDataSeedingProvider(ProductServiceDbContext dbContext) : IDataSeedingProvider
{ {
public async Task SeedingAsync(IServiceProvider ServiceProvider) public async Task SeedingAsync(IServiceProvider ServiceProvider, CancellationToken cancellationToken = default)
{ {
if (!dbContext.Set<Product>().Any()) if (!dbContext.Set<Product>().Any())
{ {
@ -82,16 +82,16 @@ namespace HelloShop.ProductService.DataSeeding
{ {
var brand = new Brand { Name = brandName }; var brand = new Brand { Name = brandName };
await dbContext.AddAsync(brand); await dbContext.AddAsync(brand, cancellationToken);
foreach (var product in productList) foreach (var product in productList)
{ {
product.Brand = brand; product.Brand = brand;
await dbContext.AddAsync(product); await dbContext.AddAsync(product, cancellationToken);
} }
} }
await dbContext.SaveChangesAsync(); await dbContext.SaveChangesAsync(cancellationToken);
} }
} }
} }

View File

@ -5,7 +5,7 @@ using HelloShop.ProductService.Entities.Products;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace HelloShop.ProductService.EntityFrameworks.EntityConfigurations.Products; namespace HelloShop.ProductService.Infrastructure.EntityConfigurations.Products;
public class BrandEntityTypeConfiguration : IEntityTypeConfiguration<Brand> public class BrandEntityTypeConfiguration : IEntityTypeConfiguration<Brand>
{ {

View File

@ -5,7 +5,7 @@ using HelloShop.ProductService.Entities.Products;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace HelloShop.ProductService.EntityFrameworks.EntityConfigurations.Products; namespace HelloShop.ProductService.Infrastructure.EntityConfigurations.Products;
public class ProductEntityTypeConfiguration : IEntityTypeConfiguration<Product> public class ProductEntityTypeConfiguration : IEntityTypeConfiguration<Product>
{ {

View File

@ -1,6 +1,6 @@
// <auto-generated /> // <auto-generated />
using System; using System;
using HelloShop.ProductService.EntityFrameworks; using HelloShop.ProductService.Infrastructure;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;

View File

@ -1,6 +1,6 @@
// <auto-generated /> // <auto-generated />
using System; using System;
using HelloShop.ProductService.EntityFrameworks; using HelloShop.ProductService.Infrastructure;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Storage.ValueConversion;

View File

@ -4,7 +4,7 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System.Reflection; using System.Reflection;
namespace HelloShop.ProductService.EntityFrameworks; namespace HelloShop.ProductService.Infrastructure;
public class ProductServiceDbContext(DbContextOptions<ProductServiceDbContext> options) : DbContext(options) public class ProductServiceDbContext(DbContextOptions<ProductServiceDbContext> options) : DbContext(options)
{ {

View File

@ -2,7 +2,7 @@
// See the license file in the project root for more information. // See the license file in the project root for more information.
using HelloShop.ProductService.Constants; using HelloShop.ProductService.Constants;
using HelloShop.ProductService.EntityFrameworks; using HelloShop.ProductService.Infrastructure;
using HelloShop.ServiceDefaults.Extensions; using HelloShop.ServiceDefaults.Extensions;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;

View File

@ -6,7 +6,7 @@ using HelloShop.ProductService.Entities.Products;
// Copyright (c) HelloShop Corporation. All rights reserved. // Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information. // See the license file in the project root for more information.
using HelloShop.ProductService.EntityFrameworks; using HelloShop.ProductService.Infrastructure;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
namespace HelloShop.ProductService.Services namespace HelloShop.ProductService.Services

View File

@ -7,6 +7,6 @@ namespace HelloShop.ServiceDefaults.Infrastructure
{ {
int Order => default; int Order => default;
Task SeedingAsync(IServiceProvider serviceProvider); Task SeedingAsync(IServiceProvider serviceProvider, CancellationToken cancellationToken = default);
} }
} }

View File

@ -1,7 +1,7 @@
// Copyright (c) HelloShop Corporation. All rights reserved. // Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information. // See the license file in the project root for more information.
using HelloShop.ProductService.EntityFrameworks; using HelloShop.ProductService.Infrastructure;
using HelloShop.ServiceDefaults.Authorization; using HelloShop.ServiceDefaults.Authorization;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.AspNetCore.Mvc.Testing;

View File

@ -3,7 +3,9 @@
using AutoMapper; using AutoMapper;
using HelloShop.ProductService.AutoMapper; using HelloShop.ProductService.AutoMapper;
using HelloShop.ProductService.Controllers;
using HelloShop.ProductService.Entities.Products; using HelloShop.ProductService.Entities.Products;
using HelloShop.ProductService.Infrastructure;
using HelloShop.ProductService.Models.Products; using HelloShop.ProductService.Models.Products;
using HelloShop.ProductService.UnitTests.Utilities; using HelloShop.ProductService.UnitTests.Utilities;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@ -16,7 +18,7 @@ namespace HelloShop.ProductService.UnitTests
public async Task GetProductByIdReturnsProductDetailsResponse() public async Task GetProductByIdReturnsProductDetailsResponse()
{ {
// Arrange // Arrange
await using EntityFrameworks.ProductServiceDbContext dbContext = new FakeDbContextFactory().CreateDbContext(); await using ProductServiceDbContext dbContext = new FakeDbContextFactory().CreateDbContext();
await dbContext.AddAsync(new Product { Id = 1, Name = "Product 1", Price = 10 }); await dbContext.AddAsync(new Product { Id = 1, Name = "Product 1", Price = 10 });
@ -40,7 +42,7 @@ namespace HelloShop.ProductService.UnitTests
public async Task PostProductReturnsProductDetailsResponse(string productName, decimal price) public async Task PostProductReturnsProductDetailsResponse(string productName, decimal price)
{ {
// Arrange // Arrange
await using EntityFrameworks.ProductServiceDbContext dbContext = new FakeDbContextFactory().CreateDbContext(); await using ProductServiceDbContext dbContext = new FakeDbContextFactory().CreateDbContext();
IMapper mapper = new MapperConfiguration(configure => configure.AddProfile<ProductsMapConfiguration>()).CreateMapper(); IMapper mapper = new MapperConfiguration(configure => configure.AddProfile<ProductsMapConfiguration>()).CreateMapper();

View File

@ -1,7 +1,7 @@
// Copyright (c) HelloShop Corporation. All rights reserved. // Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information. // See the license file in the project root for more information.
using HelloShop.ProductService.EntityFrameworks; using HelloShop.ProductService.Infrastructure;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
namespace HelloShop.ProductService.UnitTests.Utilities namespace HelloShop.ProductService.UnitTests.Utilities