초기커밋

This commit is contained in:
2025-05-01 07:20:41 +09:00
commit 98bb2e3c5c
2747 changed files with 646947 additions and 0 deletions

View File

@@ -0,0 +1,31 @@
namespace BrokerCore.ApiModels;
using System.ComponentModel;
using Swashbuckle.AspNetCore.Annotations;
public class DummyRequest
{
public required string Dummy { get; set; }
}
public class DummyResponse
{
public required string Dummy { get; set; }
}
[SwaggerSchema("유저 로그인 요청")]
public class LoginRequest
{
[Description("해당 플래닛 웹에서 런처로부터 받은 토큰")]
public string? WebPortalToken { get; set; }
}
[SwaggerSchema("유저 로그인 응답")]
public class LoginResponse
{
[Description("유저 guid")]
public required string UserGuid { get; set; }
[Description("유저 nickname")]
public required string Nickname { get; set; }
}

View File

@@ -0,0 +1,56 @@
namespace BrokerCore.ApiModels;
using System.ComponentModel;
using System.Text.Json.Serialization;
using Swashbuckle.AspNetCore.Annotations;
public class AdminSapphireChangeRequest
{
public string AccountId { get; set; } = string.Empty;
public string UserGuid { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
public required int SapphireDelta { get; set; }
}
public class AdminSapphireChangeResponse
{
public string AccountId { get; set; } = string.Empty;
public string UserGuid { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
public required int SapphireDelta { get; set; }
public long SapphireCurrentAmount { get; set; }
}
[SwaggerSchema(
"교환 주문 목록 요청 <br> - SsoAccountId 또는 UserGuid 중 하나를 선택해서 유저 구분 <br> - seasonId는 필수로 입력 (관련 내용은 사업부에 문의)")]
public class AdminItemExchangeOrderListRequest
{
[Description("SsoAccountId => sso의 accountId로 조회할 경우, UserGuid 불필요")]
public string SsoAccountId { get; init; } = string.Empty;
[Description("사용자 GUID => UserGuid으로 조회할 경우, SsoAccountId 불필요")]
public string UserGuid { get; init; } = string.Empty;
[Description("조회할 PlanetId => 웹 포탈에서 조회시 이기몹의 교환 정보를 얻으려면 반드시 igm26_iggymob을 명시해야함")]
public required string PlanetId { get; init; } = string.Empty;
[Description("시즌 아이디 => 이기몹 게임 시즌 이름으로 해당 시즌만 조회 (빈문자열 일 경우, 모두 조회)")]
public required string SeasonId { get; init; } = string.Empty;
[Description("플래닛 아이템 교환 메타 ID => 메타테이블의 ID (빈문자열 일 경우 모두 조회)")]
public required string ExchangeMetaId { get; init; }
[Description("조회 옵션 => 'All': 전체, 'Pending': 대기, 'Completed': 완료")]
[JsonConverter(typeof(JsonStringEnumConverter))]
public required FindOption Option { get; init; }
public DateTime? StartDate { get; init; }
public DateTime? EndDate { get; init; }
[Description("페이지 번호 (기본값:1)")] public int PageIndex { get; init; } = 1;
[Description("페이지 크기 (기본값:20)")] public int PageSize { get; init; } = 20;
[Description("정렬 기준 => asc: 오름차순, desc: 내림차순")]
public string SortOrder { get; init; } = "asc";
}

View File

@@ -0,0 +1,13 @@
namespace BrokerCore.ApiModels;
using System.ComponentModel;
public class ApiErrorResponse
{
[Description("에러 추척용 id")]
public required string TraceId { get; set; }
[Description("에러 코드")]
public int ErrorCode { get; set; } = (int)ServerErrorCode.InternalServerError;
[Description("에러 메시지")]
public string ErrorMessage { get; set; } = null!;
}

View File

@@ -0,0 +1,173 @@
using System.ComponentModel;
using Swashbuckle.AspNetCore.Annotations;
namespace BrokerCore.ApiModels;
using System.Runtime.Serialization;
using System.Text.Json.Serialization;
using Common;
using DbEntity;
using ServerCommon;
[SwaggerSchema("사파이어 잔액 요청")]
public class SapphireRequest
{
[Description("사용자 GUID")]
public required string UserGuid { get; init; }
}
[SwaggerSchema("사파이어 잔액 응답")]
public class SapphireResponse
{
[Description("사파이어 잔액")]
public required long Amount { get; init; }
}
[SwaggerSchema("교환 주문 정보")]
public class ExchangeOrder
{
[Description("주문 ID")]
public required string OrderId { get; init; }
[Description("사파이어 수량 - 삭제 예정"), SwaggerIgnore]
public long? SapphireAmount { get; init; }
[Description("사파이어 차감 수량")]
public required long SapphireReduceAmount { get; init; }
[Description("에메랄드 수량")]
public required long EmeraldAmount { get; init; }
[Description("주문 생성 시간")]
public required DateTime CreatedAt { get; init; }
[Description("주문 완료 시간")]
public DateTime? CompletedAt { get; init; }
[Description("주문 상태")]
public required ExchangeOrderStatus Status { get; init; }
}
[SwaggerSchema("칼리버스와 플래닛 간 재화 교환 주문 정보")]
public class CurrencyExchangeOrder
{
[Description("주문 ID")]
public required string OrderId { get; init; }
[Description("재화 타입 - ")]
public required CurrencyType CurrencyType { get; init; }
[Description("플래닛의 재화 변동 수량")]
public required long CurrencyDeltaAmount { get; init; }
[Description("재화 타입 - ")]
public required PlanetCurrencyType PlanetCurrencyType { get; init; }
[Description("플래닛의 재화 변동 수량")]
public required long PlanetCurrencyDeltaAmount { get; init; }
[Description("주문 생성 시간")]
public required DateTime CreatedAt { get; init; }
[Description("주문 완료 시간")]
public DateTime? CompletedAt { get; init; }
[Description("주문 상태")]
public required ExchangeOrderStatus Status { get; init; }
}
// [SwaggerSchema("조회 옵션")]
// [JsonConverter(typeof(JsonStringEnumConverter))]
[SwaggerSchema("조회 옵션 - 'All': 전체, 'Pending': 대기, 'Completed': 완료")]
public enum FindOption
{
[Description("전체 목록 조회")]
// [EnumMember(Value = "All")]
All = 0,
// [EnumMember(Value = "Pending")]
[Description("대기 중인 주문 조회")]
Pending = 1,
[Description("완료된 주문 조회")]
// [EnumMember(Value = "Completed")]
Completed = 2
}
[SwaggerSchema("교환 주문 목록 요청")]
public class ExchangeOrderListRequest
{
[Description("사용자 GUID")]
public required string UserGuid { get; init; }
[Description("조회 옵션 (0: 전체, 1: 대기, 2: 완료)")]
public required FindOption Option { get; init; }
[Description("페이지 번호")]
public int PageIndex { get; set; } = 1;
[Description("페이지 크기")]
public int PageSize { get; set; } = 20;
[Description("정렬 기준 => asc: 오름차순, desc: 내림차순")]
public string SortOrder { get; set; } = "asc";
}
[SwaggerSchema("교환 주문 목록 응답")]
public class ExchangeOrderListResponse
{
[Description("교환 주문 목록")]
public required IEnumerable<ExchangeOrder> Orders { get; init; }
}
[SwaggerSchema("교환 주문 요청")]
public class ExchangeOrderRequest
{
[Description("사용자 GUID")]
public required string UserGuid { get; set; }
[Description("차감을 요청할 사파이어 수량")]
public long Sapphire { get; set; }
[Description("요청할 에메랄드 수량")]
public long Emerald { get; set; }
}
[SwaggerSchema("교환 주문 응답")]
public class ExchangeOrderResponse
{
[Description("주문 ID")]
public required string OrderId { get; init; }
[Description("차감 사파이어 수량")]
public long SapphireAmount { get; init; }
[Description("에메랄드 수량")]
public long EmeraldAmount { get; init; }
[Description("현재 사파이어 잔액")]
public long CurrentSapphireBalance { get; init; }
}
[SwaggerSchema("교환 주문 완료 요청")]
public class ExchangeOrderCompleteRequest
{
[Description("주문 ID")]
public required string OrderId { get; set; }
[Description("사용자 GUID")]
public required string UserGuid { get; set; }
}
[SwaggerSchema("교환 주문 완료 응답")]
public class ExchangeOrderCompleteResponse
{
[Description("주문 ID")]
public required string OrderId { get; init; }
[Description("사파이어 수량")]
public long SapphireAmount { get; init; }
[Description("에메랄드 수량")]
public long EmeraldAmount { get; init; }
[Description("현재 주문 상태")]
public ExchangeOrderStatus Status { get; init; }
}

View File

@@ -0,0 +1,20 @@
namespace BrokerCore.ApiModels;
using System.ComponentModel;
using Swashbuckle.AspNetCore.Annotations;
[SwaggerSchema("플래닛 인증 요청")]
public class PlanetAuthRequest
{
[Description("플래닛 id (칼리버스에서 발급)")]
public string? PlanetId { get; set; }
[Description("플래닛의 시크릿 키 (칼리버스에서 발급)")]
public string? PlanetSecretKey { get; set; }
}
public class PlanetAuthResponse
{
[Description("업체 인증용 jwt 엑세스 토큰")]
public required string AccessToken { get; set; }
}

View File

@@ -0,0 +1,90 @@
namespace BrokerCore.ApiModels;
using System.ComponentModel;
using System.Text.Json.Serialization;
using Swashbuckle.AspNetCore.Annotations;
[SwaggerSchema("재화 잔액 요청")]
public class CurrencyBalanceRequest
{
[Description("칼리버스 재화 타입 : Sapphire (현재는 Sapphire 만 사용)")]
public string CaliverseCurrencyType { get; init; } = CurrencyType.Sapphire.ToString();
[Description("SsoAccountId - sso의 accountId로 조회할 경우, UserGuid 불필요")]
public string SsoAccountId { get; init; } = string.Empty;
[Description("사용자 GUID - UserGuid으로 조회할 경우, SsoAccountId 불필요")]
public string UserGuid { get; init; }
}
[SwaggerSchema("재화 잔액 응답")]
public class CurrencyBalanceResponse
{
[Description("칼리버스 재화 타입 : Sapphire (현재는 Sapphire 만 사용)")]
public string CaliverseCurrencyType { get; init; }
[Description("사용자 잔액")] public double Amount { get; init; }
}
[SwaggerSchema("아이템 교환 요청")]
public class PlanetItemExchangeRequest
{
[Description("사용자 GUID")] public required string UserGuid { get; init; }
[Description("시즌 아이디 => 이기몹 게임 시즌 이름 (사업부에 문의 - 테스트 시에는 아무거나 사용 가능)")]
public required string SeasonId { get; init; } = string.Empty;
[Description("플래닛 아이템 교환 메타 ID")] public required string ExchangeMetaId { get; init; }
[Description("플래닛 아이템 교환 메타 개수")] public required int ExchangeMetaAmount { get; init; }
}
[SwaggerSchema("아이템 교환 응답")]
public class PlanetItemExchangeResponse
{
[Description("교환 주문 정보")] public required PlanetItemExchangeOrderDto ExchangeOrder { get; init; }
}
[SwaggerSchema("아이템 교환 요청")]
public class PlanetItemExchangeCompleteRequest
{
[Description("사용자 GUID")] public required string UserGuid { get; init; }
[Description("플래닛 아이템 주문 ID")] public required string ExchangeOrderId { get; init; }
}
[SwaggerSchema(
"교환 주문 목록 요청 <br> - SsoAccountId 또는 UserGuid 중 하나를 선택해서 유저 구분 <br> - seasonId는 필수로 입력 (관련 내용은 사업부에 문의)")]
public class PlanetItemExchangeOrderListRequest
{
[Description("SsoAccountId => sso의 accountId로 조회할 경우, UserGuid 불필요")]
public string SsoAccountId { get; init; } = string.Empty;
[Description("사용자 GUID => UserGuid으로 조회할 경우, SsoAccountId 불필요")]
public string UserGuid { get; init; } = string.Empty;
[Description("조회할 PlanetId => 웹 포탈에서 조회시 이기몹의 교환 정보를 얻으려면 반드시 igm26_iggymob을 명시해야함")]
public required string PlanetId { get; init; } = string.Empty;
[Description("시즌 아이디 => 이기몹 게임 시즌 이름으로 해당 시즌만 조회 (빈문자열 일 경우, 모두 조회)")]
public required string SeasonId { get; init; } = string.Empty;
[Description("플래닛 아이템 교환 메타 ID => 메타테이블의 ID (빈문자열 일 경우 모두 조회)")]
public required string ExchangeMetaId { get; init; }
[Description("조회 옵션 => 'All': 전체, 'Pending': 대기, 'Completed': 완료")]
[JsonConverter(typeof(JsonStringEnumConverter))]
public required FindOption Option { get; init; }
[Description("페이지 번호 (기본값:1)")] public int PageIndex { get; init; } = 1;
[Description("페이지 크기 (기본값:20)")] public int PageSize { get; init; } = 20;
[Description("정렬 기준 => asc: 오름차순, desc: 내림차순")]
public string SortOrder { get; init; } = "asc";
}
[SwaggerSchema("교환 주문 목록 응답")]
public class PlanetItemExchangeOrderListResponse
{
[Description("교환 주문 목록")] public required IEnumerable<PlanetItemExchangeOrderDto> Orders { get; init; }
[Description("교환 주문 총 개수")] public required int TotalCount { get; init; }
}

View File

@@ -0,0 +1,34 @@
namespace BrokerCore.ApiModels;
using System.ComponentModel;
using System.Text.Json.Serialization;
using DbEntity;
using ServerCommon;
using Swashbuckle.AspNetCore.Annotations;
[SwaggerSchema("플래닛 아이템 교환 주문 정보")]
public class PlanetItemExchangeOrderDto
{
[Description("교환 주문 아이디")] public required string OrderId { get; init; }
[JsonConverter(typeof(JsonStringEnumConverter))]
[Description("교환 주문 상태")] public required ExchangeOrderStatus OrderStatus { get; set; }
[Description("시즌 아이디")] public string SeasonId { get; init; } = string.Empty;
[Description("플래닛 아이템 교환 메타 ID")] public required string ExchangeMetaId { get; set; }
[Description("플래닛 아이템 교환 메타 갯수")] public required long ExchangeMetaAmount { get; set; }
[Description("SSO 아이디")] public required string AccountId { get; init; }
[Description("유저 아이디")] public required string UserGuid { get; set; }
[Description("플래닛 아이디")] public required string PlanetId { get; set; }
[JsonConverter(typeof(JsonStringEnumConverter))]
[Description("칼리버스 아이템 타입")] public required CaliverseItemType CaliverseItemType { get; set; }
[Description("칼리버스 아이템 아이디")] public required string CaliverseItemId { get; set; }
[Description("칼리버스 아이템 증감 갯수")] public required long CaliverseItemDeltaAmount { get; set; }
[JsonConverter(typeof(JsonStringEnumConverter))]
[Description("플래닛 아이템 타입")] public required PlanetItemType PlanetItemType { get; set; }
[Description("플래닛 아이템 아이디")] public required string PlanetItemId { get; set; }
[Description("플래닛 아이템 증감 갯수")] public required long PlanetItemDeltaAmount { get; set; }
[Description("교환 주문 시작 시간")] public DateTime CreatedAt { get; set; }
[Description("교환 주문 완료 시간")] public DateTime? CompletedAt { get; set; }
}

View File

@@ -0,0 +1,39 @@
using System.ComponentModel;
using Swashbuckle.AspNetCore.Annotations;
namespace BrokerCore.ApiModels;
[SwaggerSchema("유저 사파이어 잔액 요청")]
public class UserSapphireRequest
{
}
[SwaggerSchema("유저 사파이어 잔액 응답")]
public class UserSapphireResponse
{
[Description("사파이어 잔액")]
public required long SapphireAmount { get; init; }
}
[SwaggerSchema("유저 교환 주문 목록 요청")]
public class UserExchangeOrderListRequest
{
[Description("플래닛 GUID")]
public required string PlanetId { get; init; }
[Description("조회 옵션 (0: 전체, 1: 대기, 2: 완료)")]
public required FindOption Option { get; init; }
[Description("페이지 번호")]
public int PageIndex { get; set; } = 1;
[Description("페이지 크기")]
public int PageSize { get; set; } = 20;
[Description("정렬 기준 => asc: 오름차순, desc: 내림차순")]
public string SortOrder { get; set; } = "asc";
}
[SwaggerSchema("유저 교환 주문 목록 응답")]
public class UserExchangeOrderListResponse
{
[Description("교환 주문 목록")]
public required IEnumerable<ExchangeOrder> Orders { get; init; }
}

View File

@@ -0,0 +1,65 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>
<!-- <PropertyGroup>-->
<!-- <TargetFramework>net8.0</TargetFramework>-->
<!-- <LangVersion>12</LangVersion>-->
<!-- <ImplicitUsings>enable</ImplicitUsings>-->
<!-- <Nullable>enable</Nullable>-->
<!-- <Configurations>Debug;Release;Shipping</Configurations>-->
<!-- <RootNamespace>BrokerCore</RootNamespace>-->
<!-- <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>-->
<!-- <AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>-->
<!-- <NoWarn>$(NoWarn);1591</NoWarn>-->
<!-- </PropertyGroup>-->
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DebugType>full</DebugType>
<OutputPath>..\..\bin\Debug\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DebugType>full</DebugType>
<OutputPath>..\..\bin\Release\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Shipping|AnyCPU'">
<DebugType>full</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\bin\Shipping\</OutputPath>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="NLog.Web.AspNetCore" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" />
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ServerCommon\ServerCommon.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Interfaces\" />
<Folder Include="Migrations\" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,27 @@
namespace BrokerCore.BrokerBusinessLog;
using Newtonsoft.Json;
using ServerBase;
public class PlanetProviderLogActor : IWithLogActor
{
// 로그 행위자 정보
public class LogActor : ILogActor
{
[JsonProperty] public ServerType ServerType { get; init; } = ServerType.BrokerApi;
[JsonProperty] public string PlanetId { get; init; } = string.Empty;
}
private readonly ILogActor m_log_actor;
public PlanetProviderLogActor(string planetId)
{
m_log_actor = new LogActor { PlanetId = planetId};
}
public ILogActor toLogActor()
{
return m_log_actor;
}
}

View File

@@ -0,0 +1,27 @@

using Newtonsoft.Json;
using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;
using ServerCore;
using ServerBase;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
using MetaAssets;
namespace BrokerCore.BrokerBusinessLog;
public class PlanetUserLogActor : ILogActor
{
[JsonProperty] public ServerType ServerType { get; init; } = ServerType.BrokerApi;
[JsonProperty] public string PlanetId { get; init; } = string.Empty; // 플래닛 아이디
[JsonProperty] public string AccountIdString { get; init; } = string.Empty; // 계정 식별 문자열
[JsonProperty] public string AccountId { get; init; } = string.Empty; // 계정 식별키
[JsonProperty] public string UserGuid { get; init; } = string.Empty; // 유저 식별키
[JsonProperty] public string UserNickname { get; init; } = string.Empty;
[JsonProperty] public AccountType AccountType { get; init; } = AccountType.None;
}

View File

@@ -0,0 +1,27 @@

using ServerBase;
using ServerCommon;
namespace BrokerCore.BrokerBusinessLog;
public class PlanetItemExchangeBusinessLog : ILogInvokerEx
{
private readonly PlanetItemExchangeLogData m_log_data;
public PlanetItemExchangeBusinessLog(LogActionEx logAction, PlanetItemExchangeLogData logData)
: base(LogDomainType.BrokerApi, logAction)
{
m_log_data = new PlanetItemExchangeLogData(this, logData);
}
protected override void fillup(ref BusinessLog.LogBody body)
{
body.append(m_log_data);
}
public override bool hasLog()
{
return true;
}
}

View File

@@ -0,0 +1,28 @@

using ServerBase;
using ServerCommon;
namespace BrokerCore.BrokerBusinessLog;
public class PlanetProviderAuthBusinessLog : ILogInvokerEx
{
private readonly PlanetProviderAuthLogData m_log_data;
public PlanetProviderAuthBusinessLog(LogActionEx logAction, PlanetProviderAuthLogData logData)
: base(LogDomainType.PlanetProviderAuth, logAction)
{
m_log_data = new PlanetProviderAuthLogData(this, logData);
}
protected override void fillup(ref BusinessLog.LogBody body)
{
body.append(m_log_data);
}
public override bool hasLog()
{
return true;
}
}

View File

@@ -0,0 +1,26 @@
using ServerBase;
using ServerCommon;
namespace BrokerCore.BrokerBusinessLog;
public class PlanetUserAuthBusinessLog : ILogInvokerEx
{
private readonly PlanetUserAuthLogData m_log_data;
public PlanetUserAuthBusinessLog(PlanetUserAuthLogData logData, LogActionType logActionType)
: base(LogDomainType.BrokerApi, new LogActionEx(logActionType))
{
m_log_data = new PlanetUserAuthLogData(this, logData);
}
protected override void fillup(ref BusinessLog.LogBody body)
{
body.append(m_log_data);
}
public override bool hasLog()
{
return true;
}
}

View File

@@ -0,0 +1,181 @@

using ServerCore;
using ServerBase;
using ServerCommon;
namespace BrokerCore;
using NLog.Config;
using MODULE_ID = System.UInt32;
public sealed class BrokerServerLogic : IServerLogic, IWithLogActor, IInitializer
{
private ServerProgramVersion m_server_program_version = new ServerProgramVersion();
private readonly DynamoDbClient m_dynamo_db_client = new();
private readonly ServerConfigMetaverseBroker m_server_config;
private readonly ServerType m_server_type = ServerType.BrokerApi;
private readonly string m_server_name = ServerType.BrokerApi.ToString();
private bool m_is_initialized = false;
public BrokerServerLogic(ServerConfigMetaverseBroker serverConfig)
{
m_server_config = serverConfig;
}
public IModule getModule(MODULE_ID moduleId) { throw new NullReferenceException(); }
public Result registerEntityTicker(EntityTicker entityTicker) { throw new NullReferenceException(); }
public async Task<Result> onInit()
{
if (m_is_initialized)
{
return new Result();
}
m_is_initialized = true;
Log.initLog(ServerType.BrokerApi.ToString(), "Developer", onNLogConfigurationChanged);
onInitBusinessLog();
var result = await onInitDynamoDb();
return result;
}
private async Task<Result> onInitDynamoDb()
{
var result = new Result();
var server_config = getServerConfig();
(var error_code, var to_load_table_names) = ServerConfigHelper.getDynamoDbTableNamesWithServiceType(server_config.ServiceType);
if (error_code.isFail())
{
var err_msg = $"Failed to DynamoDbClient.getDynamoDbTableNameWithServiceType() !!! : {server_config.toBasicString()} - {toBasicString()}";
result.setFail(error_code, err_msg);
Log.getLogger().error(err_msg);
return result;
}
var dynamo_db_client = getDynamoDbClient();
result = dynamo_db_client.connectToDb( to_load_table_names
, server_config.AWS.LocalDynamoDB, server_config.Dynamodb
, server_config.AWS.AccessKey, server_config.AWS.SecretKey, server_config.AWS.Region );
if (result.isFail())
{
Log.getLogger().error($"Failed to connectToDb !!! ");
return result;
}
if (false == await dynamo_db_client.createDBIfNotExists(false))
{
var err_msg = $"Failed to create DB Table !!! - {toBasicString()}";
result.setFail(ServerErrorCode.DynamoDbTableCreateFailed, err_msg);
Log.getLogger().fatal(result.toBasicString());
return result;
}
Log.getLogger().info($"Success ServerLogicBase.onInitDatabase() - {toBasicString()}");
return result;
}
private void onInitBusinessLog()
{
BusinessLogger.setup(new NLogAppender()
, new JsonText()
, LogTransToOutputType.TransToMultyLine);
Log.getLogger().info($"Success ServerLogicBase.onInitBusinessLog() - {toBasicString()}");
}
private void onNLogConfigurationChanged(object? sender, LoggingConfigurationChangedEventArgs e)
{
var result = new Result();
var err_msg = string.Empty;
var server_config = getServerConfig();
if (server_config.AWS.CloudWatchLog.Enable)
{
result = setupCloudwatchLog(server_config);
if (result.isFail())
{
err_msg = $"Failed to setupCloudwatchLog() !!! in onNLogConfigurationChanged() : {result.toBasicString()} - {toBasicString()}";
Log.getLogger().fatal(err_msg);
}
}
return;
Result setupCloudwatchLog(ServerConfig serverConfig)
{
var result = new Result();
var err_msg = string.Empty;
if(false == CloudWatchLog.isOpened())
{
return result;
}
if (false == CloudWatchLog.setup( serverConfig.AWS.CloudWatchLog.CloudWatchLogGroup
, serverConfig.AWS.CloudWatchLog.CloudWatchLogNamePattern
, serverConfig.AWS.CloudWatchLog.CloudWatchLogLevel
, serverConfig.AWS.Region
, serverConfig.AWS.AccessKey
, serverConfig.AWS.SecretKey
, serverConfig.AWS.CloudWatchLog.CloudWatchLogLayout) )
{
err_msg = $"Failed to CloudWatchLog.setup() !!! - {toBasicString()}";
result.setFail(ServerErrorCode.NlogWithAwsCloudWatchSetupFailed, err_msg);
Log.getLogger().fatal(result.toBasicString());
return result;
}
return result;
}
}
public ILogActor toLogActor()
{
var log_info = new LogicActorLog();
log_info.initLogInfo(
this.getServerConfig().getRegionId()
, this.getServerConfig().getWorldId()
, this.getServerType().toServerType()
, this.getServerName()
);
return log_info;
}
public string toBasicString()
{
return $"{m_server_name}({m_server_type})";
}
public string getServerType()
{
return m_server_type.ToString();
}
public string getServerName()
{
return m_server_name;
}
public ServerConfig getServerConfig()
{
return m_server_config;
}
public RedisConnector getRedisConnector()
{
throw new NotImplementedException();
}
public DynamoDbClient getDynamoDbClient()
{
return m_dynamo_db_client;
}
}

View File

@@ -0,0 +1,15 @@
namespace BrokerCore.Common;
public class ApiException: Exception
{
public int ErrorCode { get; init; }
public ApiException(int errorCode, string message) : base(message)
{
ErrorCode = errorCode;
}
public ApiException(ServerErrorCode errorCode, string message) : base(message)
{
ErrorCode = (int)errorCode;
}
}

View File

@@ -0,0 +1,27 @@
namespace BrokerCore.Common;
using ApiModels;
using DbEntity;
public static class ApiExtensions
{
public static PlanetItemExchangeOrderDto toDto( this PlanetItemExchangeOrder order ) => new()
{
OrderId = order.OrderId,
OrderStatus = order.OrderStatus,
ExchangeMetaId = order.ExchangeMetaId,
ExchangeMetaAmount = order.ExchangeMetaAmount,
AccountId = order.AccountId,
UserGuid = order.UserGuid,
PlanetId = order.PlanetId,
CaliverseItemType = order.CaliverseItemType,
CaliverseItemId = order.CaliverseItemId,
CaliverseItemDeltaAmount = order.CaliverseItemDeltaAmount,
PlanetItemType = order.PlanetItemType,
PlanetItemId = order.PlanetItemId,
PlanetItemDeltaAmount = order.PlanetItemDeltaAmount,
CreatedAt = order.CreatedAt,
CompletedAt = order.CompletedAt
};
}

View File

@@ -0,0 +1,139 @@
using System;
using System.Diagnostics.CodeAnalysis;
using ServerCore;
using ServerBase;
using ServerCommon;
namespace BrokerCore.Common;
public static class Guard
{
public static class Against
{
// 기존 메서드를 유지하면서 zero allocation 버전 추가
public static void resultFail(Result result, Func<string>? messageFactory = null)
{
if (result.isFail())
{
throw new ResultFailException(result, messageFactory?.Invoke());
}
}
// Func<string> 활용 지연 평가 버전 추가
// public static void resultFail(Result result, Func<string> messageFactory)
// {
// if (result.isFail())
// {
// throw new ResultFailException(result, messageFactory());
// }
// }
public static void resultFail(Result result, ServerErrorCode code, string message)
{
if (result.isFail())
{
throw new ResultFailException(code, message);
}
}
// Func<string> 활용 지연 평가 버전 추가
public static void resultFail(Result result, ServerErrorCode code, Func<string> messageFactory)
{
if (result.isFail())
{
throw new ResultFailException(code, messageFactory());
}
}
public static void isNull([NotNull] object? value, ServerErrorCode code, string message)
{
if (value is null)
{
throw new ApiException(code, message);
}
}
// Func<string> 활용 지연 평가 버전 추가
public static void isNull([NotNull] object? value, ServerErrorCode code, Func<string> messageFactory)
{
if (value is null)
{
throw new ApiException(code, messageFactory());
}
}
public static void isFalse(bool value, ServerErrorCode code, string message)
{
if (!value)
{
throw new ApiException(code, message);
}
}
// Func<string> 활용 지연 평가 버전 추가
public static void isFalse(bool value, ServerErrorCode code, Func<string> messageFactory)
{
if (!value)
{
throw new ApiException(code, messageFactory());
}
}
public static void isTrue(bool value, ServerErrorCode code, string message)
{
if (value)
{
throw new ApiException(code, message);
}
}
// Func<string> 활용 지연 평가 버전 추가
public static void isTrue(bool value, ServerErrorCode code, Func<string> messageFactory)
{
if (value)
{
throw new ApiException(code, messageFactory());
}
}
public static void isNullOrEmptyOrWhiteSpace([NotNull] string? value, ServerErrorCode code, string message)
{
if (value is null || string.IsNullOrEmpty(value) || string.IsNullOrWhiteSpace(value))
{
throw new ApiException(code, message);
}
}
// Func<string> 활용 지연 평가 버전 추가
public static void isNullOrEmptyOrWhiteSpace([NotNull] string? value, ServerErrorCode code, Func<string> messageFactory)
{
if (value is null || string.IsNullOrEmpty(value) || string.IsNullOrWhiteSpace(value))
{
throw new ApiException(code, messageFactory());
}
}
// ReadOnlySpan<char> 버전 추가
public static void isNullOrEmptyOrWhiteSpace([NotNull] string? value, ServerErrorCode code, ReadOnlySpan<char> message)
{
if (value is null || string.IsNullOrEmpty(value) || string.IsNullOrWhiteSpace(value))
{
throw new ApiException(code, message.ToString());
}
}
public static void throwException(ServerErrorCode code, string message)
{
throw new ApiException((int)code, message);
}
// Func<string> 활용 지연 평가 버전 추가
public static void throwException(ServerErrorCode code, Func<string> messageFactory)
{
throw new ApiException((int)code, messageFactory());
}
}
}

View File

@@ -0,0 +1,92 @@
namespace BrokerCore.Common;
using System.Security.Cryptography;
using BrokerBusinessLog;
using DbEntity;
using Entity.Actions;
using MetaAssets;
using ServerCommon;
using ServerCore; using ServerBase;
public class Helpers
{
public static string generateSecureKey(int keySizeInBytes = 32, bool isBase64 = true)
{
// 32바이트는 256비트 키를 의미합니다. (AES-256과 같은 암호화 알고리즘에 적합)
using var random_number_generator = RandomNumberGenerator.Create();
byte[] key = new byte[keySizeInBytes];
random_number_generator.GetBytes(key);
return isBase64 ? Convert.ToBase64String(key) : Convert.ToHexString(key);
}
public static MailSendOption createMailOptionByProductMeta(
ProductMetaData productMeta,
SystemMailMetaData mailMeta,
string receiverUserGuid,
string receiverNickName)
{
DateTime now = DateTimeHelper.Current;
var expire_date = now.AddSeconds(MetaHelper.GameConfigMeta.SystemMailStoragePeriod);
// if (productMeta.Storage_Period_First != 0)
// {
// expire_date = DateTime.UtcNow.AddMinutes(productMeta.Storage_Period_First);
// }
var mail_send_option = new MailSendOption
{
ReceiverUserGuid = receiverUserGuid,
ReceiverNickName = receiverNickName,
IsSystemMail = true,
IsTextByMetaData = true,
Title = mailMeta.Mail_Title,
Text = mailMeta.Mail_Desc,
ExpireDate = expire_date,
ItemList = getMailItems(productMeta).ToList(),
PackageOrderId = string.Empty,
};
return mail_send_option;
}
public static IEnumerable<MailItem> getMailItems(ProductMetaData productMetaData)
{
if (productMetaData.ItemID_First != 0)
{
return productMetaData.First_List.Select(itemMeta => new MailItem()
{
ItemId = (UInt32)itemMeta.Id,
Count = itemMeta.Value,
ProductId = (UInt32)productMetaData.Id,
isRepeatProduct = false
});
}
return new List<MailItem>();
}
public static PlanetItemExchangeLogData createFromExchangeOrderLog(PlanetItemExchangeOrder order)
{
return new PlanetItemExchangeLogData
{
OrderId = order.OrderId,
OrderStatus = order.OrderStatus.ToString(),
ExchangeMetaId = order.ExchangeMetaId,
ExchangeMetaAmount = order.ExchangeMetaAmount,
AccountId = order.AccountId,
UserGuid = order.UserGuid,
PlanetId = order.PlanetId,
SeasonId = order.SeasonId,
CaliverseItemType = order.CaliverseItemType.ToString(),
CaliverseItemId = order.CaliverseItemId,
CaliverseItemDeltaAmount = order.CaliverseItemDeltaAmount,
PlanetItemType = order.PlanetItemType.ToString(),
PlanetItemId = order.PlanetItemId,
PlanetItemDeltaAmount = order.PlanetItemDeltaAmount,
CreatedAt = order.CreatedAt,
CompletedAt = order.CompletedAt
};
}
}

View File

@@ -0,0 +1,12 @@
//==============================================================
// JWT 설정 정보를 담고있는 클래스입니다.
//==============================================================
namespace BrokerCore.Common;
public class JwtOption
{
public string ValidIssuer { get; set; } = string.Empty;
public string ValidAudience { get; set; } = string.Empty;
public required string Secret { get; init; } // JWT 토큰 서명에 사용되는 비밀키
public int TokenValidityInMinutes { get; init; } = 1440; // 토큰의 유효 기간(분)
public string JwtTestPassToken => "p8qcZBraFCGfm2QeIGkJBynb6ULKhi6wGlnCDXvKTnM";
}

View File

@@ -0,0 +1,12 @@
namespace BrokerCore.Common;
public class ResultFailException : ApiException
{
public ResultFailException(Result result, string? message = null) : base((int)result.ErrorCode,
message ?? result.ResultString)
{
}
public ResultFailException(ServerErrorCode code, string message) : base((int)code, message)
{
}
}

View File

@@ -0,0 +1,13 @@
namespace BrokerCore.DbEntity;
public class PlanetInfo
{
public required string PlanetId { get; init; } // 플래닛 이름
public required string PlanetName { get; init; }
public required string CompanyName { get; init; } // 플래닛 GUID
public required string SecretKey { get; init; } // 플래닛 비밀키 - 칼리버스에서 발급함
public required string ServerType { get; init; } // 에코 시스템에 넘길 serverType
public string Description { get; init; } = "";
public DateTime CreatedAt { get; init; } // 생성 시간
public DateTime UpdatedAt { get; set; } // 수정 시간
}

View File

@@ -0,0 +1,28 @@
namespace BrokerCore.DbEntity;
using ServerCommon;
//================================================================================
// 교환 거래 주문 정보
//================================================================================
public class PlanetItemExchangeOrder
{
public required string OrderId { get; init; } // = Guid.NewGuid().ToString("N"); // 교환 주문 아이디 guid
public required ExchangeOrderStatus OrderStatus { get; set; } // 교환 주문 상태
public string SeasonId { get; set; } = string.Empty; // 시즌 아이디
public required string ExchangeMetaId { get; set; } // 교환 메타 아이디
public required int ExchangeMetaAmount {get; set;} // 교환 메타 수량
public required string AccountId { get; init; } // sso 아이디
public required string UserGuid { get; set; } // 유저 아이디
public required string Nickname { get; set; } // 유저 닉네임
public required string PlanetId { get; set; } // 플래닛 아이디
public required CaliverseItemType CaliverseItemType { get; set; } // 칼리버스 아이템 타입
public required string CaliverseItemId { get; set; } // 칼리버스 아이템 아이디
public required int CaliverseItemDeltaAmount { get; set; } // 칼리버스 아이템 갯수
public required PlanetItemType PlanetItemType { get; set; } // 칼리버스
public required string PlanetItemId { get; set; }
public required int PlanetItemDeltaAmount { get; set; }
public DateTime CreatedAt { get; set; } // 교환 주문 시작 db 시간
public DateTime? CompletedAt { get; set; } = null; // 교환 주문 완료 시간
}

View File

@@ -0,0 +1,11 @@
namespace BrokerCore.DbEntity;
public class PlanetItemExchangeOrderAmountTotalLimit
{
public required string ExchangeMetaId { get; set; } // 교환 메타 아이디
public required DateOnly ExchangeDate { get; set; } // 교환 일자
public required string SeasonId { get; set; } // 시즌 아이디
public required int DailyAmount { get; set; } // 교환 메타 수량
public DateTime CreatedAt { get; set; } = DateTime.UtcNow; // 생성일
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow; // 수정일
}

View File

@@ -0,0 +1,12 @@
namespace BrokerCore.DbEntity;
public class PlanetItemExchangeOrderAmountUserLimit
{
public required string ExchangeMetaId { get; set; } // 교환 메타 아이디
public required DateOnly ExchangeDate { get; set; } // 교환 일자
public required string SeasonId { get; set; } // 시즌 아이디
public required string UserGuid { get; set; } // 유저 아이디
public required int DailyAmount { get; set; } // 교환 메타 수량
public DateTime CreatedAt { get; set; } = DateTime.UtcNow; // 생성일
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow; // 수정일
}

View File

@@ -0,0 +1,24 @@
namespace BrokerCore.DbEntity;
public enum ExchangeOrderStatus
{
// Init = 0,
Pending = 1,
Completed = 2,
}
//================================================================================
// 사파이어 교환 거래 시 플랫폼의 주문 db와 무결성을 처리하기 위한 보관소
//================================================================================
public class SapphireExchangeOrder
{
public required string OrderId { get; init; } // 사파이어 교환 주문 아이디 guid
public required ulong AccountId { get; init; } // sso 아이디
public required ExchangeOrderStatus OrderStatus { get; set; } // 사파이어 교환 주문 상태
public required string UserGuid { get; set; } // 유저 아이디
public required string PlanetId { get; set; } // 플래닛 아이디
public long SapphireReducedDelta { get; set; } // 사파이어 차감 수량
public long PlanetMoneyIncDelta { get; set; } // 플래닛에서 발급한 재화 수량
public DateTime CreatedAt { get; set; } // 사파이어 교환 주문 시작 시간
public DateTime? CompletedAt { get; set; } // 사파이어 교환 주문 완료 시간
}

View File

@@ -0,0 +1,12 @@
namespace BrokerCore.DbEntity;
using Microsoft.EntityFrameworkCore;
[Keyless]
public class SsoAccountInfo
{
public ulong Id { get; init; }
public ulong? AccessToken { get; init; }
public ulong? AccessTokenIgm { get; init; }
public string? Email { get; init; } = string.Empty;
}

View File

@@ -0,0 +1,277 @@
using System.Text;
using BrokerCore.BrokerBusinessLog;
using ServerCommon;
using ServerCore; using ServerBase;
namespace BrokerCore.Entity.Actions;
using MetaAssets;
using ServerCommon.BusinessLogDomain;
public class BrokerMailSendAction : EntityActionBase
{
private readonly DynamoDbClient m_dynamo_db_client;
public BrokerMailSendAction(EntityBase owner, DynamoDbClient dynamoDbClient) : base(owner)
{
m_dynamo_db_client = dynamoDbClient;
}
public override void onClear()
{
}
public override Task<Result> onInit()
{
return Task.FromResult(new Result());
}
string makeMailGuid(DateTime now)
{
var guid = Guid.NewGuid().ToString("N");
return $"{now.ToString("yyyy/MM/dd/HH:mm:ss:ff")}-{guid}";
}
private void setMailAttribute(MailSendOption option)
{
DateTime now = DateTimeHelper.Current;
var expire_date = now.AddSeconds(MetaHelper.GameConfigMeta.SystemMailStoragePeriod);
string mail_guid = makeMailGuid(now);
var mail_attribute = getOwner().getEntityAttributeNotNull<MailAttribute>();
mail_attribute.MailGuid = mail_guid;
mail_attribute.SenderNickName = option.SenderNickName;
mail_attribute.SenderGuid = option.SenderGuid;
mail_attribute.ReceiverNickName = option.ReceiverNickName;
mail_attribute.ReceiverGuid = option.ReceiverUserGuid;
mail_attribute.Title = option.Title;
mail_attribute.Text = option.Text;
mail_attribute.CreateTime = now;
mail_attribute.ExpireTime = expire_date;
mail_attribute.IsSystemMail = option.IsSystemMail;
mail_attribute.IsRead = false;
mail_attribute.IsGetItem = false;
mail_attribute.IsTextByMetaData = option.IsTextByMetaData;
mail_attribute.ItemList = option.ItemList;
mail_attribute.newEntityAttribute();
}
public async Task<Result> sendMail(MailSendOption mailSendOption, Func<Task> operationSuccess,
Func<Task> operationFail)
{
var result = new Result();
var user_guid = mailSendOption.ReceiverUserGuid;
StringBuilder str_builder = new();
str_builder.Append($"guid : {user_guid}, nickname : {mailSendOption.ReceiverNickName}");
str_builder.Append($" accountId : {mailSendOption.AccountId}");
setMailAttribute(mailSendOption);
var (doc_result, doc) = await getOwner().getEntityAttributeNotNull<MailAttribute>().toDocBase()!;
if (doc_result.isFail() || doc is null)
{
Log.getLogger().error($"fail create system mail, {str_builder.ToString()}");
return doc_result;
}
var mail_doc = doc as ReceivedMailDoc;
NullReferenceCheckHelper.throwIfNull(mail_doc,
() => $"mail_doc is null !!! - receiverUserGuid:{mailSendOption.ReceiverUserGuid}");
var log_actor = getOwner() as IWithLogActor;
NullReferenceCheckHelper.throwIfNull(log_actor,
() => $"log_actor is null !!! - receiverUserGuid:{mailSendOption.ReceiverUserGuid}");
var batch = new QueryBatchEx<QueryRunnerWithDocument>(log_actor, LogActionType.MailSend, m_dynamo_db_client,
true);
batch.addQuery(new DBQEntityWrite(mail_doc));
batch.addQuery(new QueryFinal(),
async (query) =>
{
// actionSuccess 실행하기
await operationSuccess();
return QueryBatchBase.QueryResultType.Success;
},
async (query, errorResult) =>
{
await operationFail();
return QueryBatchBase.QueryResultType.QueryFailed;
}
);
var query_result = await batch.doQueryWithStopwatch();
if (query_result.isFail())
{
Log.getLogger().error($"broker system mail send error, {str_builder.ToString()}");
return query_result;
}
var mail_attrib = mail_doc.getAttrib<MailAttrib>();
NullReferenceCheckHelper.throwIfNull(mail_attrib,
() => $"mail_attrib is null !!! - receiverUserGuid:{mailSendOption.ReceiverUserGuid}");
// 비즈니스 로그 작성
var log_data = new MailLogData();
setMailData(log_data, mail_attrib);
BusinessLogger.collectLog(log_actor, new MailBusinessLog(log_data));
Log.getLogger().info($"system mail send success, {str_builder.ToString()}");
return result;
}
private void setMailData(in MailLogData logData, in MailAttrib mailAttrib)
{
logData.MailGuid = mailAttrib.MailGuid;
logData.Title = mailAttrib.Title;
logData.Text = mailAttrib.Text;
logData.IsSystemMail = mailAttrib.IsSystemMail;
logData.IsReadMail = mailAttrib.IsRead;
logData.IsGetItem = mailAttrib.IsGetItem;
logData.SenderNickname = mailAttrib.SenderNickName;
logData.SenderGuid = mailAttrib.SenderGuid;
logData.ReceiverNickname = mailAttrib.ReceiverNickName;
logData.ReceiverGuid = mailAttrib.ReceiverGuid;
logData.CreateTime = mailAttrib.CreateTime;
logData.ExpireTime = mailAttrib.ExpireTime;
logData.IsTextByMetaData = mailAttrib.IsTextByMetaData;
logData.packageOrderId = mailAttrib.packageOrderId;
logData.ItemList = mailAttrib.ItemList;
}
public MailSendOption createSystemSendMailOptionByMeta(
ProductMetaData productMeta,
SystemMailMetaData mailMeta,
string receiverUserGuid,
string receiverNickName, int amount)
{
DateTime now = DateTimeHelper.Current;
var expire_date = now.AddSeconds(MetaHelper.GameConfigMeta.SystemMailStoragePeriod);
// if (productMeta.Storage_Period_First != 0)
// {
// expire_date = DateTime.UtcNow.AddMinutes(productMeta.Storage_Period_First);
// }
var mail_send_option = new MailSendOption
{
ReceiverUserGuid = receiverUserGuid,
ReceiverNickName = receiverNickName,
IsSystemMail = true,
IsTextByMetaData = true,
Title = mailMeta.Mail_Title,
Text = mailMeta.Mail_Desc,
ExpireDate = expire_date,
ItemList = getMailItems(productMeta, amount).ToList(),
PackageOrderId = string.Empty,
};
return mail_send_option;
}
private static IEnumerable<ServerCommon.MailItem> getMailItems(ProductMetaData productMetaData, int amount)
{
if (productMetaData.ItemID_First != 0)
{
IEnumerable<ServerCommon.MailItem> total_items = Enumerable.Range(0, amount).Select(i =>
{
return productMetaData.First_List.Select(itemMeta => new ServerCommon.MailItem()
{
ItemId = (UInt32)itemMeta.Id,
Count = itemMeta.Value,
ProductId = (UInt32)productMetaData.Id,
isRepeatProduct = false
});
}).SelectMany(x => x);
return total_items;
}
return new List<ServerCommon.MailItem>();
}
}
public class BrokerMailRecvAction : EntityActionBase
{
private readonly DynamoDbClient m_dynamo_db_client;
public BrokerMailRecvAction(EntityBase owner, DynamoDbClient dynamoDbClient) : base(owner)
{
m_dynamo_db_client = dynamoDbClient;
}
public override void onClear()
{
throw new NotImplementedException();
}
public override Task<Result> onInit()
{
return Task.FromResult(new Result());
}
public async Task<(Result, List<ReceivedMailDoc>)> findReceivedMailDoc(string userGuid)
{
var err_msg = string.Empty;
var dynamo_db_client = m_dynamo_db_client;
var received_mail_docs = new List<ReceivedMailDoc>();
var doc = new ReceivedMailDoc(userGuid);
var event_tid = Guid.NewGuid().ToString("N");
var query_config = dynamo_db_client.makeQueryConfigForReadByPKOnly(doc.getPK());
var (result, read_docs) =
await dynamo_db_client.simpleQueryDocTypesWithQueryOperationConfig<ReceivedMailDoc>(query_config);
if (result.isSuccess())
{
foreach (var recv_mail_doc in read_docs)
{
var mail_attrib = recv_mail_doc.getAttrib<MailAttrib>();
NullReferenceCheckHelper.throwIfNull(mail_attrib,
() => $"mail_attrib is null !!! - userGuid:{userGuid}");
if (DateTimeHelper.Current > mail_attrib.ExpireTime)
{
var to_delete_result =
await dynamo_db_client.simpleDeleteDocumentWithDocType(recv_mail_doc, event_tid);
if (to_delete_result.isFail())
{
err_msg =
$"Failed to simpleDeleteDocumentWithDocType() !!!, can't received mail : Mail:{mail_attrib.toBasicString()} - userGuid:{userGuid}";
Log.getLogger().error(err_msg);
}
else
{
err_msg =
$"Mail deleted with expired retention period !!! : deletedMail:{mail_attrib.toBasicString()} - userGuid:{userGuid}";
Log.getLogger().info(err_msg);
}
continue;
}
received_mail_docs.Add(recv_mail_doc);
}
}
return (result, received_mail_docs);
}
public async Task<Result> deleteMail(string mailGuid)
{
var result = new Result();
var err_msg = string.Empty;
var mail_doc = new ReceivedMailDoc(mailGuid);
var event_tid = Guid.NewGuid().ToString("N");
result = await m_dynamo_db_client.simpleDeleteDocumentWithDocType(mail_doc, event_tid);
if (result.isFail())
{
err_msg =
$"Failed to simpleDeleteDocumentWithDocType() !!!, can't received mail : Mail:{mail_doc.toBasicString()}";
Log.getLogger().error(err_msg);
return result;
}
return result;
}
}

View File

@@ -0,0 +1,163 @@
using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;
using ServerCore;
using ServerBase;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
using MetaAssets;
namespace BrokerCore.Entity;
using ServerCommon;
//==========================================
// 유저의 인증 처리 Action 정의
//==========================================
public class UserAuthAction : EntityActionBase
{
private readonly DynamoDbClient m_dynamo_db_client;
public UserAuthAction(EntityBase owner, DynamoDbClient dynamoDbClient) : base(owner)
{
this.m_dynamo_db_client = dynamoDbClient;
}
public override Task<Result> onInit()
{
return Task.FromResult(new Result());
}
public override void onClear()
{
throw new NotImplementedException();
}
public async Task<(Result, AccountBaseDoc?)> findAccountDoc(string accountId)
{
return await EntityHelper.findDocByPk<AccountBaseDoc>(accountId, getOwner(), m_dynamo_db_client);
}
public async Task<(Result, UserBaseDoc?)> findUserDoc(string userGuid)
{
return await EntityHelper.findDocByPk<UserBaseDoc>(userGuid, getOwner(), m_dynamo_db_client);
}
public async Task<(Result, NicknameDoc?)> findNicknameDoc(string nickname)
{
return await EntityHelper.findDocByPk<NicknameDoc>(nickname, getOwner(), m_dynamo_db_client);
}
public async Task<Result> findAndSetAllAttributeByAccountId(string accountId)
{
var result = await findAndSetAccount(accountId);
if (result.isFail())
{
return result;
}
var user_guid = getOwner().getEntityAttributeNotNull<AccountAttribute>().UserGuid;
result = await findAndSetUser(user_guid);
if (result.isFail())
{
return result;
}
result = await findAndSetNickName(user_guid);
if (result.isFail())
{
return result;
}
return result;
}
public async Task<Result> findAndSetAllAttributeByUserGuid(string userGuid)
{
var result = await findAndSetUser(userGuid);
if (result.isFail())
{
return result;
}
result = await findAndSetNickName(userGuid);
if (result.isFail())
{
return result;
}
var account_id = getOwner().getEntityAttributeNotNull<UserAttribute>().AccountId;
result = await findAndSetAccount(account_id);
if (result.isFail())
{
return result;
}
return result;
}
// account로 AccountDoc을 읽고, AccountAttribute에 저장한다.
public async Task<Result> findAndSetAccount(string accountId)
{
var (result, doc) = await findAccountDoc(accountId);
if (result.isFail())
{
return result;
}
if (doc is null)
{
result.setFail(ServerErrorCode.AccountIdInvalid, accountId);
return result;
}
var attribute = getOwner().getEntityAttributeNotNull<AccountAttribute>();
attribute.copyEntityAttributeFromDoc(doc);
return result;
}
// UserBaseDoc을 읽고 UserAttribute에 저장
public async Task<Result> findAndSetUser(string userGuid)
{
var (result, doc) = await findUserDoc(userGuid);
if (result.isFail())
{
return result;
}
if (doc is null)
{
result.setFail(ServerErrorCode.UserGuidInvalid,
$"userGuid:{userGuid} not found - {getOwner().toBasicString()}");
return result;
}
var attribute = getOwner().getEntityAttributeNotNull<UserAttribute>();
attribute.copyEntityAttributeFromDoc(doc);
return result;
}
// NicknameDoc을 읽고, NicknameAttribute에 저장
public async Task<Result> findAndSetNickName(string userGuid)
{
var (result, doc) = await findNicknameDoc(userGuid);
if (result.isFail())
{
return result;
}
if (doc is null)
{
result.setFail(ServerErrorCode.NotFoundNickName,
$"nickname not found by userGuid:{userGuid} - {getOwner().toBasicString()}");
return result;
}
var attribute = getOwner().getEntityAttributeNotNull<NicknameAttribute>();
attribute.copyEntityAttributeFromDoc(doc);
return result;
}
}

View File

@@ -0,0 +1,60 @@

using ServerCore;
using ServerBase;
using ServerCommon;
namespace BrokerCore.Entity;
using Actions;
public class BrokerMailEntity : EntityBase, IWithLogActor
{
private readonly EntityBase m_parent;
private readonly IServerLogic m_server_logic;
// !! 주의 현상태에서는 EntityBase는 반드시 UserBase여야 한다.
// !! MailAttribute가 AccountAttribute를 참조하고, AccountAttribute는 UserBase를 참조하기 때문
public BrokerMailEntity(EntityBase parent, IServerLogic serverLogic)
: base(EntityType.Mail, parent)
{
this.m_parent = parent;
this.m_server_logic = serverLogic;
}
//====================================================================================================
// mail에 동록된 모든 Attribute와 Action을 초기화
//====================================================================================================
public override async Task<Result> onInit()
{
addEntityAttribute(new MailAttribute(this, m_parent));
addEntityAction(new BrokerMailSendAction(this, m_server_logic.getDynamoDbClient()));
addEntityAction(new BrokerMailRecvAction(this, m_server_logic.getDynamoDbClient()));
var mail_attribute = this.getEntityAttributeNotNull<MailAttribute>();
var result = await mail_attribute.onInit();
if (result.isFail())
{
return result;
}
var mail_send_action = this.getEntityActionNotNull<BrokerMailSendAction>();
result = await mail_send_action.onInit();
if (result.isFail())
{
return result;
}
return await base.onInit();
}
public ILogActor toLogActor()
{
var log_actor = m_parent as IWithLogActor;
NullReferenceCheckHelper.throwIfNull(log_actor,
() => $"m_parent is not IWithLogActor");
return log_actor.toLogActor();
}
}

View File

@@ -0,0 +1,28 @@
namespace BrokerCore.Entity;
using ServerCommon;
using ServerCore; using ServerBase;
public static class EntityExtensions
{
public static TEntityAttributeBase getEntityAttributeNotNull<TEntityAttributeBase>(this EntityBase entity)
where TEntityAttributeBase : EntityAttributeBase
{
TEntityAttributeBase? attribute = entity.getEntityAttribute<TEntityAttributeBase>();
// todo: 이렇게 널 처리를 하면 일관되게 처리할 수 있지만, null이 발생한 코드 위치가 항상 여기로 찍힌다.
// getEntityAttributeNotNull를 호출한 위치에서 로그를 찍을 수 있는 지 고민해보자.
NullReferenceCheckHelper.throwIfNull(attribute,
() => $"entity attribute {nameof(TEntityAttributeBase)} not found - {entity.toBasicString()}");
return attribute;
}
public static TEntityActionBase getEntityActionNotNull<TEntityActionBase>(this EntityBase entity)
where TEntityActionBase : EntityActionBase
{
TEntityActionBase? action = entity.getEntityAction<TEntityActionBase>();
NullReferenceCheckHelper.throwIfNull(action,
() => $"entity action {nameof(TEntityActionBase)} not found - {entity.toBasicString()}");
return action;
}
}

View File

@@ -0,0 +1,42 @@

using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;
using ServerCore;
using ServerBase;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
using MetaAssets;
namespace BrokerCore.Entity;
public static class EntityHelper
{
public static async Task<(Result, TDoc?)> findDocByPk<TDoc>(string pk, EntityBase owner, DynamoDbClient dynamoDbClient)
where TDoc : DynamoDbDocBase, new()
{
ArgumentNullException.ThrowIfNull(owner, $"owner is null !!!");
var (result, user_primary_key) = await DynamoDBDocBaseHelper.makePrimaryKey<TDoc>(pk);
if (result.isFail())
{
return (result, null);
}
ArgumentNullException.ThrowIfNull(user_primary_key, $"user_primary_key is null !!! - {owner.toBasicString()}");
var query_config = dynamoDbClient.makeQueryConfigForReadByPKSK(user_primary_key.PK);
(result, var found_doc) =
await dynamoDbClient.simpleQueryDocTypeWithQueryOperationConfig<TDoc>(query_config, false);
if (result.isFail())
{
return (result, null);
}
return (result, found_doc);
}
}

View File

@@ -0,0 +1,65 @@
namespace BrokerCore.Entity.Actions;
using ServerCommon;
using ServerCore; using ServerBase;
public record class MailSendOption
{
//==================
// 기본 속성들
//==================
public string ReceiverUserGuid { get; set; } = string.Empty;
public string ReceiverNickName { get; set; } = string.Empty;
public string SenderNickName { get; set; } = string.Empty;
public string SenderGuid { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public string Text { get; set; } = string.Empty;
public List<string> ContentsArguments { get; set; } = new List<string>();
public bool IsTextByMetaData { get; set; } = true;
public List<ServerCommon.MailItem> ItemList { get; set; } = new List<ServerCommon.MailItem>();
public DateTime ExpireDate { get; set; } = DateTimeHelper.MaxTime;
public string PackageOrderId { get; set; } = string.Empty;
//==================
// 추가 옵션들
//==================
public bool IsSystemMail { get; set; } = true;
public string PlanetId { get; set; } = string.Empty;
public string AccountId { get; set; } = string.Empty;
//==================
// 기본 생성자
//==================
public MailSendOption() { }
//==================
// 필수 항목을 포함한 생성자
//==================
public MailSendOption(string receiverUserGuid, string receiverNickName, string title, string text)
{
ReceiverUserGuid = receiverUserGuid;
ReceiverNickName = receiverNickName;
Title = title;
Text = text;
}
//==================
// 아이템 목록 추가 메서드
//==================
public void addItems(List<MailItem>? mailItems)
{
if (mailItems != null)
{
ItemList.AddRange(mailItems);
}
}
//==================
// 기본값 검증 메서드
//==================
public bool validate()
{
return !string.IsNullOrEmpty(ReceiverUserGuid) && !string.IsNullOrEmpty(Title);
}
}

View File

@@ -0,0 +1,75 @@
namespace BrokerCore.Entity;
using Actions;
using BrokerBusinessLog;
using ServerCommon;
using ServerCore; using ServerBase;
public sealed class PlanetUserEntity : EntityBase, IWithLogActor
{
private readonly DynamoDbClient m_dynamo_db_client;
private readonly IServerLogic m_server_logic;
private string m_planet_id = string.Empty;
// private BrokerMail m_broker_mail = null!;
public string AccountId
=> this.getEntityAttributeNotNull<AccountAttribute>().AccountId;
public string UserGuid
=> this.getEntityAttributeNotNull<UserAttribute>().UserGuid;
public string Nickname
=> this.getEntityAttributeNotNull<NicknameAttribute>().Nickname;
public PlanetUserEntity(IServerLogic serverLogic) : base(EntityType.PlanetUser)
{
m_server_logic = serverLogic;
m_dynamo_db_client = serverLogic.getDynamoDbClient();
}
public override OwnerEntityType onGetOwnerEntityType()
{
return OwnerEntityType.User;
}
public override async Task<Result> onInit()
{
try
{
addEntityAttribute(new UserAttribute(this));
addEntityAttribute(new NicknameAttribute(this));
addEntityAction(new UserAuthAction(this, m_dynamo_db_client));
addEntityAttribute(new AccountAttribute(this));
}
catch (Exception ex)
{
Log.getLogger().Error(ex, $"{nameof(PlanetUserEntity)}.onInit() Exception => {ex.Message}");
}
return await base.onInit();
}
public void setPlanetId(string planetId)
{
m_planet_id = planetId;
}
// IWithLogActor 구현
public ILogActor toLogActor()
{
var account = this.getEntityAttributeNotNull<AccountAttribute>();
var nickname = this.getEntityAttributeNotNull<NicknameAttribute>();
var log_actor = new PlanetUserLogActor
{
ServerType = m_server_logic.getServerType().toServerType(),
PlanetId = m_planet_id,
AccountType = account.AccountType,
AccountId = account.AccountId,
AccountIdString = account.AccountIdString,
UserNickname = nickname.Nickname,
UserGuid = account.UserGuid,
};
return log_actor;
}
}

View File

@@ -0,0 +1,26 @@
namespace BrokerCore.Meta;
using Microsoft.Extensions.Hosting;
public class MetaDataReloadScheduler : BackgroundService
{
const int m_reload_interval_min = 1;
private readonly BrokerApiMetaLoader m_broker_api_meta_data_loader;
public MetaDataReloadScheduler(BrokerApiMetaLoader brokerApiMetaDataLoader)
{
m_broker_api_meta_data_loader = brokerApiMetaDataLoader;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
using var timer = new PeriodicTimer(TimeSpan.FromMinutes(m_reload_interval_min));
while (!stoppingToken.IsCancellationRequested)
{
// TODO: 버전 관리 이슈를 먼저 해결할 후에 사용할 것
// m_broker_api_meta_data_loader.load();
await timer.WaitForNextTickAsync(stoppingToken);
}
}
}

View File

@@ -0,0 +1,260 @@
using System.Collections.Concurrent;
using ServerBase;
using ServerCommon;
using MetaAssets;
public class BrokerMetaTable
{
public string Version { get; private set; }
private readonly MetaTable m_meta_table = new MetaTable();
public ProductMetaTable ProductMetaTable => m_meta_table.ProductMetaTable;
// TODO: PlanetItemExchangePolicyMetaTable를 PlanetItemExchangePolicyTable로 이름 변경
public PlanetItemExchangePolicyMetaTable PlanetItemExchangePolicyMetaTable => m_meta_table.PlanetItemExchangePolicyMetaTable;
public SystemMailMetaTable SystemMailMetaTable => m_meta_table.SystemMailMetaTable;
public ItemMetaTable ItemMetaTable => m_meta_table.ItemMetaTable;
public TextStringMetaTable TextStringMetaTable => m_meta_table.TextStringMetaTable;
public BrokerMetaTable(MetaTable? source = null, string? versionName = null)
{
if (source != null)
{
m_meta_table = source;
Version = versionName ?? Guid.NewGuid().ToString();
}
}
}
public class BrokerApiMetaLoader : IDisposable
{
readonly string m_input_path = "resource/meta";
// 스레드 세이프한 딕셔너리로 변경
private readonly ConcurrentDictionary<string, BrokerMetaTable> m_meta_tables =
new ConcurrentDictionary<string, BrokerMetaTable>();
// 더 세밀한 제어가 필요한 경우를 위한 ReaderWriterLockSlim 추가
private readonly ReaderWriterLockSlim m_lock = new ReaderWriterLockSlim();
// 기본 메타테이블 캐싱
private BrokerMetaTable m_default_meta_table;
public Result load(string? dataPath = null)
{
try
{
m_lock.EnterWriteLock();
// 기본 메타 테이블 로드
var (result, meta_table) = loadMetaData(dataPath);
if (result.isFail() || meta_table == null)
{
return result;
}
if (m_meta_tables.TryAdd(meta_table.Version, meta_table))
{
m_default_meta_table = meta_table;
}
return result;
}
finally
{
m_lock.ExitWriteLock();
}
}
private (Result, BrokerMetaTable?) loadMetaData(string? dataPath = null, string? versionName = null)
{
var result = new Result();
var input_path = dataPath ?? m_input_path;
try
{
var full_path = Path.GetFullPath(input_path, Environment.CurrentDirectory);
if (!Directory.Exists(full_path))
{
full_path = Path.GetFullPath(input_path, AppContext.BaseDirectory);
if (!Directory.Exists(full_path))
{
result.setFail(ServerErrorCode.MetaDataLoadFailed, $"Meta data path not found: {input_path}");
return (result, null);
}
}
var meta_table = new MetaTable();
meta_table.loadForBrokerApi(full_path);
var errors = new ValidatorErrorCollection();
foreach (var data in meta_table.PlanetItemExchangePolicyMetaTable.PlanetItemExchangePolicyDataList)
{
validate(data, meta_table, errors);
}
if (errors.HasError)
{
errors.log();
}
//TODO: ProductMetaTable, SystemMailMetaTable, ItemMetaTable 에 대한 검사도 필요하다.
var broker_meta_table = new BrokerMetaTable(meta_table, versionName);
return (result, broker_meta_table);
}
catch (Exception ex)
{
result.setFail(ServerErrorCode.MetaDataLoadFailed, $"Meta data load failed => {ex.Message}");
}
return (result, null);
}
public BrokerMetaTable getMetaTable(string? versionName = null!)
{
try
{
m_lock.EnterReadLock();
if (string.IsNullOrEmpty(versionName) || versionName == "default")
{
return m_default_meta_table;
}
return m_meta_tables.GetValueOrDefault(versionName, m_default_meta_table);
// 요청된 버전이 없으면 기본 메타테이블 반환
}
finally
{
m_lock.ExitReadLock();
}
}
private ValidatorErrorCollection validate(PlanetItemExchangePolicyMetaData planetItemExchange, MetaTable metaTable, ValidatorErrorCollection errors)
{
checkValidCaliverseItem(planetItemExchange);
checkValidPlanetItem(planetItemExchange);
return errors;
void checkValidPlanetItem(PlanetItemExchangePolicyMetaData data)
{
var planet_item_type = toEnum(data.PlanetItemType, PlanetItemType.None);
switch (planet_item_type)
{
case PlanetItemType.Igm26Currency:
{
var currency_type = toEnum(data.PlanetItemId, PlanetCurrencyType.None);
if (currency_type == PlanetCurrencyType.None)
{
addError(nameof(data.PlanetItemId),
$"Planet 화폐 타입이 잘못되었습니다 => PlanetItemId:{data.PlanetItemId}");
}
// if (data.PlanetItemAmount >= 0)
// {
// // 재화는 차감만 가능
// addError(nameof(data.PlanetItemAmount),
// $"Planet 화폐 수량은 양수 합니다 => PlanetItemAmount:{data.PlanetItemAmount}");
// }
break;
}
case PlanetItemType.Igm26Quest:
break;
case PlanetItemType.None:
default:
addError(nameof(data.PlanetItemId),
$"Planet 화폐 타입이 잘못되었습니다 => PlanetItemId:{data.PlanetItemId}");
break;
}
}
void checkValidCaliverseItem(PlanetItemExchangePolicyMetaData data)
{
var caliverse_item_type = toEnum(data.CaliverseItemType, CaliverseItemType.None);
switch (caliverse_item_type)
{
case CaliverseItemType.Currency:
{
var currency_type = toEnum(data.CaliverseItemId, CurrencyType.None);
if (currency_type == CurrencyType.None)
{
addError(nameof(data.CaliverseItemId),
$"Caliverse 화폐 타입이 잘못되었습니다 => CaliverseItemId:{data.CaliverseItemId}");
}
// if (data.CaliverseItemAmount >= 0)
// {
// // 재화는 차감만 가능
// addError(nameof(data.CaliverseItemAmount),
// $"Caliverse 화폐 수량은 음수여야 합니다 => CaliverseItemAmount:{data.CaliverseItemAmount}");
// }
break;
}
case CaliverseItemType.CaliverseProduct:
{
var product_id = Convert.ToInt32(data.CaliverseItemId);
if (metaTable.ProductMetaTable.ProductMetaDataListbyId.ContainsKey(product_id) == false)
{
addError(nameof(data.CaliverseItemId),
$"CaliverseItemId이 존재하지 않습니다 => CaliverseItemId: {data.CaliverseItemId}");
}
if (data.CaliverseItemAmount < 0)
{
addError(nameof(data.CaliverseItemAmount),
$"Product 수량은 0보다 커야합니다 => CaliverseItemAmount:{data.CaliverseItemAmount}");
}
break;
}
case CaliverseItemType.None:
default:
{
addError(nameof(data.CaliverseItemType),
$"Caliverse 아이템 타입이 잘못되었습니다 => CaliverseItemType:{data.CaliverseItemType}");
break;
}
}
}
void addError(string variableName, string msg)
{
errors.add($"Invalid PlanetItemExchangePolicyMetaData Value: {variableName} - {msg}");
}
TEnum toEnum<TEnum>(string enumTypeString, TEnum defaultValue) where TEnum : struct, Enum
{
var enum_type_string_result = enumTypeString.Replace("_", "");
return Enum.TryParse<TEnum>(enum_type_string_result, ignoreCase: true, out var enum_type)
? enum_type
: defaultValue;
}
}
// 리소스 해제를 위한 Dispose 패턴 구현
private bool m_disposed = false;
public void Dispose()
{
if (!m_disposed)
{
m_lock.Dispose();
m_disposed = true;
}
}
}
// 최신 메타테이블을 참조하는 클래스
public class BrokerMetaTableRef
{
public BrokerMetaTable MetaTable => m_meta_table;
private readonly BrokerMetaTable m_meta_table;
public BrokerMetaTableRef(BrokerMetaTable metaTable)
{
m_meta_table = metaTable;
}
}

View File

@@ -0,0 +1,23 @@
// namespace BrokerCore.Meta;
//
// public class PlanetItemExchangePolicy
// {
// // ID
// // PlanetId
// // CaliverseItemType
// // CaliverseItemId
// // CaliverseItemAmount
// // PlanetItemType
// // PlanetItemId
// // PlanetItemAmount
// // Description
//
// public string? Id { get; set; }
// public string? PlanetId { get; set; }
// public string? CaliverseItemType { get; set; }
// public string? CaliverseItemId { get; set; }
// public long CaliverseItemAmount { get; set; }
// public string? PlanetItemType { get; set; }
// public string? PlanetItemId { get; set; }
// public long PlanetItemAmount { get; set; }
// }

View File

@@ -0,0 +1,108 @@
#========================================================================
# 자동으로 마이그레이션을 생성하고 마이그레이션할 내용이 없으면 생성된 마이그레이션을 삭제하는 스크립트
# PowerShell 스크립트
#========================================================================
# 설정 (프로젝트 경로, DbContext 타입 등 - 필요에 따라 변수로 설정)
$projectDir = $PSScriptRoot # 스크립트 파일이 있는 디렉토리를 프로젝트 경로로 설정
Write-Host "프로젝트 경로: $projectDir"
$dbContextTypeName = "MetaverseBrokerDbContext"
$migrationsOutputDir = "$projectDir/Migrations" # 마이그레이션 파일 출력 디렉토리
Write-Host "마이그레이션 시작..."
# dotnet ef migrations script 명령어 실행 및 결과 캡처
$scriptOutput = dotnet ef migrations script `
--idempotent `
--project $projectDir `
--context $dbContextTypeName
#Write-Host "마이그레이션 필요 여부 확인 결과:"
# 결과에서 "No pending migrations" 메시지 또는 빈 스크립트 여부 확인
if ($scriptOutput -like "-- *No pending migrations*" -or ([string]::IsNullOrEmpty($scriptOutput)) ) {
Write-Host "스키마 변경 없음: 새로운 마이그레이션 불필요"
Write-Host "데이터베이스 업데이트 불필요 (스키마 변경 없음)"
} else {
# Write-Host "스키마 변경 감지: 새로운 마이그레이션 필요"
# 마이그레이션 이름 생성 (예: 날짜_시간 기반)
$migrationName = "SchemaChanges_" + (Get-Date -Format "HHmmss")
Write-Host "마이그레이션 생성 시작: $migrationName"
# dotnet ef migrations add 명령어 실행 (자동 마이그레이션 생성)
$scriptOutput = dotnet ef migrations add $migrationName `
--project $projectDir `
--context $dbContextTypeName `
--output-dir $migrationsOutputDir `
--verbose
Write-Host "마이그레이션 생성 결과: $scriptOutput"
if ($LASTEXITCODE -eq 0) {
Write-Host "마이그레이션 생성 성공: $migrationName"
# $migrationFileName = "$migrationsOutputDir/$migrationName.cs" # 마이그레이션 파일 경로
# $migrationsOutputDir에서 $migrationName로 끝나는 cs 파일 찾기
# $migrationFileName = Get-ChildItem -Path $migrationsOutputDir -Filter "$migrationName.cs" -Recurse | Select-Object -First 1 -ExpandProperty FullName
$migrationFileName = Get-ChildItem -Path $migrationsOutputDir -Filter "*$migrationName.cs" -Recurse | Select-Object -First 1 -ExpandProperty Name
$migrationFileName = "$migrationsOutputDir/$migrationFileName" # 마이그레이션 파일 경로
if ($migrationFileName -eq $null) {
Write-Error "마이그레이션 파일을 찾을 수 없습니다."
exit
}
# 생성된 마이그레이션 파일 내용 확인 (Up 및 Down 메소드 검사)
Write-Host "마이그레이션 파일 내용 분석 시작: $migrationFileName"
$migrationFileContent = Get-Content $migrationFileName -Raw
# Up 메소드와 Down 메소드 내용 정규식으로 추출 (공백 및 주석 허용)
$upMethodContentMatch = [regex]::Match($migrationFileContent, 'protected override void Up\(MigrationBuilder migrationBuilder\)\s*{(.*?)}', [System.Text.RegularExpressions.RegexOptions]::Singleline)
$downMethodContentMatch = [regex]::Match($migrationFileContent, 'protected override void Down\(MigrationBuilder migrationBuilder\)\s*{(.*?)}', [System.Text.RegularExpressions.RegexOptions]::Singleline)
$upMethodContent = $upMethodContentMatch.Groups[1].Value.Trim()
$downMethodContent = $downMethodContentMatch.Groups[1].Value.Trim()
# Up 및 Down 메소드가 비어 있는지 확인 (공백 및 주석 제거 후)
$isEmptyMigration = ($upMethodContent -notmatch '\S') -and ($downMethodContent -notmatch '\S') # \S: 공백 문자 제외한 문자
if ($isEmptyMigration) {
Write-Host "마이그레이션 클래스 (Up, Down 메소드) 내용 없음 감지"
Write-Host "생성된 마이그레이션 삭제 시작: $migrationName"
# 마이그레이션 삭제 명령어 실행
dotnet ef migrations remove `
--project $projectDir `
--context $dbContextTypeName --force
if ($LASTEXITCODE -eq 0) {
Write-Host "마이그레이션 삭제 성공: $migrationName"
Write-Host "스키마 변경 내용이 없어 데이터베이스 업데이트를 생략합니다."
} else {
Write-Error "마이그레이션 삭제 실패 (Exit Code: $LASTEXITCODE)"
Write-Error "마이그레이션 파일은 남아있을 수 있습니다: $migrationFileName"
Write-Error "수동으로 마이그레이션 삭제를 확인해주세요."
}
} else {
Write-Host "마이그레이션 클래스 내용 확인: 스키마 변경 내용 있음"
Write-Host "데이터베이스 업데이트 시작..."
# dotnet ef database update 명령어 실행 (데이터베이스 업데이트)
dotnet ef database update `
--project $projectDir `
--context $dbContextTypeName
if ($LASTEXITCODE -eq 0) {
Write-Host "데이터베이스 업데이트 성공"
} else {
Write-Error "데이터베이스 업데이트 실패 (Exit Code: $LASTEXITCODE)"
Write-Error "마이그레이션은 생성되었지만, 데이터베이스 업데이트에 실패했습니다. 수동으로 데이터베이스 업데이트를 수행해야 할 수 있습니다."
}
}
} else {
Write-Error "마이그레이션 생성 실패 (Exit Code: $LASTEXITCODE)"
Write-Error "데이터베이스 업데이트를 진행할 수 없습니다."
}
}
Write-Host "마이그레이션 및 데이터베이스 업데이트 자동화 스크립트 완료."

View File

@@ -0,0 +1,150 @@
// <auto-generated />
using System;
using BrokerCore.Repository.Context;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace BrokerApiCore.Migrations
{
[DbContext(typeof(MetaverseBrokerDbContext))]
[Migration("20250217015116_SchemaChanges_105106")]
partial class SchemaChanges_105106
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.2")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder);
modelBuilder.Entity("BrokerCore.DbEntity.PlanetInfo", b =>
{
b.Property<string>("PlanetId")
.HasColumnType("varchar(50)")
.HasColumnName("planet_id");
b.Property<string>("CompanyName")
.IsRequired()
.HasColumnType("varchar(32)")
.HasColumnName("company_name");
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp")
.HasColumnName("created_at")
.HasDefaultValueSql("CURRENT_TIMESTAMP")
.HasComment("생성 시간");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("varchar(255)")
.HasColumnName("description");
b.Property<string>("PlanetName")
.IsRequired()
.HasColumnType("varchar(32)")
.HasColumnName("planet_name");
b.Property<string>("SecretKey")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("secret_key");
b.Property<string>("ServerType")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("server_type");
b.Property<DateTime>("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp")
.HasColumnName("updated_at")
.HasDefaultValueSql("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
.HasComment("수정 시간");
b.HasKey("PlanetId");
b.HasIndex("CompanyName");
b.HasIndex("PlanetName");
b.HasIndex("SecretKey");
b.ToTable("planet_info", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.SapphireExchangeOrder", b =>
{
b.Property<string>("OrderId")
.HasColumnType("varchar(50)")
.HasColumnName("order_id")
.HasComment("사파이어 교환 주문 아이디 guid");
b.Property<ulong>("AccountId")
.HasColumnType("bigint unsigned")
.HasColumnName("account_id")
.HasComment("sso 계정 아이디");
b.Property<DateTime?>("CompletedAt")
.HasColumnType("timestamp")
.HasColumnName("completed_at")
.HasComment("사파이어 교환 주문 완료 시간");
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp")
.HasColumnName("created_at")
.HasComment("사파이어 교환 주문 시작 시간");
b.Property<sbyte>("OrderStatus")
.HasColumnType("tinyint")
.HasColumnName("order_status")
.HasComment("사파이어 교환 주문 상태");
b.Property<string>("PlanetId")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("planet_id")
.HasComment("플래닛 아이디");
b.Property<decimal>("PlanetMoneyIncDelta")
.HasColumnType("decimal(20, 0)")
.HasColumnName("planet_money_amount")
.HasComment("플래닛에서 발급한 재화 수량");
b.Property<decimal>("SapphireReducedDelta")
.HasColumnType("decimal(20, 0)")
.HasColumnName("sapphire_reduced_amount")
.HasComment("사파이어 차감 수량");
b.Property<string>("UserGuid")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("user_guid")
.HasComment("유저 아이디");
b.HasKey("OrderId");
b.HasIndex("AccountId");
b.HasIndex("CreatedAt");
b.HasIndex("OrderStatus");
b.HasIndex("PlanetId");
b.HasIndex("UserGuid");
b.ToTable("sapphire_exchange_order", (string)null);
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,116 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace BrokerApiCore.Migrations
{
/// <inheritdoc />
public partial class SchemaChanges_105106 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterDatabase()
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "planet_info",
columns: table => new
{
planet_id = table.Column<string>(type: "varchar(50)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
planet_name = table.Column<string>(type: "varchar(32)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
company_name = table.Column<string>(type: "varchar(32)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
secret_key = table.Column<string>(type: "varchar(50)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
server_type = table.Column<string>(type: "varchar(50)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
description = table.Column<string>(type: "varchar(255)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
created_at = table.Column<DateTime>(type: "timestamp", nullable: false, defaultValueSql: "CURRENT_TIMESTAMP", comment: "생성 시간"),
updated_at = table.Column<DateTime>(type: "timestamp", nullable: false, defaultValueSql: "CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP", comment: "수정 시간")
},
constraints: table =>
{
table.PrimaryKey("PK_planet_info", x => x.planet_id);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "sapphire_exchange_order",
columns: table => new
{
order_id = table.Column<string>(type: "varchar(50)", nullable: false, comment: "사파이어 교환 주문 아이디 guid")
.Annotation("MySql:CharSet", "utf8mb4"),
account_id = table.Column<ulong>(type: "bigint unsigned", nullable: false, comment: "sso 계정 아이디"),
order_status = table.Column<sbyte>(type: "tinyint", nullable: false, comment: "사파이어 교환 주문 상태"),
user_guid = table.Column<string>(type: "varchar(50)", nullable: false, comment: "유저 아이디")
.Annotation("MySql:CharSet", "utf8mb4"),
planet_id = table.Column<string>(type: "varchar(50)", nullable: false, comment: "플래닛 아이디")
.Annotation("MySql:CharSet", "utf8mb4"),
sapphire_reduced_amount = table.Column<decimal>(type: "decimal(20,0)", nullable: false, comment: "사파이어 차감 수량"),
planet_money_amount = table.Column<decimal>(type: "decimal(20,0)", nullable: false, comment: "플래닛에서 발급한 재화 수량"),
created_at = table.Column<DateTime>(type: "timestamp", nullable: false, comment: "사파이어 교환 주문 시작 시간"),
completed_at = table.Column<DateTime>(type: "timestamp", nullable: true, comment: "사파이어 교환 주문 완료 시간")
},
constraints: table =>
{
table.PrimaryKey("PK_sapphire_exchange_order", x => x.order_id);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateIndex(
name: "IX_planet_info_company_name",
table: "planet_info",
column: "company_name");
migrationBuilder.CreateIndex(
name: "IX_planet_info_planet_name",
table: "planet_info",
column: "planet_name");
migrationBuilder.CreateIndex(
name: "IX_planet_info_secret_key",
table: "planet_info",
column: "secret_key");
migrationBuilder.CreateIndex(
name: "IX_sapphire_exchange_order_account_id",
table: "sapphire_exchange_order",
column: "account_id");
migrationBuilder.CreateIndex(
name: "IX_sapphire_exchange_order_created_at",
table: "sapphire_exchange_order",
column: "created_at");
migrationBuilder.CreateIndex(
name: "IX_sapphire_exchange_order_order_status",
table: "sapphire_exchange_order",
column: "order_status");
migrationBuilder.CreateIndex(
name: "IX_sapphire_exchange_order_planet_id",
table: "sapphire_exchange_order",
column: "planet_id");
migrationBuilder.CreateIndex(
name: "IX_sapphire_exchange_order_user_guid",
table: "sapphire_exchange_order",
column: "user_guid");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "planet_info");
migrationBuilder.DropTable(
name: "sapphire_exchange_order");
}
}
}

View File

@@ -0,0 +1,263 @@
// <auto-generated />
using System;
using BrokerCore.Repository.Context;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace BrokerApiCore.Migrations
{
[DbContext(typeof(MetaverseBrokerDbContext))]
[Migration("20250224031421_SchemaChanges_121410")]
partial class SchemaChanges_121410
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.2")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder);
modelBuilder.Entity("BrokerCore.DbEntity.PlanetInfo", b =>
{
b.Property<string>("PlanetId")
.HasColumnType("varchar(50)")
.HasColumnName("planet_id");
b.Property<string>("CompanyName")
.IsRequired()
.HasColumnType("varchar(32)")
.HasColumnName("company_name");
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp")
.HasColumnName("created_at")
.HasDefaultValueSql("CURRENT_TIMESTAMP")
.HasComment("생성 시간");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("varchar(255)")
.HasColumnName("description");
b.Property<string>("PlanetName")
.IsRequired()
.HasColumnType("varchar(32)")
.HasColumnName("planet_name");
b.Property<string>("SecretKey")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("secret_key");
b.Property<string>("ServerType")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("server_type");
b.Property<DateTime>("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp")
.HasColumnName("updated_at")
.HasDefaultValueSql("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
.HasComment("수정 시간");
b.HasKey("PlanetId");
b.HasIndex("CompanyName");
b.HasIndex("PlanetName");
b.HasIndex("SecretKey");
b.ToTable("planet_info", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.PlanetItemExchangeOrder", b =>
{
b.Property<string>("OrderId")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("order_id")
.HasComment("교환 주문 아이디 (GUID)");
b.Property<string>("AccountId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("account_id")
.HasComment("SSO 아이디");
b.Property<int>("CaliverseItemDeltaAmount")
.HasColumnType("INT")
.HasColumnName("caliverse_item_quantity")
.HasComment("칼리버스 아이템 갯수");
b.Property<string>("CaliverseItemId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("caliverse_item_id")
.HasComment("칼리버스 아이템 아이디");
b.Property<string>("CaliverseItemType")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("caliverse_item_type")
.HasComment("칼리버스 아이템 타입");
b.Property<DateTime?>("CompletedAt")
.HasColumnType("TIMESTAMP")
.HasColumnName("completed_at")
.HasComment("교환 주문 완료 시간");
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("TIMESTAMP")
.HasColumnName("created_at")
.HasDefaultValueSql("CURRENT_TIMESTAMP")
.HasComment("교환 주문 시작 시간");
b.Property<int>("ExchangeMetaAmount")
.HasColumnType("INT")
.HasColumnName("exchange_meta_amount")
.HasComment("교환 메타 수량");
b.Property<string>("ExchangeMetaId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("exchange_meta_id")
.HasComment("교환 메타 아이디");
b.Property<string>("OrderStatus")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("order_status")
.HasComment("교환 주문 상태");
b.Property<string>("PlanetId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("planet_id")
.HasComment("플래닛 아이디");
b.Property<int>("PlanetItemDeltaAmount")
.HasColumnType("INT")
.HasColumnName("planet_item_quantity")
.HasComment("플래닛 아이템 갯수");
b.Property<string>("PlanetItemId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("planet_item_id")
.HasComment("플래닛 아이템 아이디");
b.Property<string>("PlanetItemType")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("planet_item_type")
.HasComment("플래닛 아이템 타입");
b.Property<string>("UserGuid")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("user_guid")
.HasComment("유저 아이디 (GUID)");
b.HasKey("OrderId");
b.HasIndex("AccountId");
b.HasIndex("CreatedAt");
b.HasIndex("OrderStatus");
b.HasIndex("PlanetId");
b.HasIndex("UserGuid");
b.ToTable("planet_exchange_orders", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.SapphireExchangeOrder", b =>
{
b.Property<string>("OrderId")
.HasColumnType("varchar(50)")
.HasColumnName("order_id")
.HasComment("사파이어 교환 주문 아이디 guid");
b.Property<ulong>("AccountId")
.HasColumnType("bigint unsigned")
.HasColumnName("account_id")
.HasComment("sso 계정 아이디");
b.Property<DateTime?>("CompletedAt")
.HasColumnType("timestamp")
.HasColumnName("completed_at")
.HasComment("사파이어 교환 주문 완료 시간");
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp")
.HasColumnName("created_at")
.HasComment("사파이어 교환 주문 시작 시간");
b.Property<sbyte>("OrderStatus")
.HasColumnType("tinyint")
.HasColumnName("order_status")
.HasComment("사파이어 교환 주문 상태");
b.Property<string>("PlanetId")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("planet_id")
.HasComment("플래닛 아이디");
b.Property<decimal>("PlanetMoneyIncDelta")
.HasColumnType("decimal(20, 0)")
.HasColumnName("planet_money_amount")
.HasComment("플래닛에서 발급한 재화 수량");
b.Property<decimal>("SapphireReducedDelta")
.HasColumnType("decimal(20, 0)")
.HasColumnName("sapphire_reduced_amount")
.HasComment("사파이어 차감 수량");
b.Property<string>("UserGuid")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("user_guid")
.HasComment("유저 아이디");
b.HasKey("OrderId");
b.HasIndex("AccountId");
b.HasIndex("CreatedAt");
b.HasIndex("OrderStatus");
b.HasIndex("PlanetId");
b.HasIndex("UserGuid");
b.ToTable("sapphire_exchange_order", (string)null);
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,83 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace BrokerApiCore.Migrations
{
/// <inheritdoc />
public partial class SchemaChanges_121410 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "planet_exchange_orders",
columns: table => new
{
order_id = table.Column<string>(type: "varchar(50)", maxLength: 50, nullable: false, comment: "교환 주문 아이디 (GUID)")
.Annotation("MySql:CharSet", "utf8mb4"),
order_status = table.Column<string>(type: "varchar(50)", maxLength: 50, nullable: false, comment: "교환 주문 상태")
.Annotation("MySql:CharSet", "utf8mb4"),
exchange_meta_id = table.Column<string>(type: "varchar(50)", maxLength: 50, nullable: false, comment: "교환 메타 아이디")
.Annotation("MySql:CharSet", "utf8mb4"),
exchange_meta_amount = table.Column<int>(type: "INT", nullable: false, comment: "교환 메타 수량"),
account_id = table.Column<string>(type: "varchar(50)", maxLength: 50, nullable: false, comment: "SSO 아이디")
.Annotation("MySql:CharSet", "utf8mb4"),
user_guid = table.Column<string>(type: "varchar(50)", maxLength: 50, nullable: false, comment: "유저 아이디 (GUID)")
.Annotation("MySql:CharSet", "utf8mb4"),
planet_id = table.Column<string>(type: "varchar(50)", maxLength: 50, nullable: false, comment: "플래닛 아이디")
.Annotation("MySql:CharSet", "utf8mb4"),
caliverse_item_type = table.Column<string>(type: "varchar(50)", maxLength: 50, nullable: false, comment: "칼리버스 아이템 타입")
.Annotation("MySql:CharSet", "utf8mb4"),
caliverse_item_id = table.Column<string>(type: "varchar(50)", maxLength: 50, nullable: false, comment: "칼리버스 아이템 아이디")
.Annotation("MySql:CharSet", "utf8mb4"),
caliverse_item_quantity = table.Column<int>(type: "INT", nullable: false, comment: "칼리버스 아이템 갯수"),
planet_item_type = table.Column<string>(type: "varchar(50)", maxLength: 50, nullable: false, comment: "플래닛 아이템 타입")
.Annotation("MySql:CharSet", "utf8mb4"),
planet_item_id = table.Column<string>(type: "varchar(50)", maxLength: 50, nullable: false, comment: "플래닛 아이템 아이디")
.Annotation("MySql:CharSet", "utf8mb4"),
planet_item_quantity = table.Column<int>(type: "INT", nullable: false, comment: "플래닛 아이템 갯수"),
created_at = table.Column<DateTime>(type: "TIMESTAMP", nullable: false, defaultValueSql: "CURRENT_TIMESTAMP", comment: "교환 주문 시작 시간"),
completed_at = table.Column<DateTime>(type: "TIMESTAMP", nullable: true, comment: "교환 주문 완료 시간")
},
constraints: table =>
{
table.PrimaryKey("PK_planet_exchange_orders", x => x.order_id);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateIndex(
name: "IX_planet_exchange_orders_account_id",
table: "planet_exchange_orders",
column: "account_id");
migrationBuilder.CreateIndex(
name: "IX_planet_exchange_orders_created_at",
table: "planet_exchange_orders",
column: "created_at");
migrationBuilder.CreateIndex(
name: "IX_planet_exchange_orders_order_status",
table: "planet_exchange_orders",
column: "order_status");
migrationBuilder.CreateIndex(
name: "IX_planet_exchange_orders_planet_id",
table: "planet_exchange_orders",
column: "planet_id");
migrationBuilder.CreateIndex(
name: "IX_planet_exchange_orders_user_guid",
table: "planet_exchange_orders",
column: "user_guid");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "planet_exchange_orders");
}
}
}

View File

@@ -0,0 +1,270 @@
// <auto-generated />
using System;
using BrokerCore.Repository.Context;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace BrokerApiCore.Migrations
{
[DbContext(typeof(MetaverseBrokerDbContext))]
[Migration("20250314055515_SchemaChanges_145503")]
partial class SchemaChanges_145503
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.2")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder);
modelBuilder.Entity("BrokerCore.DbEntity.PlanetInfo", b =>
{
b.Property<string>("PlanetId")
.HasColumnType("varchar(50)")
.HasColumnName("planet_id");
b.Property<string>("CompanyName")
.IsRequired()
.HasColumnType("varchar(32)")
.HasColumnName("company_name");
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp")
.HasColumnName("created_at")
.HasDefaultValueSql("CURRENT_TIMESTAMP")
.HasComment("생성 시간");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("varchar(255)")
.HasColumnName("description");
b.Property<string>("PlanetName")
.IsRequired()
.HasColumnType("varchar(32)")
.HasColumnName("planet_name");
b.Property<string>("SecretKey")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("secret_key");
b.Property<string>("ServerType")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("server_type");
b.Property<DateTime>("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp")
.HasColumnName("updated_at")
.HasDefaultValueSql("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
.HasComment("수정 시간");
b.HasKey("PlanetId");
b.HasIndex("CompanyName");
b.HasIndex("PlanetName");
b.HasIndex("SecretKey");
b.ToTable("planet_info", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.PlanetItemExchangeOrder", b =>
{
b.Property<string>("OrderId")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("order_id")
.HasComment("교환 주문 아이디 (GUID)");
b.Property<string>("AccountId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("account_id")
.HasComment("SSO 아이디");
b.Property<int>("CaliverseItemDeltaAmount")
.HasColumnType("INT")
.HasColumnName("caliverse_item_quantity")
.HasComment("칼리버스 아이템 갯수");
b.Property<string>("CaliverseItemId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("caliverse_item_id")
.HasComment("칼리버스 아이템 아이디");
b.Property<string>("CaliverseItemType")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("caliverse_item_type")
.HasComment("칼리버스 아이템 타입");
b.Property<DateTime?>("CompletedAt")
.HasColumnType("TIMESTAMP")
.HasColumnName("completed_at")
.HasComment("교환 주문 완료 시간");
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("TIMESTAMP")
.HasColumnName("created_at")
.HasDefaultValueSql("CURRENT_TIMESTAMP")
.HasComment("교환 주문 시작 시간");
b.Property<int>("ExchangeMetaAmount")
.HasColumnType("INT")
.HasColumnName("exchange_meta_amount")
.HasComment("교환 메타 수량");
b.Property<string>("ExchangeMetaId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("exchange_meta_id")
.HasComment("교환 메타 아이디");
b.Property<string>("OrderStatus")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("order_status")
.HasComment("교환 주문 상태");
b.Property<string>("PlanetId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("planet_id")
.HasComment("플래닛 아이디");
b.Property<int>("PlanetItemDeltaAmount")
.HasColumnType("INT")
.HasColumnName("planet_item_quantity")
.HasComment("플래닛 아이템 갯수");
b.Property<string>("PlanetItemId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("planet_item_id")
.HasComment("플래닛 아이템 아이디");
b.Property<string>("PlanetItemType")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("planet_item_type")
.HasComment("플래닛 아이템 타입");
b.Property<string>("SeasonId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("season_id")
.HasComment("시즌 아이디");
b.Property<string>("UserGuid")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("user_guid")
.HasComment("유저 아이디 (GUID)");
b.HasKey("OrderId");
b.HasIndex("AccountId");
b.HasIndex("CreatedAt");
b.HasIndex("OrderStatus");
b.HasIndex("PlanetId");
b.HasIndex("UserGuid");
b.ToTable("planet_exchange_orders", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.SapphireExchangeOrder", b =>
{
b.Property<string>("OrderId")
.HasColumnType("varchar(50)")
.HasColumnName("order_id")
.HasComment("사파이어 교환 주문 아이디 guid");
b.Property<ulong>("AccountId")
.HasColumnType("bigint unsigned")
.HasColumnName("account_id")
.HasComment("sso 계정 아이디");
b.Property<DateTime?>("CompletedAt")
.HasColumnType("timestamp")
.HasColumnName("completed_at")
.HasComment("사파이어 교환 주문 완료 시간");
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp")
.HasColumnName("created_at")
.HasComment("사파이어 교환 주문 시작 시간");
b.Property<sbyte>("OrderStatus")
.HasColumnType("tinyint")
.HasColumnName("order_status")
.HasComment("사파이어 교환 주문 상태");
b.Property<string>("PlanetId")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("planet_id")
.HasComment("플래닛 아이디");
b.Property<decimal>("PlanetMoneyIncDelta")
.HasColumnType("decimal(20, 0)")
.HasColumnName("planet_money_amount")
.HasComment("플래닛에서 발급한 재화 수량");
b.Property<decimal>("SapphireReducedDelta")
.HasColumnType("decimal(20, 0)")
.HasColumnName("sapphire_reduced_amount")
.HasComment("사파이어 차감 수량");
b.Property<string>("UserGuid")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("user_guid")
.HasComment("유저 아이디");
b.HasKey("OrderId");
b.HasIndex("AccountId");
b.HasIndex("CreatedAt");
b.HasIndex("OrderStatus");
b.HasIndex("PlanetId");
b.HasIndex("UserGuid");
b.ToTable("sapphire_exchange_order", (string)null);
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,32 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace BrokerApiCore.Migrations
{
/// <inheritdoc />
public partial class SchemaChanges_145503 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "season_id",
table: "planet_exchange_orders",
type: "varchar(50)",
maxLength: 50,
nullable: false,
defaultValue: "",
comment: "시즌 아이디")
.Annotation("MySql:CharSet", "utf8mb4");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "season_id",
table: "planet_exchange_orders");
}
}
}

View File

@@ -0,0 +1,276 @@
// <auto-generated />
using System;
using BrokerCore.Repository.Context;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace BrokerApiCore.Migrations
{
[DbContext(typeof(MetaverseBrokerDbContext))]
[Migration("20250314062930_SchemaChanges_152918")]
partial class SchemaChanges_152918
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.2")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder);
modelBuilder.Entity("BrokerCore.DbEntity.PlanetInfo", b =>
{
b.Property<string>("PlanetId")
.HasColumnType("varchar(50)")
.HasColumnName("planet_id");
b.Property<string>("CompanyName")
.IsRequired()
.HasColumnType("varchar(32)")
.HasColumnName("company_name");
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp")
.HasColumnName("created_at")
.HasDefaultValueSql("CURRENT_TIMESTAMP")
.HasComment("생성 시간");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("varchar(255)")
.HasColumnName("description");
b.Property<string>("PlanetName")
.IsRequired()
.HasColumnType("varchar(32)")
.HasColumnName("planet_name");
b.Property<string>("SecretKey")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("secret_key");
b.Property<string>("ServerType")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("server_type");
b.Property<DateTime>("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp")
.HasColumnName("updated_at")
.HasDefaultValueSql("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
.HasComment("수정 시간");
b.HasKey("PlanetId");
b.HasIndex("CompanyName");
b.HasIndex("PlanetName");
b.HasIndex("SecretKey");
b.ToTable("planet_info", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.PlanetItemExchangeOrder", b =>
{
b.Property<string>("OrderId")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("order_id")
.HasColumnOrder(1)
.HasComment("교환 주문 아이디 (GUID)");
b.Property<string>("AccountId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("account_id")
.HasColumnOrder(7)
.HasComment("SSO 아이디");
b.Property<int>("CaliverseItemDeltaAmount")
.HasColumnType("INT")
.HasColumnName("caliverse_item_quantity")
.HasColumnOrder(11)
.HasComment("칼리버스 아이템 갯수");
b.Property<string>("CaliverseItemId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("caliverse_item_id")
.HasColumnOrder(10)
.HasComment("칼리버스 아이템 아이디");
b.Property<string>("CaliverseItemType")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("caliverse_item_type")
.HasColumnOrder(9)
.HasComment("칼리버스 아이템 타입");
b.Property<DateTime?>("CompletedAt")
.HasColumnType("TIMESTAMP")
.HasColumnName("completed_at")
.HasColumnOrder(16)
.HasComment("교환 주문 완료 시간");
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("TIMESTAMP")
.HasColumnName("created_at")
.HasColumnOrder(15)
.HasDefaultValueSql("CURRENT_TIMESTAMP")
.HasComment("교환 주문 시작 시간");
b.Property<int>("ExchangeMetaAmount")
.HasColumnType("INT")
.HasColumnName("exchange_meta_amount")
.HasColumnOrder(6)
.HasComment("교환 메타 수량");
b.Property<string>("ExchangeMetaId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("exchange_meta_id")
.HasColumnOrder(5)
.HasComment("교환 메타 아이디");
b.Property<string>("OrderStatus")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("order_status")
.HasColumnOrder(2)
.HasComment("교환 주문 상태");
b.Property<string>("PlanetId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("planet_id")
.HasColumnOrder(3)
.HasComment("플래닛 아이디");
b.Property<int>("PlanetItemDeltaAmount")
.HasColumnType("INT")
.HasColumnName("planet_item_quantity")
.HasColumnOrder(14)
.HasComment("플래닛 아이템 갯수");
b.Property<string>("PlanetItemId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("planet_item_id")
.HasColumnOrder(13)
.HasComment("플래닛 아이템 아이디");
b.Property<string>("PlanetItemType")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("planet_item_type")
.HasColumnOrder(12)
.HasComment("플래닛 아이템 타입");
b.Property<string>("SeasonId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("season_id")
.HasColumnOrder(4)
.HasComment("시즌 아이디");
b.Property<string>("UserGuid")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("user_guid")
.HasColumnOrder(8)
.HasComment("유저 아이디 (GUID)");
b.HasKey("OrderId");
b.ToTable("PlanetItemExchangeOrders");
});
modelBuilder.Entity("BrokerCore.DbEntity.SapphireExchangeOrder", b =>
{
b.Property<string>("OrderId")
.HasColumnType("varchar(50)")
.HasColumnName("order_id")
.HasComment("사파이어 교환 주문 아이디 guid");
b.Property<ulong>("AccountId")
.HasColumnType("bigint unsigned")
.HasColumnName("account_id")
.HasComment("sso 계정 아이디");
b.Property<DateTime?>("CompletedAt")
.HasColumnType("timestamp")
.HasColumnName("completed_at")
.HasComment("사파이어 교환 주문 완료 시간");
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp")
.HasColumnName("created_at")
.HasComment("사파이어 교환 주문 시작 시간");
b.Property<sbyte>("OrderStatus")
.HasColumnType("tinyint")
.HasColumnName("order_status")
.HasComment("사파이어 교환 주문 상태");
b.Property<string>("PlanetId")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("planet_id")
.HasComment("플래닛 아이디");
b.Property<decimal>("PlanetMoneyIncDelta")
.HasColumnType("decimal(20, 0)")
.HasColumnName("planet_money_amount")
.HasComment("플래닛에서 발급한 재화 수량");
b.Property<decimal>("SapphireReducedDelta")
.HasColumnType("decimal(20, 0)")
.HasColumnName("sapphire_reduced_amount")
.HasComment("사파이어 차감 수량");
b.Property<string>("UserGuid")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("user_guid")
.HasComment("유저 아이디");
b.HasKey("OrderId");
b.HasIndex("AccountId");
b.HasIndex("CreatedAt");
b.HasIndex("OrderStatus");
b.HasIndex("PlanetId");
b.HasIndex("UserGuid");
b.ToTable("sapphire_exchange_order", (string)null);
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,536 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace BrokerApiCore.Migrations
{
/// <inheritdoc />
public partial class SchemaChanges_152918 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropPrimaryKey(
name: "PK_planet_exchange_orders",
table: "planet_exchange_orders");
migrationBuilder.DropIndex(
name: "IX_planet_exchange_orders_account_id",
table: "planet_exchange_orders");
migrationBuilder.DropIndex(
name: "IX_planet_exchange_orders_created_at",
table: "planet_exchange_orders");
migrationBuilder.DropIndex(
name: "IX_planet_exchange_orders_order_status",
table: "planet_exchange_orders");
migrationBuilder.DropIndex(
name: "IX_planet_exchange_orders_planet_id",
table: "planet_exchange_orders");
migrationBuilder.DropIndex(
name: "IX_planet_exchange_orders_user_guid",
table: "planet_exchange_orders");
migrationBuilder.RenameTable(
name: "planet_exchange_orders",
newName: "PlanetItemExchangeOrders");
migrationBuilder.AlterColumn<string>(
name: "user_guid",
table: "PlanetItemExchangeOrders",
type: "varchar(50)",
maxLength: 50,
nullable: false,
comment: "유저 아이디 (GUID)",
oldClrType: typeof(string),
oldType: "varchar(50)",
oldMaxLength: 50,
oldComment: "유저 아이디 (GUID)")
.Annotation("MySql:CharSet", "utf8mb4")
.Annotation("Relational:ColumnOrder", 8)
.OldAnnotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AlterColumn<string>(
name: "season_id",
table: "PlanetItemExchangeOrders",
type: "varchar(50)",
maxLength: 50,
nullable: false,
comment: "시즌 아이디",
oldClrType: typeof(string),
oldType: "varchar(50)",
oldMaxLength: 50,
oldComment: "시즌 아이디")
.Annotation("MySql:CharSet", "utf8mb4")
.Annotation("Relational:ColumnOrder", 4)
.OldAnnotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AlterColumn<string>(
name: "planet_item_type",
table: "PlanetItemExchangeOrders",
type: "varchar(50)",
maxLength: 50,
nullable: false,
comment: "플래닛 아이템 타입",
oldClrType: typeof(string),
oldType: "varchar(50)",
oldMaxLength: 50,
oldComment: "플래닛 아이템 타입")
.Annotation("MySql:CharSet", "utf8mb4")
.Annotation("Relational:ColumnOrder", 12)
.OldAnnotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AlterColumn<int>(
name: "planet_item_quantity",
table: "PlanetItemExchangeOrders",
type: "INT",
nullable: false,
comment: "플래닛 아이템 갯수",
oldClrType: typeof(int),
oldType: "INT",
oldComment: "플래닛 아이템 갯수")
.Annotation("Relational:ColumnOrder", 14);
migrationBuilder.AlterColumn<string>(
name: "planet_item_id",
table: "PlanetItemExchangeOrders",
type: "varchar(50)",
maxLength: 50,
nullable: false,
comment: "플래닛 아이템 아이디",
oldClrType: typeof(string),
oldType: "varchar(50)",
oldMaxLength: 50,
oldComment: "플래닛 아이템 아이디")
.Annotation("MySql:CharSet", "utf8mb4")
.Annotation("Relational:ColumnOrder", 13)
.OldAnnotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AlterColumn<string>(
name: "planet_id",
table: "PlanetItemExchangeOrders",
type: "varchar(50)",
maxLength: 50,
nullable: false,
comment: "플래닛 아이디",
oldClrType: typeof(string),
oldType: "varchar(50)",
oldMaxLength: 50,
oldComment: "플래닛 아이디")
.Annotation("MySql:CharSet", "utf8mb4")
.Annotation("Relational:ColumnOrder", 3)
.OldAnnotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AlterColumn<string>(
name: "order_status",
table: "PlanetItemExchangeOrders",
type: "varchar(50)",
maxLength: 50,
nullable: false,
comment: "교환 주문 상태",
oldClrType: typeof(string),
oldType: "varchar(50)",
oldMaxLength: 50,
oldComment: "교환 주문 상태")
.Annotation("MySql:CharSet", "utf8mb4")
.Annotation("Relational:ColumnOrder", 2)
.OldAnnotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AlterColumn<string>(
name: "exchange_meta_id",
table: "PlanetItemExchangeOrders",
type: "varchar(50)",
maxLength: 50,
nullable: false,
comment: "교환 메타 아이디",
oldClrType: typeof(string),
oldType: "varchar(50)",
oldMaxLength: 50,
oldComment: "교환 메타 아이디")
.Annotation("MySql:CharSet", "utf8mb4")
.Annotation("Relational:ColumnOrder", 5)
.OldAnnotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AlterColumn<int>(
name: "exchange_meta_amount",
table: "PlanetItemExchangeOrders",
type: "INT",
nullable: false,
comment: "교환 메타 수량",
oldClrType: typeof(int),
oldType: "INT",
oldComment: "교환 메타 수량")
.Annotation("Relational:ColumnOrder", 6);
migrationBuilder.AlterColumn<DateTime>(
name: "created_at",
table: "PlanetItemExchangeOrders",
type: "TIMESTAMP",
nullable: false,
defaultValueSql: "CURRENT_TIMESTAMP",
comment: "교환 주문 시작 시간",
oldClrType: typeof(DateTime),
oldType: "TIMESTAMP",
oldDefaultValueSql: "CURRENT_TIMESTAMP",
oldComment: "교환 주문 시작 시간")
.Annotation("Relational:ColumnOrder", 15);
migrationBuilder.AlterColumn<DateTime>(
name: "completed_at",
table: "PlanetItemExchangeOrders",
type: "TIMESTAMP",
nullable: true,
comment: "교환 주문 완료 시간",
oldClrType: typeof(DateTime),
oldType: "TIMESTAMP",
oldNullable: true,
oldComment: "교환 주문 완료 시간")
.Annotation("Relational:ColumnOrder", 16);
migrationBuilder.AlterColumn<string>(
name: "caliverse_item_type",
table: "PlanetItemExchangeOrders",
type: "varchar(50)",
maxLength: 50,
nullable: false,
comment: "칼리버스 아이템 타입",
oldClrType: typeof(string),
oldType: "varchar(50)",
oldMaxLength: 50,
oldComment: "칼리버스 아이템 타입")
.Annotation("MySql:CharSet", "utf8mb4")
.Annotation("Relational:ColumnOrder", 9)
.OldAnnotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AlterColumn<int>(
name: "caliverse_item_quantity",
table: "PlanetItemExchangeOrders",
type: "INT",
nullable: false,
comment: "칼리버스 아이템 갯수",
oldClrType: typeof(int),
oldType: "INT",
oldComment: "칼리버스 아이템 갯수")
.Annotation("Relational:ColumnOrder", 11);
migrationBuilder.AlterColumn<string>(
name: "caliverse_item_id",
table: "PlanetItemExchangeOrders",
type: "varchar(50)",
maxLength: 50,
nullable: false,
comment: "칼리버스 아이템 아이디",
oldClrType: typeof(string),
oldType: "varchar(50)",
oldMaxLength: 50,
oldComment: "칼리버스 아이템 아이디")
.Annotation("MySql:CharSet", "utf8mb4")
.Annotation("Relational:ColumnOrder", 10)
.OldAnnotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AlterColumn<string>(
name: "account_id",
table: "PlanetItemExchangeOrders",
type: "varchar(50)",
maxLength: 50,
nullable: false,
comment: "SSO 아이디",
oldClrType: typeof(string),
oldType: "varchar(50)",
oldMaxLength: 50,
oldComment: "SSO 아이디")
.Annotation("MySql:CharSet", "utf8mb4")
.Annotation("Relational:ColumnOrder", 7)
.OldAnnotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AlterColumn<string>(
name: "order_id",
table: "PlanetItemExchangeOrders",
type: "varchar(50)",
maxLength: 50,
nullable: false,
comment: "교환 주문 아이디 (GUID)",
oldClrType: typeof(string),
oldType: "varchar(50)",
oldMaxLength: 50,
oldComment: "교환 주문 아이디 (GUID)")
.Annotation("MySql:CharSet", "utf8mb4")
.Annotation("Relational:ColumnOrder", 1)
.OldAnnotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AddPrimaryKey(
name: "PK_PlanetItemExchangeOrders",
table: "PlanetItemExchangeOrders",
column: "order_id");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropPrimaryKey(
name: "PK_PlanetItemExchangeOrders",
table: "PlanetItemExchangeOrders");
migrationBuilder.RenameTable(
name: "PlanetItemExchangeOrders",
newName: "planet_exchange_orders");
migrationBuilder.AlterColumn<string>(
name: "user_guid",
table: "planet_exchange_orders",
type: "varchar(50)",
maxLength: 50,
nullable: false,
comment: "유저 아이디 (GUID)",
oldClrType: typeof(string),
oldType: "varchar(50)",
oldMaxLength: 50,
oldComment: "유저 아이디 (GUID)")
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("Relational:ColumnOrder", 8);
migrationBuilder.AlterColumn<string>(
name: "season_id",
table: "planet_exchange_orders",
type: "varchar(50)",
maxLength: 50,
nullable: false,
comment: "시즌 아이디",
oldClrType: typeof(string),
oldType: "varchar(50)",
oldMaxLength: 50,
oldComment: "시즌 아이디")
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("Relational:ColumnOrder", 4);
migrationBuilder.AlterColumn<string>(
name: "planet_item_type",
table: "planet_exchange_orders",
type: "varchar(50)",
maxLength: 50,
nullable: false,
comment: "플래닛 아이템 타입",
oldClrType: typeof(string),
oldType: "varchar(50)",
oldMaxLength: 50,
oldComment: "플래닛 아이템 타입")
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("Relational:ColumnOrder", 12);
migrationBuilder.AlterColumn<int>(
name: "planet_item_quantity",
table: "planet_exchange_orders",
type: "INT",
nullable: false,
comment: "플래닛 아이템 갯수",
oldClrType: typeof(int),
oldType: "INT",
oldComment: "플래닛 아이템 갯수")
.OldAnnotation("Relational:ColumnOrder", 14);
migrationBuilder.AlterColumn<string>(
name: "planet_item_id",
table: "planet_exchange_orders",
type: "varchar(50)",
maxLength: 50,
nullable: false,
comment: "플래닛 아이템 아이디",
oldClrType: typeof(string),
oldType: "varchar(50)",
oldMaxLength: 50,
oldComment: "플래닛 아이템 아이디")
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("Relational:ColumnOrder", 13);
migrationBuilder.AlterColumn<string>(
name: "planet_id",
table: "planet_exchange_orders",
type: "varchar(50)",
maxLength: 50,
nullable: false,
comment: "플래닛 아이디",
oldClrType: typeof(string),
oldType: "varchar(50)",
oldMaxLength: 50,
oldComment: "플래닛 아이디")
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("Relational:ColumnOrder", 3);
migrationBuilder.AlterColumn<string>(
name: "order_status",
table: "planet_exchange_orders",
type: "varchar(50)",
maxLength: 50,
nullable: false,
comment: "교환 주문 상태",
oldClrType: typeof(string),
oldType: "varchar(50)",
oldMaxLength: 50,
oldComment: "교환 주문 상태")
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("Relational:ColumnOrder", 2);
migrationBuilder.AlterColumn<string>(
name: "exchange_meta_id",
table: "planet_exchange_orders",
type: "varchar(50)",
maxLength: 50,
nullable: false,
comment: "교환 메타 아이디",
oldClrType: typeof(string),
oldType: "varchar(50)",
oldMaxLength: 50,
oldComment: "교환 메타 아이디")
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("Relational:ColumnOrder", 5);
migrationBuilder.AlterColumn<int>(
name: "exchange_meta_amount",
table: "planet_exchange_orders",
type: "INT",
nullable: false,
comment: "교환 메타 수량",
oldClrType: typeof(int),
oldType: "INT",
oldComment: "교환 메타 수량")
.OldAnnotation("Relational:ColumnOrder", 6);
migrationBuilder.AlterColumn<DateTime>(
name: "created_at",
table: "planet_exchange_orders",
type: "TIMESTAMP",
nullable: false,
defaultValueSql: "CURRENT_TIMESTAMP",
comment: "교환 주문 시작 시간",
oldClrType: typeof(DateTime),
oldType: "TIMESTAMP",
oldDefaultValueSql: "CURRENT_TIMESTAMP",
oldComment: "교환 주문 시작 시간")
.OldAnnotation("Relational:ColumnOrder", 15);
migrationBuilder.AlterColumn<DateTime>(
name: "completed_at",
table: "planet_exchange_orders",
type: "TIMESTAMP",
nullable: true,
comment: "교환 주문 완료 시간",
oldClrType: typeof(DateTime),
oldType: "TIMESTAMP",
oldNullable: true,
oldComment: "교환 주문 완료 시간")
.OldAnnotation("Relational:ColumnOrder", 16);
migrationBuilder.AlterColumn<string>(
name: "caliverse_item_type",
table: "planet_exchange_orders",
type: "varchar(50)",
maxLength: 50,
nullable: false,
comment: "칼리버스 아이템 타입",
oldClrType: typeof(string),
oldType: "varchar(50)",
oldMaxLength: 50,
oldComment: "칼리버스 아이템 타입")
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("Relational:ColumnOrder", 9);
migrationBuilder.AlterColumn<int>(
name: "caliverse_item_quantity",
table: "planet_exchange_orders",
type: "INT",
nullable: false,
comment: "칼리버스 아이템 갯수",
oldClrType: typeof(int),
oldType: "INT",
oldComment: "칼리버스 아이템 갯수")
.OldAnnotation("Relational:ColumnOrder", 11);
migrationBuilder.AlterColumn<string>(
name: "caliverse_item_id",
table: "planet_exchange_orders",
type: "varchar(50)",
maxLength: 50,
nullable: false,
comment: "칼리버스 아이템 아이디",
oldClrType: typeof(string),
oldType: "varchar(50)",
oldMaxLength: 50,
oldComment: "칼리버스 아이템 아이디")
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("Relational:ColumnOrder", 10);
migrationBuilder.AlterColumn<string>(
name: "account_id",
table: "planet_exchange_orders",
type: "varchar(50)",
maxLength: 50,
nullable: false,
comment: "SSO 아이디",
oldClrType: typeof(string),
oldType: "varchar(50)",
oldMaxLength: 50,
oldComment: "SSO 아이디")
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("Relational:ColumnOrder", 7);
migrationBuilder.AlterColumn<string>(
name: "order_id",
table: "planet_exchange_orders",
type: "varchar(50)",
maxLength: 50,
nullable: false,
comment: "교환 주문 아이디 (GUID)",
oldClrType: typeof(string),
oldType: "varchar(50)",
oldMaxLength: 50,
oldComment: "교환 주문 아이디 (GUID)")
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("Relational:ColumnOrder", 1);
migrationBuilder.AddPrimaryKey(
name: "PK_planet_exchange_orders",
table: "planet_exchange_orders",
column: "order_id");
migrationBuilder.CreateIndex(
name: "IX_planet_exchange_orders_account_id",
table: "planet_exchange_orders",
column: "account_id");
migrationBuilder.CreateIndex(
name: "IX_planet_exchange_orders_created_at",
table: "planet_exchange_orders",
column: "created_at");
migrationBuilder.CreateIndex(
name: "IX_planet_exchange_orders_order_status",
table: "planet_exchange_orders",
column: "order_status");
migrationBuilder.CreateIndex(
name: "IX_planet_exchange_orders_planet_id",
table: "planet_exchange_orders",
column: "planet_id");
migrationBuilder.CreateIndex(
name: "IX_planet_exchange_orders_user_guid",
table: "planet_exchange_orders",
column: "user_guid");
}
}
}

View File

@@ -0,0 +1,288 @@
// <auto-generated />
using System;
using BrokerCore.Repository.Context;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace BrokerApiCore.Migrations
{
[DbContext(typeof(MetaverseBrokerDbContext))]
[Migration("20250314063529_SchemaChanges_153518")]
partial class SchemaChanges_153518
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.2")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder);
modelBuilder.Entity("BrokerCore.DbEntity.PlanetInfo", b =>
{
b.Property<string>("PlanetId")
.HasColumnType("varchar(50)")
.HasColumnName("planet_id");
b.Property<string>("CompanyName")
.IsRequired()
.HasColumnType("varchar(32)")
.HasColumnName("company_name");
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp")
.HasColumnName("created_at")
.HasDefaultValueSql("CURRENT_TIMESTAMP")
.HasComment("생성 시간");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("varchar(255)")
.HasColumnName("description");
b.Property<string>("PlanetName")
.IsRequired()
.HasColumnType("varchar(32)")
.HasColumnName("planet_name");
b.Property<string>("SecretKey")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("secret_key");
b.Property<string>("ServerType")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("server_type");
b.Property<DateTime>("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp")
.HasColumnName("updated_at")
.HasDefaultValueSql("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
.HasComment("수정 시간");
b.HasKey("PlanetId");
b.HasIndex("CompanyName");
b.HasIndex("PlanetName");
b.HasIndex("SecretKey");
b.ToTable("planet_info", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.PlanetItemExchangeOrder", b =>
{
b.Property<string>("OrderId")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("order_id")
.HasColumnOrder(1)
.HasComment("교환 주문 아이디 (GUID)");
b.Property<string>("AccountId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("account_id")
.HasColumnOrder(7)
.HasComment("SSO 아이디");
b.Property<int>("CaliverseItemDeltaAmount")
.HasColumnType("INT")
.HasColumnName("caliverse_item_quantity")
.HasColumnOrder(11)
.HasComment("칼리버스 아이템 갯수");
b.Property<string>("CaliverseItemId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("caliverse_item_id")
.HasColumnOrder(10)
.HasComment("칼리버스 아이템 아이디");
b.Property<string>("CaliverseItemType")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("caliverse_item_type")
.HasColumnOrder(9)
.HasComment("칼리버스 아이템 타입");
b.Property<DateTime?>("CompletedAt")
.HasColumnType("TIMESTAMP")
.HasColumnName("completed_at")
.HasColumnOrder(16)
.HasComment("교환 주문 완료 시간");
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("TIMESTAMP")
.HasColumnName("created_at")
.HasColumnOrder(15)
.HasDefaultValueSql("CURRENT_TIMESTAMP")
.HasComment("교환 주문 시작 시간");
b.Property<int>("ExchangeMetaAmount")
.HasColumnType("INT")
.HasColumnName("exchange_meta_amount")
.HasColumnOrder(6)
.HasComment("교환 메타 수량");
b.Property<string>("ExchangeMetaId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("exchange_meta_id")
.HasColumnOrder(5)
.HasComment("교환 메타 아이디");
b.Property<string>("OrderStatus")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("order_status")
.HasColumnOrder(2)
.HasComment("교환 주문 상태");
b.Property<string>("PlanetId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("planet_id")
.HasColumnOrder(3)
.HasComment("플래닛 아이디");
b.Property<int>("PlanetItemDeltaAmount")
.HasColumnType("INT")
.HasColumnName("planet_item_quantity")
.HasColumnOrder(14)
.HasComment("플래닛 아이템 갯수");
b.Property<string>("PlanetItemId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("planet_item_id")
.HasColumnOrder(13)
.HasComment("플래닛 아이템 아이디");
b.Property<string>("PlanetItemType")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("planet_item_type")
.HasColumnOrder(12)
.HasComment("플래닛 아이템 타입");
b.Property<string>("SeasonId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("season_id")
.HasColumnOrder(4)
.HasComment("시즌 아이디");
b.Property<string>("UserGuid")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("user_guid")
.HasColumnOrder(8)
.HasComment("유저 아이디 (GUID)");
b.HasKey("OrderId");
b.HasIndex("AccountId");
b.HasIndex("CreatedAt");
b.HasIndex("OrderStatus");
b.HasIndex("PlanetId");
b.HasIndex("SeasonId");
b.HasIndex("UserGuid");
b.ToTable("planet_item_exchange_order", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.SapphireExchangeOrder", b =>
{
b.Property<string>("OrderId")
.HasColumnType("varchar(50)")
.HasColumnName("order_id")
.HasComment("사파이어 교환 주문 아이디 guid");
b.Property<ulong>("AccountId")
.HasColumnType("bigint unsigned")
.HasColumnName("account_id")
.HasComment("sso 계정 아이디");
b.Property<DateTime?>("CompletedAt")
.HasColumnType("timestamp")
.HasColumnName("completed_at")
.HasComment("사파이어 교환 주문 완료 시간");
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp")
.HasColumnName("created_at")
.HasComment("사파이어 교환 주문 시작 시간");
b.Property<sbyte>("OrderStatus")
.HasColumnType("tinyint")
.HasColumnName("order_status")
.HasComment("사파이어 교환 주문 상태");
b.Property<string>("PlanetId")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("planet_id")
.HasComment("플래닛 아이디");
b.Property<decimal>("PlanetMoneyIncDelta")
.HasColumnType("decimal(20, 0)")
.HasColumnName("planet_money_amount")
.HasComment("플래닛에서 발급한 재화 수량");
b.Property<decimal>("SapphireReducedDelta")
.HasColumnType("decimal(20, 0)")
.HasColumnName("sapphire_reduced_amount")
.HasComment("사파이어 차감 수량");
b.Property<string>("UserGuid")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("user_guid")
.HasComment("유저 아이디");
b.HasKey("OrderId");
b.HasIndex("AccountId");
b.HasIndex("CreatedAt");
b.HasIndex("OrderStatus");
b.HasIndex("PlanetId");
b.HasIndex("UserGuid");
b.ToTable("sapphire_exchange_order", (string)null);
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,98 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace BrokerApiCore.Migrations
{
/// <inheritdoc />
public partial class SchemaChanges_153518 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropPrimaryKey(
name: "PK_PlanetItemExchangeOrders",
table: "PlanetItemExchangeOrders");
migrationBuilder.RenameTable(
name: "PlanetItemExchangeOrders",
newName: "planet_item_exchange_order");
migrationBuilder.AddPrimaryKey(
name: "PK_planet_item_exchange_order",
table: "planet_item_exchange_order",
column: "order_id");
migrationBuilder.CreateIndex(
name: "IX_planet_item_exchange_order_account_id",
table: "planet_item_exchange_order",
column: "account_id");
migrationBuilder.CreateIndex(
name: "IX_planet_item_exchange_order_created_at",
table: "planet_item_exchange_order",
column: "created_at");
migrationBuilder.CreateIndex(
name: "IX_planet_item_exchange_order_order_status",
table: "planet_item_exchange_order",
column: "order_status");
migrationBuilder.CreateIndex(
name: "IX_planet_item_exchange_order_planet_id",
table: "planet_item_exchange_order",
column: "planet_id");
migrationBuilder.CreateIndex(
name: "IX_planet_item_exchange_order_season_id",
table: "planet_item_exchange_order",
column: "season_id");
migrationBuilder.CreateIndex(
name: "IX_planet_item_exchange_order_user_guid",
table: "planet_item_exchange_order",
column: "user_guid");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropPrimaryKey(
name: "PK_planet_item_exchange_order",
table: "planet_item_exchange_order");
migrationBuilder.DropIndex(
name: "IX_planet_item_exchange_order_account_id",
table: "planet_item_exchange_order");
migrationBuilder.DropIndex(
name: "IX_planet_item_exchange_order_created_at",
table: "planet_item_exchange_order");
migrationBuilder.DropIndex(
name: "IX_planet_item_exchange_order_order_status",
table: "planet_item_exchange_order");
migrationBuilder.DropIndex(
name: "IX_planet_item_exchange_order_planet_id",
table: "planet_item_exchange_order");
migrationBuilder.DropIndex(
name: "IX_planet_item_exchange_order_season_id",
table: "planet_item_exchange_order");
migrationBuilder.DropIndex(
name: "IX_planet_item_exchange_order_user_guid",
table: "planet_item_exchange_order");
migrationBuilder.RenameTable(
name: "planet_item_exchange_order",
newName: "PlanetItemExchangeOrders");
migrationBuilder.AddPrimaryKey(
name: "PK_PlanetItemExchangeOrders",
table: "PlanetItemExchangeOrders",
column: "order_id");
}
}
}

View File

@@ -0,0 +1,298 @@
// <auto-generated />
using System;
using BrokerCore.Repository.Context;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace BrokerApiCore.Migrations
{
[DbContext(typeof(MetaverseBrokerDbContext))]
[Migration("20250314070903_SchemaChanges_160851")]
partial class SchemaChanges_160851
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.2")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder);
modelBuilder.Entity("BrokerCore.DbEntity.PlanetInfo", b =>
{
b.Property<string>("PlanetId")
.HasColumnType("varchar(50)")
.HasColumnName("planet_id");
b.Property<string>("CompanyName")
.IsRequired()
.HasColumnType("varchar(32)")
.HasColumnName("company_name");
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp")
.HasColumnName("created_at")
.HasDefaultValueSql("CURRENT_TIMESTAMP")
.HasComment("생성 시간");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("varchar(255)")
.HasColumnName("description");
b.Property<string>("PlanetName")
.IsRequired()
.HasColumnType("varchar(32)")
.HasColumnName("planet_name");
b.Property<string>("SecretKey")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("secret_key");
b.Property<string>("ServerType")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("server_type");
b.Property<DateTime>("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp")
.HasColumnName("updated_at")
.HasDefaultValueSql("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
.HasComment("수정 시간");
b.HasKey("PlanetId");
b.HasIndex("CompanyName");
b.HasIndex("PlanetName");
b.HasIndex("SecretKey");
b.ToTable("planet_info", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.PlanetItemExchangeOrder", b =>
{
b.Property<string>("OrderId")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("order_id")
.HasColumnOrder(1)
.HasComment("교환 주문 아이디 (GUID)");
b.Property<string>("AccountId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("account_id")
.HasColumnOrder(7)
.HasComment("SSO 아이디");
b.Property<int>("CaliverseItemDeltaAmount")
.HasColumnType("INT")
.HasColumnName("caliverse_item_quantity")
.HasColumnOrder(11)
.HasComment("칼리버스 아이템 갯수");
b.Property<string>("CaliverseItemId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("caliverse_item_id")
.HasColumnOrder(10)
.HasComment("칼리버스 아이템 아이디");
b.Property<string>("CaliverseItemType")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("caliverse_item_type")
.HasColumnOrder(9)
.HasComment("칼리버스 아이템 타입");
b.Property<DateTime?>("CompletedAt")
.HasColumnType("TIMESTAMP")
.HasColumnName("completed_at")
.HasColumnOrder(16)
.HasComment("교환 주문 완료 시간");
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("TIMESTAMP")
.HasColumnName("created_at")
.HasColumnOrder(15)
.HasDefaultValueSql("CURRENT_TIMESTAMP")
.HasComment("교환 주문 시작 시간");
b.Property<int>("ExchangeMetaAmount")
.HasColumnType("INT")
.HasColumnName("exchange_meta_amount")
.HasColumnOrder(6)
.HasComment("교환 메타 수량");
b.Property<string>("ExchangeMetaId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("exchange_meta_id")
.HasColumnOrder(5)
.HasComment("교환 메타 아이디");
b.Property<string>("OrderStatus")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("order_status")
.HasColumnOrder(2)
.HasComment("교환 주문 상태");
b.Property<string>("PlanetId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("planet_id")
.HasColumnOrder(3)
.HasComment("플래닛 아이디");
b.Property<int>("PlanetItemDeltaAmount")
.HasColumnType("INT")
.HasColumnName("planet_item_quantity")
.HasColumnOrder(14)
.HasComment("플래닛 아이템 갯수");
b.Property<string>("PlanetItemId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("planet_item_id")
.HasColumnOrder(13)
.HasComment("플래닛 아이템 아이디");
b.Property<string>("PlanetItemType")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("planet_item_type")
.HasColumnOrder(12)
.HasComment("플래닛 아이템 타입");
b.Property<string>("SeasonId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("season_id")
.HasColumnOrder(4)
.HasComment("시즌 아이디");
b.Property<string>("UserGuid")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("user_guid")
.HasColumnOrder(8)
.HasComment("유저 아이디 (GUID)");
b.HasKey("OrderId");
b.HasIndex("AccountId");
b.HasIndex("CreatedAt");
b.HasIndex("OrderStatus");
b.HasIndex("PlanetId");
b.HasIndex("SeasonId");
b.HasIndex("UserGuid");
b.ToTable("planet_item_exchange_order", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.SapphireExchangeOrder", b =>
{
b.Property<string>("OrderId")
.HasColumnType("varchar(50)")
.HasColumnName("order_id")
.HasComment("사파이어 교환 주문 아이디 guid");
b.Property<ulong>("AccountId")
.HasColumnType("bigint unsigned")
.HasColumnName("account_id")
.HasComment("sso 계정 아이디");
b.Property<DateTime?>("CompletedAt")
.HasColumnType("timestamp")
.HasColumnName("completed_at")
.HasComment("사파이어 교환 주문 완료 시간");
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp")
.HasColumnName("created_at")
.HasComment("사파이어 교환 주문 시작 시간");
b.Property<sbyte>("OrderStatus")
.HasColumnType("tinyint")
.HasColumnName("order_status")
.HasComment("사파이어 교환 주문 상태");
b.Property<string>("PlanetId")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("planet_id")
.HasComment("플래닛 아이디");
b.Property<decimal>("PlanetMoneyIncDelta")
.HasColumnType("decimal(20, 0)")
.HasColumnName("planet_money_amount")
.HasComment("플래닛에서 발급한 재화 수량");
b.Property<decimal>("SapphireReducedDelta")
.HasColumnType("decimal(20, 0)")
.HasColumnName("sapphire_reduced_amount")
.HasComment("사파이어 차감 수량");
b.Property<string>("UserGuid")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("user_guid")
.HasComment("유저 아이디");
b.HasKey("OrderId");
b.HasIndex("AccountId");
b.HasIndex("CreatedAt");
b.HasIndex("OrderStatus");
b.HasIndex("PlanetId");
b.HasIndex("UserGuid");
b.ToTable("sapphire_exchange_order", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.PlanetItemExchangeOrder", b =>
{
b.HasOne("BrokerCore.DbEntity.PlanetInfo", null)
.WithMany()
.HasForeignKey("PlanetId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired()
.HasConstraintName("FK_PlanetExchangeOrder_PlanetInfo");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,30 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace BrokerApiCore.Migrations
{
/// <inheritdoc />
public partial class SchemaChanges_160851 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddForeignKey(
name: "FK_PlanetExchangeOrder_PlanetInfo",
table: "planet_item_exchange_order",
column: "planet_id",
principalTable: "planet_info",
principalColumn: "planet_id",
onDelete: ReferentialAction.Restrict);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_PlanetExchangeOrder_PlanetInfo",
table: "planet_item_exchange_order");
}
}
}

View File

@@ -0,0 +1,388 @@
// <auto-generated />
using System;
using BrokerCore.Repository.Context;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace BrokerApiCore.Migrations
{
[DbContext(typeof(MetaverseBrokerDbContext))]
[Migration("20250317020124_SchemaChanges_110113")]
partial class SchemaChanges_110113
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.2")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder);
modelBuilder.Entity("BrokerCore.DbEntity.PlanetInfo", b =>
{
b.Property<string>("PlanetId")
.HasColumnType("varchar(50)")
.HasColumnName("planet_id");
b.Property<string>("CompanyName")
.IsRequired()
.HasColumnType("varchar(32)")
.HasColumnName("company_name");
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp")
.HasColumnName("created_at")
.HasDefaultValueSql("CURRENT_TIMESTAMP")
.HasComment("생성 시간");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("varchar(255)")
.HasColumnName("description");
b.Property<string>("PlanetName")
.IsRequired()
.HasColumnType("varchar(32)")
.HasColumnName("planet_name");
b.Property<string>("SecretKey")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("secret_key");
b.Property<string>("ServerType")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("server_type");
b.Property<DateTime>("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp")
.HasColumnName("updated_at")
.HasDefaultValueSql("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
.HasComment("수정 시간");
b.HasKey("PlanetId");
b.HasIndex("CompanyName");
b.HasIndex("PlanetName");
b.HasIndex("SecretKey");
b.ToTable("planet_info", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.PlanetItemExchangeOrder", b =>
{
b.Property<string>("OrderId")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("order_id")
.HasColumnOrder(1)
.HasComment("교환 주문 아이디 (GUID)");
b.Property<string>("AccountId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("account_id")
.HasColumnOrder(7)
.HasComment("SSO 아이디");
b.Property<int>("CaliverseItemDeltaAmount")
.HasColumnType("INT")
.HasColumnName("caliverse_item_quantity")
.HasColumnOrder(11)
.HasComment("칼리버스 아이템 갯수");
b.Property<string>("CaliverseItemId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("caliverse_item_id")
.HasColumnOrder(10)
.HasComment("칼리버스 아이템 아이디");
b.Property<string>("CaliverseItemType")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("caliverse_item_type")
.HasColumnOrder(9)
.HasComment("칼리버스 아이템 타입");
b.Property<DateTime?>("CompletedAt")
.HasColumnType("TIMESTAMP")
.HasColumnName("completed_at")
.HasColumnOrder(16)
.HasComment("교환 주문 완료 시간");
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("TIMESTAMP")
.HasColumnName("created_at")
.HasColumnOrder(15)
.HasDefaultValueSql("CURRENT_TIMESTAMP")
.HasComment("교환 주문 시작 시간");
b.Property<int>("ExchangeMetaAmount")
.HasColumnType("INT")
.HasColumnName("exchange_meta_amount")
.HasColumnOrder(6)
.HasComment("교환 메타 수량");
b.Property<string>("ExchangeMetaId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("exchange_meta_id")
.HasColumnOrder(5)
.HasComment("교환 메타 아이디");
b.Property<string>("OrderStatus")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("order_status")
.HasColumnOrder(2)
.HasComment("교환 주문 상태");
b.Property<string>("PlanetId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("planet_id")
.HasColumnOrder(3)
.HasComment("플래닛 아이디");
b.Property<int>("PlanetItemDeltaAmount")
.HasColumnType("INT")
.HasColumnName("planet_item_quantity")
.HasColumnOrder(14)
.HasComment("플래닛 아이템 갯수");
b.Property<string>("PlanetItemId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("planet_item_id")
.HasColumnOrder(13)
.HasComment("플래닛 아이템 아이디");
b.Property<string>("PlanetItemType")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("planet_item_type")
.HasColumnOrder(12)
.HasComment("플래닛 아이템 타입");
b.Property<string>("SeasonId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("season_id")
.HasColumnOrder(4)
.HasComment("시즌 아이디");
b.Property<string>("UserGuid")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("user_guid")
.HasColumnOrder(8)
.HasComment("유저 아이디 (GUID)");
b.HasKey("OrderId");
b.HasIndex("AccountId");
b.HasIndex("CreatedAt");
b.HasIndex("OrderStatus");
b.HasIndex("PlanetId");
b.HasIndex("SeasonId");
b.HasIndex("UserGuid");
b.ToTable("planet_item_exchange_order", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.PlanetItemExchangeOrderAmountTotalLimit", b =>
{
b.Property<string>("ExchangeMetaId")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("exchange_meta_id")
.HasComment("교환 메타 아이디");
b.Property<DateOnly>("ExchangeDate")
.HasColumnType("date")
.HasColumnName("exchange_date")
.HasComment("교환 일자");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<int>("DailyAmount")
.HasColumnType("INT")
.HasColumnName("daily_amount")
.HasComment("일일 교환 메타 수량 합계");
b.Property<string>("PlanetId")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("SeasonId")
.IsRequired()
.HasColumnType("longtext");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("datetime(6)");
b.HasKey("ExchangeMetaId", "ExchangeDate");
b.HasIndex("ExchangeDate");
b.HasIndex("ExchangeMetaId");
b.ToTable("planet_exchange_order_amount_total_limits", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.PlanetItemExchangeOrderAmountUserLimit", b =>
{
b.Property<string>("ExchangeMetaId")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("exchange_meta_id")
.HasComment("교환 메타 아이디");
b.Property<DateOnly>("ExchangeDate")
.HasColumnType("date")
.HasColumnName("exchange_date")
.HasComment("교환 일자");
b.Property<string>("UserGuid")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("user_guid")
.HasComment("유저 아이디 (GUID)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("datetime(6)");
b.Property<int>("DailyAmount")
.HasColumnType("INT")
.HasColumnName("daily_amount")
.HasComment("사용자별 일일 교환 메타 수량");
b.Property<string>("PlanetId")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("SeasonId")
.IsRequired()
.HasColumnType("longtext");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("datetime(6)");
b.HasKey("ExchangeMetaId", "ExchangeDate", "UserGuid");
b.HasIndex("ExchangeDate");
b.HasIndex("ExchangeMetaId");
b.HasIndex("UserGuid");
b.ToTable("planet_exchange_order_amount_user_limits", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.SapphireExchangeOrder", b =>
{
b.Property<string>("OrderId")
.HasColumnType("varchar(50)")
.HasColumnName("order_id")
.HasComment("사파이어 교환 주문 아이디 guid");
b.Property<ulong>("AccountId")
.HasColumnType("bigint unsigned")
.HasColumnName("account_id")
.HasComment("sso 계정 아이디");
b.Property<DateTime?>("CompletedAt")
.HasColumnType("timestamp")
.HasColumnName("completed_at")
.HasComment("사파이어 교환 주문 완료 시간");
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp")
.HasColumnName("created_at")
.HasComment("사파이어 교환 주문 시작 시간");
b.Property<sbyte>("OrderStatus")
.HasColumnType("tinyint")
.HasColumnName("order_status")
.HasComment("사파이어 교환 주문 상태");
b.Property<string>("PlanetId")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("planet_id")
.HasComment("플래닛 아이디");
b.Property<decimal>("PlanetMoneyIncDelta")
.HasColumnType("decimal(20, 0)")
.HasColumnName("planet_money_amount")
.HasComment("플래닛에서 발급한 재화 수량");
b.Property<decimal>("SapphireReducedDelta")
.HasColumnType("decimal(20, 0)")
.HasColumnName("sapphire_reduced_amount")
.HasComment("사파이어 차감 수량");
b.Property<string>("UserGuid")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("user_guid")
.HasComment("유저 아이디");
b.HasKey("OrderId");
b.HasIndex("AccountId");
b.HasIndex("CreatedAt");
b.HasIndex("OrderStatus");
b.HasIndex("PlanetId");
b.HasIndex("UserGuid");
b.ToTable("sapphire_exchange_order", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.PlanetItemExchangeOrder", b =>
{
b.HasOne("BrokerCore.DbEntity.PlanetInfo", null)
.WithMany()
.HasForeignKey("PlanetId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired()
.HasConstraintName("FK_PlanetExchangeOrder_PlanetInfo");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,94 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace BrokerApiCore.Migrations
{
/// <inheritdoc />
public partial class SchemaChanges_110113 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "planet_exchange_order_amount_total_limits",
columns: table => new
{
exchange_meta_id = table.Column<string>(type: "varchar(50)", maxLength: 50, nullable: false, comment: "교환 메타 아이디")
.Annotation("MySql:CharSet", "utf8mb4"),
exchange_date = table.Column<DateOnly>(type: "date", nullable: false, comment: "교환 일자"),
PlanetId = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
SeasonId = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
daily_amount = table.Column<int>(type: "INT", nullable: false, comment: "일일 교환 메타 수량 합계"),
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
UpdatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_planet_exchange_order_amount_total_limits", x => new { x.exchange_meta_id, x.exchange_date });
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "planet_exchange_order_amount_user_limits",
columns: table => new
{
exchange_meta_id = table.Column<string>(type: "varchar(50)", maxLength: 50, nullable: false, comment: "교환 메타 아이디")
.Annotation("MySql:CharSet", "utf8mb4"),
exchange_date = table.Column<DateOnly>(type: "date", nullable: false, comment: "교환 일자"),
user_guid = table.Column<string>(type: "varchar(50)", maxLength: 50, nullable: false, comment: "유저 아이디 (GUID)")
.Annotation("MySql:CharSet", "utf8mb4"),
PlanetId = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
SeasonId = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
daily_amount = table.Column<int>(type: "INT", nullable: false, comment: "사용자별 일일 교환 메타 수량"),
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
UpdatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_planet_exchange_order_amount_user_limits", x => new { x.exchange_meta_id, x.exchange_date, x.user_guid });
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateIndex(
name: "IX_planet_exchange_order_amount_total_limits_exchange_date",
table: "planet_exchange_order_amount_total_limits",
column: "exchange_date");
migrationBuilder.CreateIndex(
name: "IX_planet_exchange_order_amount_total_limits_exchange_meta_id",
table: "planet_exchange_order_amount_total_limits",
column: "exchange_meta_id");
migrationBuilder.CreateIndex(
name: "IX_planet_exchange_order_amount_user_limits_exchange_date",
table: "planet_exchange_order_amount_user_limits",
column: "exchange_date");
migrationBuilder.CreateIndex(
name: "IX_planet_exchange_order_amount_user_limits_exchange_meta_id",
table: "planet_exchange_order_amount_user_limits",
column: "exchange_meta_id");
migrationBuilder.CreateIndex(
name: "IX_planet_exchange_order_amount_user_limits_user_guid",
table: "planet_exchange_order_amount_user_limits",
column: "user_guid");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "planet_exchange_order_amount_total_limits");
migrationBuilder.DropTable(
name: "planet_exchange_order_amount_user_limits");
}
}
}

View File

@@ -0,0 +1,409 @@
// <auto-generated />
using System;
using BrokerCore.Repository.Context;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace BrokerApiCore.Migrations
{
[DbContext(typeof(MetaverseBrokerDbContext))]
[Migration("20250317030502_SchemaChanges_120450")]
partial class SchemaChanges_120450
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.2")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder);
modelBuilder.Entity("BrokerCore.DbEntity.PlanetInfo", b =>
{
b.Property<string>("PlanetId")
.HasColumnType("varchar(50)")
.HasColumnName("planet_id");
b.Property<string>("CompanyName")
.IsRequired()
.HasColumnType("varchar(32)")
.HasColumnName("company_name");
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp")
.HasColumnName("created_at")
.HasDefaultValueSql("CURRENT_TIMESTAMP")
.HasComment("생성 시간");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("varchar(255)")
.HasColumnName("description");
b.Property<string>("PlanetName")
.IsRequired()
.HasColumnType("varchar(32)")
.HasColumnName("planet_name");
b.Property<string>("SecretKey")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("secret_key");
b.Property<string>("ServerType")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("server_type");
b.Property<DateTime>("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp")
.HasColumnName("updated_at")
.HasDefaultValueSql("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
.HasComment("수정 시간");
b.HasKey("PlanetId");
b.HasIndex("CompanyName");
b.HasIndex("PlanetName");
b.HasIndex("SecretKey");
b.ToTable("planet_info", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.PlanetItemExchangeOrder", b =>
{
b.Property<string>("OrderId")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("order_id")
.HasColumnOrder(1)
.HasComment("교환 주문 아이디 (GUID)");
b.Property<string>("AccountId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("account_id")
.HasColumnOrder(7)
.HasComment("SSO 아이디");
b.Property<int>("CaliverseItemDeltaAmount")
.HasColumnType("INT")
.HasColumnName("caliverse_item_quantity")
.HasColumnOrder(11)
.HasComment("칼리버스 아이템 갯수");
b.Property<string>("CaliverseItemId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("caliverse_item_id")
.HasColumnOrder(10)
.HasComment("칼리버스 아이템 아이디");
b.Property<string>("CaliverseItemType")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("caliverse_item_type")
.HasColumnOrder(9)
.HasComment("칼리버스 아이템 타입");
b.Property<DateTime?>("CompletedAt")
.HasColumnType("TIMESTAMP")
.HasColumnName("completed_at")
.HasColumnOrder(16)
.HasComment("교환 주문 완료 시간");
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("TIMESTAMP")
.HasColumnName("created_at")
.HasColumnOrder(15)
.HasDefaultValueSql("CURRENT_TIMESTAMP")
.HasComment("교환 주문 시작 시간");
b.Property<int>("ExchangeMetaAmount")
.HasColumnType("INT")
.HasColumnName("exchange_meta_amount")
.HasColumnOrder(6)
.HasComment("교환 메타 수량");
b.Property<string>("ExchangeMetaId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("exchange_meta_id")
.HasColumnOrder(5)
.HasComment("교환 메타 아이디");
b.Property<string>("OrderStatus")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("order_status")
.HasColumnOrder(2)
.HasComment("교환 주문 상태");
b.Property<string>("PlanetId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("planet_id")
.HasColumnOrder(3)
.HasComment("플래닛 아이디");
b.Property<int>("PlanetItemDeltaAmount")
.HasColumnType("INT")
.HasColumnName("planet_item_quantity")
.HasColumnOrder(14)
.HasComment("플래닛 아이템 갯수");
b.Property<string>("PlanetItemId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("planet_item_id")
.HasColumnOrder(13)
.HasComment("플래닛 아이템 아이디");
b.Property<string>("PlanetItemType")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("planet_item_type")
.HasColumnOrder(12)
.HasComment("플래닛 아이템 타입");
b.Property<string>("SeasonId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("season_id")
.HasColumnOrder(4)
.HasComment("시즌 아이디");
b.Property<string>("UserGuid")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("user_guid")
.HasColumnOrder(8)
.HasComment("유저 아이디 (GUID)");
b.HasKey("OrderId");
b.HasIndex("AccountId");
b.HasIndex("CreatedAt");
b.HasIndex("OrderStatus");
b.HasIndex("PlanetId");
b.HasIndex("SeasonId");
b.HasIndex("UserGuid");
b.ToTable("planet_item_exchange_order", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.PlanetItemExchangeOrderAmountTotalLimit", b =>
{
b.Property<string>("ExchangeMetaId")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("exchange_meta_id")
.HasComment("교환 메타 아이디");
b.Property<DateOnly>("ExchangeDate")
.HasColumnType("date")
.HasColumnName("exchange_date")
.HasComment("교환 일자");
b.Property<string>("SeasonId")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("season_id")
.HasComment("시즌 아이디");
b.Property<DateTime>("CreatedAt")
.HasColumnType("TIMESTAMP")
.HasColumnName("created_at")
.HasComment("생성 일자");
b.Property<int>("DailyAmount")
.HasColumnType("INT")
.HasColumnName("daily_amount")
.HasComment("일일 교환 메타 수량 합계");
b.Property<string>("PlanetId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("planet_id")
.HasComment("플래닛 아이디");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("TIMESTAMP")
.HasColumnName("updated_at")
.HasComment("업데이트 일자");
b.HasKey("ExchangeMetaId", "ExchangeDate", "SeasonId");
b.HasIndex("ExchangeDate");
b.HasIndex("ExchangeMetaId");
b.HasIndex("PlanetId");
b.HasIndex("SeasonId");
b.ToTable("planet_exchange_order_amount_total_limits", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.PlanetItemExchangeOrderAmountUserLimit", b =>
{
b.Property<string>("ExchangeMetaId")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("exchange_meta_id")
.HasComment("교환 메타 아이디");
b.Property<DateOnly>("ExchangeDate")
.HasColumnType("date")
.HasColumnName("exchange_date")
.HasComment("교환 일자");
b.Property<string>("SeasonId")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("season_id")
.HasComment("시즌 아이디");
b.Property<string>("UserGuid")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("user_guid")
.HasComment("유저 아이디 (GUID)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("TIMESTAMP")
.HasColumnName("created_at")
.HasComment("생성 일자");
b.Property<int>("DailyAmount")
.HasColumnType("INT")
.HasColumnName("daily_amount")
.HasComment("사용자별 일일 교환 메타 수량");
b.Property<string>("PlanetId")
.IsRequired()
.HasColumnType("longtext");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("TIMESTAMP")
.HasColumnName("updated_at")
.HasComment("업데이트 일자");
b.HasKey("ExchangeMetaId", "ExchangeDate", "SeasonId", "UserGuid");
b.HasIndex("ExchangeDate");
b.HasIndex("ExchangeMetaId");
b.HasIndex("SeasonId");
b.HasIndex("UserGuid");
b.ToTable("planet_exchange_order_amount_user_limits", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.SapphireExchangeOrder", b =>
{
b.Property<string>("OrderId")
.HasColumnType("varchar(50)")
.HasColumnName("order_id")
.HasComment("사파이어 교환 주문 아이디 guid");
b.Property<ulong>("AccountId")
.HasColumnType("bigint unsigned")
.HasColumnName("account_id")
.HasComment("sso 계정 아이디");
b.Property<DateTime?>("CompletedAt")
.HasColumnType("timestamp")
.HasColumnName("completed_at")
.HasComment("사파이어 교환 주문 완료 시간");
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp")
.HasColumnName("created_at")
.HasComment("사파이어 교환 주문 시작 시간");
b.Property<sbyte>("OrderStatus")
.HasColumnType("tinyint")
.HasColumnName("order_status")
.HasComment("사파이어 교환 주문 상태");
b.Property<string>("PlanetId")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("planet_id")
.HasComment("플래닛 아이디");
b.Property<decimal>("PlanetMoneyIncDelta")
.HasColumnType("decimal(20, 0)")
.HasColumnName("planet_money_amount")
.HasComment("플래닛에서 발급한 재화 수량");
b.Property<decimal>("SapphireReducedDelta")
.HasColumnType("decimal(20, 0)")
.HasColumnName("sapphire_reduced_amount")
.HasComment("사파이어 차감 수량");
b.Property<string>("UserGuid")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("user_guid")
.HasComment("유저 아이디");
b.HasKey("OrderId");
b.HasIndex("AccountId");
b.HasIndex("CreatedAt");
b.HasIndex("OrderStatus");
b.HasIndex("PlanetId");
b.HasIndex("UserGuid");
b.ToTable("sapphire_exchange_order", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.PlanetItemExchangeOrder", b =>
{
b.HasOne("BrokerCore.DbEntity.PlanetInfo", null)
.WithMany()
.HasForeignKey("PlanetId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired()
.HasConstraintName("FK_PlanetExchangeOrder_PlanetInfo");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,296 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace BrokerApiCore.Migrations
{
/// <inheritdoc />
public partial class SchemaChanges_120450 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropPrimaryKey(
name: "PK_planet_exchange_order_amount_user_limits",
table: "planet_exchange_order_amount_user_limits");
migrationBuilder.DropPrimaryKey(
name: "PK_planet_exchange_order_amount_total_limits",
table: "planet_exchange_order_amount_total_limits");
migrationBuilder.RenameColumn(
name: "UpdatedAt",
table: "planet_exchange_order_amount_user_limits",
newName: "updated_at");
migrationBuilder.RenameColumn(
name: "SeasonId",
table: "planet_exchange_order_amount_user_limits",
newName: "season_id");
migrationBuilder.RenameColumn(
name: "CreatedAt",
table: "planet_exchange_order_amount_user_limits",
newName: "created_at");
migrationBuilder.RenameColumn(
name: "UpdatedAt",
table: "planet_exchange_order_amount_total_limits",
newName: "updated_at");
migrationBuilder.RenameColumn(
name: "SeasonId",
table: "planet_exchange_order_amount_total_limits",
newName: "season_id");
migrationBuilder.RenameColumn(
name: "PlanetId",
table: "planet_exchange_order_amount_total_limits",
newName: "planet_id");
migrationBuilder.RenameColumn(
name: "CreatedAt",
table: "planet_exchange_order_amount_total_limits",
newName: "created_at");
migrationBuilder.AlterColumn<DateTime>(
name: "updated_at",
table: "planet_exchange_order_amount_user_limits",
type: "TIMESTAMP",
nullable: false,
comment: "업데이트 일자",
oldClrType: typeof(DateTime),
oldType: "datetime(6)");
migrationBuilder.AlterColumn<string>(
name: "season_id",
table: "planet_exchange_order_amount_user_limits",
type: "varchar(50)",
maxLength: 50,
nullable: false,
comment: "시즌 아이디",
oldClrType: typeof(string),
oldType: "longtext")
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AlterColumn<DateTime>(
name: "created_at",
table: "planet_exchange_order_amount_user_limits",
type: "TIMESTAMP",
nullable: false,
comment: "생성 일자",
oldClrType: typeof(DateTime),
oldType: "datetime(6)");
migrationBuilder.AlterColumn<DateTime>(
name: "updated_at",
table: "planet_exchange_order_amount_total_limits",
type: "TIMESTAMP",
nullable: false,
comment: "업데이트 일자",
oldClrType: typeof(DateTime),
oldType: "datetime(6)");
migrationBuilder.AlterColumn<string>(
name: "season_id",
table: "planet_exchange_order_amount_total_limits",
type: "varchar(50)",
maxLength: 50,
nullable: false,
comment: "시즌 아이디",
oldClrType: typeof(string),
oldType: "longtext")
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AlterColumn<string>(
name: "planet_id",
table: "planet_exchange_order_amount_total_limits",
type: "varchar(50)",
maxLength: 50,
nullable: false,
comment: "플래닛 아이디",
oldClrType: typeof(string),
oldType: "longtext")
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AlterColumn<DateTime>(
name: "created_at",
table: "planet_exchange_order_amount_total_limits",
type: "TIMESTAMP",
nullable: false,
comment: "생성 일자",
oldClrType: typeof(DateTime),
oldType: "datetime(6)");
migrationBuilder.AddPrimaryKey(
name: "PK_planet_exchange_order_amount_user_limits",
table: "planet_exchange_order_amount_user_limits",
columns: new[] { "exchange_meta_id", "exchange_date", "season_id", "user_guid" });
migrationBuilder.AddPrimaryKey(
name: "PK_planet_exchange_order_amount_total_limits",
table: "planet_exchange_order_amount_total_limits",
columns: new[] { "exchange_meta_id", "exchange_date", "season_id" });
migrationBuilder.CreateIndex(
name: "IX_planet_exchange_order_amount_user_limits_season_id",
table: "planet_exchange_order_amount_user_limits",
column: "season_id");
migrationBuilder.CreateIndex(
name: "IX_planet_exchange_order_amount_total_limits_planet_id",
table: "planet_exchange_order_amount_total_limits",
column: "planet_id");
migrationBuilder.CreateIndex(
name: "IX_planet_exchange_order_amount_total_limits_season_id",
table: "planet_exchange_order_amount_total_limits",
column: "season_id");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropPrimaryKey(
name: "PK_planet_exchange_order_amount_user_limits",
table: "planet_exchange_order_amount_user_limits");
migrationBuilder.DropIndex(
name: "IX_planet_exchange_order_amount_user_limits_season_id",
table: "planet_exchange_order_amount_user_limits");
migrationBuilder.DropPrimaryKey(
name: "PK_planet_exchange_order_amount_total_limits",
table: "planet_exchange_order_amount_total_limits");
migrationBuilder.DropIndex(
name: "IX_planet_exchange_order_amount_total_limits_planet_id",
table: "planet_exchange_order_amount_total_limits");
migrationBuilder.DropIndex(
name: "IX_planet_exchange_order_amount_total_limits_season_id",
table: "planet_exchange_order_amount_total_limits");
migrationBuilder.RenameColumn(
name: "updated_at",
table: "planet_exchange_order_amount_user_limits",
newName: "UpdatedAt");
migrationBuilder.RenameColumn(
name: "created_at",
table: "planet_exchange_order_amount_user_limits",
newName: "CreatedAt");
migrationBuilder.RenameColumn(
name: "season_id",
table: "planet_exchange_order_amount_user_limits",
newName: "SeasonId");
migrationBuilder.RenameColumn(
name: "updated_at",
table: "planet_exchange_order_amount_total_limits",
newName: "UpdatedAt");
migrationBuilder.RenameColumn(
name: "planet_id",
table: "planet_exchange_order_amount_total_limits",
newName: "PlanetId");
migrationBuilder.RenameColumn(
name: "created_at",
table: "planet_exchange_order_amount_total_limits",
newName: "CreatedAt");
migrationBuilder.RenameColumn(
name: "season_id",
table: "planet_exchange_order_amount_total_limits",
newName: "SeasonId");
migrationBuilder.AlterColumn<DateTime>(
name: "UpdatedAt",
table: "planet_exchange_order_amount_user_limits",
type: "datetime(6)",
nullable: false,
oldClrType: typeof(DateTime),
oldType: "TIMESTAMP",
oldComment: "업데이트 일자");
migrationBuilder.AlterColumn<DateTime>(
name: "CreatedAt",
table: "planet_exchange_order_amount_user_limits",
type: "datetime(6)",
nullable: false,
oldClrType: typeof(DateTime),
oldType: "TIMESTAMP",
oldComment: "생성 일자");
migrationBuilder.AlterColumn<string>(
name: "SeasonId",
table: "planet_exchange_order_amount_user_limits",
type: "longtext",
nullable: false,
oldClrType: typeof(string),
oldType: "varchar(50)",
oldMaxLength: 50,
oldComment: "시즌 아이디")
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AlterColumn<DateTime>(
name: "UpdatedAt",
table: "planet_exchange_order_amount_total_limits",
type: "datetime(6)",
nullable: false,
oldClrType: typeof(DateTime),
oldType: "TIMESTAMP",
oldComment: "업데이트 일자");
migrationBuilder.AlterColumn<string>(
name: "PlanetId",
table: "planet_exchange_order_amount_total_limits",
type: "longtext",
nullable: false,
oldClrType: typeof(string),
oldType: "varchar(50)",
oldMaxLength: 50,
oldComment: "플래닛 아이디")
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AlterColumn<DateTime>(
name: "CreatedAt",
table: "planet_exchange_order_amount_total_limits",
type: "datetime(6)",
nullable: false,
oldClrType: typeof(DateTime),
oldType: "TIMESTAMP",
oldComment: "생성 일자");
migrationBuilder.AlterColumn<string>(
name: "SeasonId",
table: "planet_exchange_order_amount_total_limits",
type: "longtext",
nullable: false,
oldClrType: typeof(string),
oldType: "varchar(50)",
oldMaxLength: 50,
oldComment: "시즌 아이디")
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AddPrimaryKey(
name: "PK_planet_exchange_order_amount_user_limits",
table: "planet_exchange_order_amount_user_limits",
columns: new[] { "exchange_meta_id", "exchange_date", "user_guid" });
migrationBuilder.AddPrimaryKey(
name: "PK_planet_exchange_order_amount_total_limits",
table: "planet_exchange_order_amount_total_limits",
columns: new[] { "exchange_meta_id", "exchange_date" });
}
}
}

View File

@@ -0,0 +1,396 @@
// <auto-generated />
using System;
using BrokerCore.Repository.Context;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace BrokerApiCore.Migrations
{
[DbContext(typeof(MetaverseBrokerDbContext))]
[Migration("20250317032756_SchemaChanges_122745")]
partial class SchemaChanges_122745
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.2")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder);
modelBuilder.Entity("BrokerCore.DbEntity.PlanetInfo", b =>
{
b.Property<string>("PlanetId")
.HasColumnType("varchar(50)")
.HasColumnName("planet_id");
b.Property<string>("CompanyName")
.IsRequired()
.HasColumnType("varchar(32)")
.HasColumnName("company_name");
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp")
.HasColumnName("created_at")
.HasDefaultValueSql("CURRENT_TIMESTAMP")
.HasComment("생성 시간");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("varchar(255)")
.HasColumnName("description");
b.Property<string>("PlanetName")
.IsRequired()
.HasColumnType("varchar(32)")
.HasColumnName("planet_name");
b.Property<string>("SecretKey")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("secret_key");
b.Property<string>("ServerType")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("server_type");
b.Property<DateTime>("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp")
.HasColumnName("updated_at")
.HasDefaultValueSql("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
.HasComment("수정 시간");
b.HasKey("PlanetId");
b.HasIndex("CompanyName");
b.HasIndex("PlanetName");
b.HasIndex("SecretKey");
b.ToTable("planet_info", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.PlanetItemExchangeOrder", b =>
{
b.Property<string>("OrderId")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("order_id")
.HasColumnOrder(1)
.HasComment("교환 주문 아이디 (GUID)");
b.Property<string>("AccountId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("account_id")
.HasColumnOrder(7)
.HasComment("SSO 아이디");
b.Property<int>("CaliverseItemDeltaAmount")
.HasColumnType("INT")
.HasColumnName("caliverse_item_quantity")
.HasColumnOrder(11)
.HasComment("칼리버스 아이템 갯수");
b.Property<string>("CaliverseItemId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("caliverse_item_id")
.HasColumnOrder(10)
.HasComment("칼리버스 아이템 아이디");
b.Property<string>("CaliverseItemType")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("caliverse_item_type")
.HasColumnOrder(9)
.HasComment("칼리버스 아이템 타입");
b.Property<DateTime?>("CompletedAt")
.HasColumnType("TIMESTAMP")
.HasColumnName("completed_at")
.HasColumnOrder(16)
.HasComment("교환 주문 완료 시간");
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("TIMESTAMP")
.HasColumnName("created_at")
.HasColumnOrder(15)
.HasDefaultValueSql("CURRENT_TIMESTAMP")
.HasComment("교환 주문 시작 시간");
b.Property<int>("ExchangeMetaAmount")
.HasColumnType("INT")
.HasColumnName("exchange_meta_amount")
.HasColumnOrder(6)
.HasComment("교환 메타 수량");
b.Property<string>("ExchangeMetaId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("exchange_meta_id")
.HasColumnOrder(5)
.HasComment("교환 메타 아이디");
b.Property<string>("OrderStatus")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("order_status")
.HasColumnOrder(2)
.HasComment("교환 주문 상태");
b.Property<string>("PlanetId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("planet_id")
.HasColumnOrder(3)
.HasComment("플래닛 아이디");
b.Property<int>("PlanetItemDeltaAmount")
.HasColumnType("INT")
.HasColumnName("planet_item_quantity")
.HasColumnOrder(14)
.HasComment("플래닛 아이템 갯수");
b.Property<string>("PlanetItemId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("planet_item_id")
.HasColumnOrder(13)
.HasComment("플래닛 아이템 아이디");
b.Property<string>("PlanetItemType")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("planet_item_type")
.HasColumnOrder(12)
.HasComment("플래닛 아이템 타입");
b.Property<string>("SeasonId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("season_id")
.HasColumnOrder(4)
.HasComment("시즌 아이디");
b.Property<string>("UserGuid")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("user_guid")
.HasColumnOrder(8)
.HasComment("유저 아이디 (GUID)");
b.HasKey("OrderId");
b.HasIndex("AccountId");
b.HasIndex("CreatedAt");
b.HasIndex("OrderStatus");
b.HasIndex("PlanetId");
b.HasIndex("SeasonId");
b.HasIndex("UserGuid");
b.ToTable("planet_item_exchange_order", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.PlanetItemExchangeOrderAmountTotalLimit", b =>
{
b.Property<string>("ExchangeMetaId")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("exchange_meta_id")
.HasComment("교환 메타 아이디");
b.Property<DateOnly>("ExchangeDate")
.HasColumnType("date")
.HasColumnName("exchange_date")
.HasComment("교환 일자");
b.Property<string>("SeasonId")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("season_id")
.HasComment("시즌 아이디");
b.Property<DateTime>("CreatedAt")
.HasColumnType("TIMESTAMP")
.HasColumnName("created_at")
.HasComment("생성 일자");
b.Property<int>("DailyAmount")
.HasColumnType("INT")
.HasColumnName("daily_amount")
.HasComment("일일 교환 메타 수량 합계");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("TIMESTAMP")
.HasColumnName("updated_at")
.HasComment("업데이트 일자");
b.HasKey("ExchangeMetaId", "ExchangeDate", "SeasonId");
b.HasIndex("ExchangeDate");
b.HasIndex("ExchangeMetaId");
b.HasIndex("SeasonId");
b.ToTable("planet_exchange_order_amount_total_limits", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.PlanetItemExchangeOrderAmountUserLimit", b =>
{
b.Property<string>("ExchangeMetaId")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("exchange_meta_id")
.HasComment("교환 메타 아이디");
b.Property<DateOnly>("ExchangeDate")
.HasColumnType("date")
.HasColumnName("exchange_date")
.HasComment("교환 일자");
b.Property<string>("SeasonId")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("season_id")
.HasComment("시즌 아이디");
b.Property<string>("UserGuid")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("user_guid")
.HasComment("유저 아이디 (GUID)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("TIMESTAMP")
.HasColumnName("created_at")
.HasComment("생성 일자");
b.Property<int>("DailyAmount")
.HasColumnType("INT")
.HasColumnName("daily_amount")
.HasComment("사용자별 일일 교환 메타 수량");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("TIMESTAMP")
.HasColumnName("updated_at")
.HasComment("업데이트 일자");
b.HasKey("ExchangeMetaId", "ExchangeDate", "SeasonId", "UserGuid");
b.HasIndex("ExchangeDate");
b.HasIndex("ExchangeMetaId");
b.HasIndex("SeasonId");
b.HasIndex("UserGuid");
b.ToTable("planet_exchange_order_amount_user_limits", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.SapphireExchangeOrder", b =>
{
b.Property<string>("OrderId")
.HasColumnType("varchar(50)")
.HasColumnName("order_id")
.HasComment("사파이어 교환 주문 아이디 guid");
b.Property<ulong>("AccountId")
.HasColumnType("bigint unsigned")
.HasColumnName("account_id")
.HasComment("sso 계정 아이디");
b.Property<DateTime?>("CompletedAt")
.HasColumnType("timestamp")
.HasColumnName("completed_at")
.HasComment("사파이어 교환 주문 완료 시간");
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp")
.HasColumnName("created_at")
.HasComment("사파이어 교환 주문 시작 시간");
b.Property<sbyte>("OrderStatus")
.HasColumnType("tinyint")
.HasColumnName("order_status")
.HasComment("사파이어 교환 주문 상태");
b.Property<string>("PlanetId")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("planet_id")
.HasComment("플래닛 아이디");
b.Property<decimal>("PlanetMoneyIncDelta")
.HasColumnType("decimal(20, 0)")
.HasColumnName("planet_money_amount")
.HasComment("플래닛에서 발급한 재화 수량");
b.Property<decimal>("SapphireReducedDelta")
.HasColumnType("decimal(20, 0)")
.HasColumnName("sapphire_reduced_amount")
.HasComment("사파이어 차감 수량");
b.Property<string>("UserGuid")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("user_guid")
.HasComment("유저 아이디");
b.HasKey("OrderId");
b.HasIndex("AccountId");
b.HasIndex("CreatedAt");
b.HasIndex("OrderStatus");
b.HasIndex("PlanetId");
b.HasIndex("UserGuid");
b.ToTable("sapphire_exchange_order", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.PlanetItemExchangeOrder", b =>
{
b.HasOne("BrokerCore.DbEntity.PlanetInfo", null)
.WithMany()
.HasForeignKey("PlanetId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired()
.HasConstraintName("FK_PlanetExchangeOrder_PlanetInfo");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,52 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace BrokerApiCore.Migrations
{
/// <inheritdoc />
public partial class SchemaChanges_122745 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropIndex(
name: "IX_planet_exchange_order_amount_total_limits_planet_id",
table: "planet_exchange_order_amount_total_limits");
migrationBuilder.DropColumn(
name: "PlanetId",
table: "planet_exchange_order_amount_user_limits");
migrationBuilder.DropColumn(
name: "planet_id",
table: "planet_exchange_order_amount_total_limits");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "PlanetId",
table: "planet_exchange_order_amount_user_limits",
type: "longtext",
nullable: false)
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AddColumn<string>(
name: "planet_id",
table: "planet_exchange_order_amount_total_limits",
type: "varchar(50)",
maxLength: 50,
nullable: false,
defaultValue: "",
comment: "플래닛 아이디")
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateIndex(
name: "IX_planet_exchange_order_amount_total_limits_planet_id",
table: "planet_exchange_order_amount_total_limits",
column: "planet_id");
}
}
}

View File

@@ -0,0 +1,396 @@
// <auto-generated />
using System;
using BrokerCore.Repository.Context;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace BrokerApiCore.Migrations
{
[DbContext(typeof(MetaverseBrokerDbContext))]
[Migration("20250321034709_SchemaChanges_124658")]
partial class SchemaChanges_124658
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.2")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder);
modelBuilder.Entity("BrokerCore.DbEntity.PlanetInfo", b =>
{
b.Property<string>("PlanetId")
.HasColumnType("varchar(50)")
.HasColumnName("planet_id");
b.Property<string>("CompanyName")
.IsRequired()
.HasColumnType("varchar(32)")
.HasColumnName("company_name");
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp")
.HasColumnName("created_at")
.HasDefaultValueSql("CURRENT_TIMESTAMP")
.HasComment("생성 시간");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("varchar(255)")
.HasColumnName("description");
b.Property<string>("PlanetName")
.IsRequired()
.HasColumnType("varchar(32)")
.HasColumnName("planet_name");
b.Property<string>("SecretKey")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("secret_key");
b.Property<string>("ServerType")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("server_type");
b.Property<DateTime>("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp")
.HasColumnName("updated_at")
.HasDefaultValueSql("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
.HasComment("수정 시간");
b.HasKey("PlanetId");
b.HasIndex("CompanyName");
b.HasIndex("PlanetName");
b.HasIndex("SecretKey");
b.ToTable("planet_info", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.PlanetItemExchangeOrder", b =>
{
b.Property<string>("OrderId")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("order_id")
.HasColumnOrder(1)
.HasComment("교환 주문 아이디 (GUID)");
b.Property<string>("AccountId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("account_id")
.HasColumnOrder(7)
.HasComment("SSO 아이디");
b.Property<int>("CaliverseItemDeltaAmount")
.HasColumnType("INT")
.HasColumnName("caliverse_item_quantity")
.HasColumnOrder(11)
.HasComment("칼리버스 아이템 갯수");
b.Property<string>("CaliverseItemId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("caliverse_item_id")
.HasColumnOrder(10)
.HasComment("칼리버스 아이템 아이디");
b.Property<string>("CaliverseItemType")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("caliverse_item_type")
.HasColumnOrder(9)
.HasComment("칼리버스 아이템 타입");
b.Property<DateTime?>("CompletedAt")
.HasColumnType("TIMESTAMP")
.HasColumnName("completed_at")
.HasColumnOrder(16)
.HasComment("교환 주문 완료 시간");
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("TIMESTAMP")
.HasColumnName("created_at")
.HasColumnOrder(15)
.HasDefaultValueSql("CURRENT_TIMESTAMP")
.HasComment("교환 주문 시작 시간");
b.Property<int>("ExchangeMetaAmount")
.HasColumnType("INT")
.HasColumnName("exchange_meta_amount")
.HasColumnOrder(6)
.HasComment("교환 메타 수량");
b.Property<string>("ExchangeMetaId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("exchange_meta_id")
.HasColumnOrder(5)
.HasComment("교환 메타 아이디");
b.Property<string>("OrderStatus")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("order_status")
.HasColumnOrder(2)
.HasComment("교환 주문 상태");
b.Property<string>("PlanetId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("planet_id")
.HasColumnOrder(3)
.HasComment("플래닛 아이디");
b.Property<int>("PlanetItemDeltaAmount")
.HasColumnType("INT")
.HasColumnName("planet_item_quantity")
.HasColumnOrder(14)
.HasComment("플래닛 아이템 갯수");
b.Property<string>("PlanetItemId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("planet_item_id")
.HasColumnOrder(13)
.HasComment("플래닛 아이템 아이디");
b.Property<string>("PlanetItemType")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("planet_item_type")
.HasColumnOrder(12)
.HasComment("플래닛 아이템 타입");
b.Property<string>("SeasonId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("season_id")
.HasColumnOrder(4)
.HasComment("시즌 아이디");
b.Property<string>("UserGuid")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("user_guid")
.HasColumnOrder(8)
.HasComment("유저 아이디 (GUID)");
b.HasKey("OrderId");
b.HasIndex("AccountId");
b.HasIndex("CreatedAt");
b.HasIndex("OrderStatus");
b.HasIndex("PlanetId");
b.HasIndex("SeasonId");
b.HasIndex("UserGuid");
b.ToTable("planet_item_exchange_order", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.PlanetItemExchangeOrderAmountTotalLimit", b =>
{
b.Property<string>("ExchangeMetaId")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("exchange_meta_id")
.HasComment("교환 메타 아이디");
b.Property<DateOnly>("ExchangeDate")
.HasColumnType("date")
.HasColumnName("exchange_date")
.HasComment("교환 일자");
b.Property<string>("SeasonId")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("season_id")
.HasComment("시즌 아이디");
b.Property<DateTime>("CreatedAt")
.HasColumnType("TIMESTAMP")
.HasColumnName("created_at")
.HasComment("생성 일자");
b.Property<int>("DailyAmount")
.HasColumnType("INT")
.HasColumnName("daily_amount")
.HasComment("일일 교환 메타 수량 합계");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("TIMESTAMP")
.HasColumnName("updated_at")
.HasComment("업데이트 일자");
b.HasKey("ExchangeMetaId", "ExchangeDate", "SeasonId");
b.HasIndex("ExchangeDate");
b.HasIndex("ExchangeMetaId");
b.HasIndex("SeasonId");
b.ToTable("planet_exchange_order_amount_total_limits", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.PlanetItemExchangeOrderAmountUserLimit", b =>
{
b.Property<string>("ExchangeMetaId")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("exchange_meta_id")
.HasComment("교환 메타 아이디");
b.Property<DateOnly>("ExchangeDate")
.HasColumnType("date")
.HasColumnName("exchange_date")
.HasComment("교환 일자");
b.Property<string>("SeasonId")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("season_id")
.HasComment("시즌 아이디");
b.Property<string>("UserGuid")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("user_guid")
.HasComment("유저 아이디 (GUID)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("TIMESTAMP")
.HasColumnName("created_at")
.HasComment("생성 일자");
b.Property<int>("DailyAmount")
.HasColumnType("INT")
.HasColumnName("daily_amount")
.HasComment("사용자별 일일 교환 메타 수량");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("TIMESTAMP")
.HasColumnName("updated_at")
.HasComment("업데이트 일자");
b.HasKey("ExchangeMetaId", "ExchangeDate", "SeasonId", "UserGuid");
b.HasIndex("ExchangeDate");
b.HasIndex("ExchangeMetaId");
b.HasIndex("SeasonId");
b.HasIndex("UserGuid");
b.ToTable("planet_exchange_order_amount_user_limits", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.SapphireExchangeOrder", b =>
{
b.Property<string>("OrderId")
.HasColumnType("varchar(60)")
.HasColumnName("order_id")
.HasComment("사파이어 교환 주문 아이디 guid");
b.Property<ulong>("AccountId")
.HasColumnType("bigint unsigned")
.HasColumnName("account_id")
.HasComment("sso 계정 아이디");
b.Property<DateTime?>("CompletedAt")
.HasColumnType("timestamp")
.HasColumnName("completed_at")
.HasComment("사파이어 교환 주문 완료 시간");
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp")
.HasColumnName("created_at")
.HasComment("사파이어 교환 주문 시작 시간");
b.Property<sbyte>("OrderStatus")
.HasColumnType("tinyint")
.HasColumnName("order_status")
.HasComment("사파이어 교환 주문 상태");
b.Property<string>("PlanetId")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("planet_id")
.HasComment("플래닛 아이디");
b.Property<decimal>("PlanetMoneyIncDelta")
.HasColumnType("decimal(20, 0)")
.HasColumnName("planet_money_amount")
.HasComment("플래닛에서 발급한 재화 수량");
b.Property<decimal>("SapphireReducedDelta")
.HasColumnType("decimal(20, 0)")
.HasColumnName("sapphire_reduced_amount")
.HasComment("사파이어 차감 수량");
b.Property<string>("UserGuid")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("user_guid")
.HasComment("유저 아이디");
b.HasKey("OrderId");
b.HasIndex("AccountId");
b.HasIndex("CreatedAt");
b.HasIndex("OrderStatus");
b.HasIndex("PlanetId");
b.HasIndex("UserGuid");
b.ToTable("sapphire_exchange_order", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.PlanetItemExchangeOrder", b =>
{
b.HasOne("BrokerCore.DbEntity.PlanetInfo", null)
.WithMany()
.HasForeignKey("PlanetId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired()
.HasConstraintName("FK_PlanetExchangeOrder_PlanetInfo");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,42 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace BrokerApiCore.Migrations
{
/// <inheritdoc />
public partial class SchemaChanges_124658 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "order_id",
table: "sapphire_exchange_order",
type: "varchar(60)",
nullable: false,
comment: "사파이어 교환 주문 아이디 guid",
oldClrType: typeof(string),
oldType: "varchar(50)",
oldComment: "사파이어 교환 주문 아이디 guid")
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "order_id",
table: "sapphire_exchange_order",
type: "varchar(50)",
nullable: false,
comment: "사파이어 교환 주문 아이디 guid",
oldClrType: typeof(string),
oldType: "varchar(60)",
oldComment: "사파이어 교환 주문 아이디 guid")
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4");
}
}
}

View File

@@ -0,0 +1,404 @@
// <auto-generated />
using System;
using BrokerCore.Repository.Context;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace BrokerApiCore.Migrations
{
[DbContext(typeof(MetaverseBrokerDbContext))]
[Migration("20250324074920_SchemaChanges_164908")]
partial class SchemaChanges_164908
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.2")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder);
modelBuilder.Entity("BrokerCore.DbEntity.PlanetInfo", b =>
{
b.Property<string>("PlanetId")
.HasColumnType("varchar(50)")
.HasColumnName("planet_id");
b.Property<string>("CompanyName")
.IsRequired()
.HasColumnType("varchar(32)")
.HasColumnName("company_name");
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp")
.HasColumnName("created_at")
.HasDefaultValueSql("CURRENT_TIMESTAMP")
.HasComment("생성 시간");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("varchar(255)")
.HasColumnName("description");
b.Property<string>("PlanetName")
.IsRequired()
.HasColumnType("varchar(32)")
.HasColumnName("planet_name");
b.Property<string>("SecretKey")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("secret_key");
b.Property<string>("ServerType")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("server_type");
b.Property<DateTime>("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp")
.HasColumnName("updated_at")
.HasDefaultValueSql("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
.HasComment("수정 시간");
b.HasKey("PlanetId");
b.HasIndex("CompanyName");
b.HasIndex("PlanetName");
b.HasIndex("SecretKey");
b.ToTable("planet_info", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.PlanetItemExchangeOrder", b =>
{
b.Property<string>("OrderId")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("order_id")
.HasColumnOrder(1)
.HasComment("교환 주문 아이디 (GUID)");
b.Property<string>("AccountId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("account_id")
.HasColumnOrder(7)
.HasComment("SSO 아이디");
b.Property<int>("CaliverseItemDeltaAmount")
.HasColumnType("INT")
.HasColumnName("caliverse_item_quantity")
.HasColumnOrder(12)
.HasComment("칼리버스 아이템 갯수");
b.Property<string>("CaliverseItemId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("caliverse_item_id")
.HasColumnOrder(11)
.HasComment("칼리버스 아이템 아이디");
b.Property<string>("CaliverseItemType")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("caliverse_item_type")
.HasColumnOrder(10)
.HasComment("칼리버스 아이템 타입");
b.Property<DateTime?>("CompletedAt")
.HasColumnType("TIMESTAMP")
.HasColumnName("completed_at")
.HasColumnOrder(17)
.HasComment("교환 주문 완료 시간");
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("TIMESTAMP")
.HasColumnName("created_at")
.HasColumnOrder(16)
.HasDefaultValueSql("CURRENT_TIMESTAMP")
.HasComment("교환 주문 시작 시간");
b.Property<int>("ExchangeMetaAmount")
.HasColumnType("INT")
.HasColumnName("exchange_meta_amount")
.HasColumnOrder(6)
.HasComment("교환 메타 수량");
b.Property<string>("ExchangeMetaId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("exchange_meta_id")
.HasColumnOrder(5)
.HasComment("교환 메타 아이디");
b.Property<string>("Nickname")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("nickname")
.HasColumnOrder(9)
.HasComment("유저 닉네임");
b.Property<string>("OrderStatus")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("order_status")
.HasColumnOrder(2)
.HasComment("교환 주문 상태");
b.Property<string>("PlanetId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("planet_id")
.HasColumnOrder(3)
.HasComment("플래닛 아이디");
b.Property<int>("PlanetItemDeltaAmount")
.HasColumnType("INT")
.HasColumnName("planet_item_quantity")
.HasColumnOrder(15)
.HasComment("플래닛 아이템 갯수");
b.Property<string>("PlanetItemId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("planet_item_id")
.HasColumnOrder(14)
.HasComment("플래닛 아이템 아이디");
b.Property<string>("PlanetItemType")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("planet_item_type")
.HasColumnOrder(13)
.HasComment("플래닛 아이템 타입");
b.Property<string>("SeasonId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("season_id")
.HasColumnOrder(4)
.HasComment("시즌 아이디");
b.Property<string>("UserGuid")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("user_guid")
.HasColumnOrder(8)
.HasComment("유저 아이디 (GUID)");
b.HasKey("OrderId");
b.HasIndex("AccountId");
b.HasIndex("CreatedAt");
b.HasIndex("OrderStatus");
b.HasIndex("PlanetId");
b.HasIndex("SeasonId");
b.HasIndex("UserGuid");
b.ToTable("planet_item_exchange_order", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.PlanetItemExchangeOrderAmountTotalLimit", b =>
{
b.Property<string>("ExchangeMetaId")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("exchange_meta_id")
.HasComment("교환 메타 아이디");
b.Property<DateOnly>("ExchangeDate")
.HasColumnType("date")
.HasColumnName("exchange_date")
.HasComment("교환 일자");
b.Property<string>("SeasonId")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("season_id")
.HasComment("시즌 아이디");
b.Property<DateTime>("CreatedAt")
.HasColumnType("TIMESTAMP")
.HasColumnName("created_at")
.HasComment("생성 일자");
b.Property<int>("DailyAmount")
.HasColumnType("INT")
.HasColumnName("daily_amount")
.HasComment("일일 교환 메타 수량 합계");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("TIMESTAMP")
.HasColumnName("updated_at")
.HasComment("업데이트 일자");
b.HasKey("ExchangeMetaId", "ExchangeDate", "SeasonId");
b.HasIndex("ExchangeDate");
b.HasIndex("ExchangeMetaId");
b.HasIndex("SeasonId");
b.ToTable("planet_exchange_order_amount_total_limits", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.PlanetItemExchangeOrderAmountUserLimit", b =>
{
b.Property<string>("ExchangeMetaId")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("exchange_meta_id")
.HasComment("교환 메타 아이디");
b.Property<DateOnly>("ExchangeDate")
.HasColumnType("date")
.HasColumnName("exchange_date")
.HasComment("교환 일자");
b.Property<string>("SeasonId")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("season_id")
.HasComment("시즌 아이디");
b.Property<string>("UserGuid")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("user_guid")
.HasComment("유저 아이디 (GUID)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("TIMESTAMP")
.HasColumnName("created_at")
.HasComment("생성 일자");
b.Property<int>("DailyAmount")
.HasColumnType("INT")
.HasColumnName("daily_amount")
.HasComment("사용자별 일일 교환 메타 수량");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("TIMESTAMP")
.HasColumnName("updated_at")
.HasComment("업데이트 일자");
b.HasKey("ExchangeMetaId", "ExchangeDate", "SeasonId", "UserGuid");
b.HasIndex("ExchangeDate");
b.HasIndex("ExchangeMetaId");
b.HasIndex("SeasonId");
b.HasIndex("UserGuid");
b.ToTable("planet_exchange_order_amount_user_limits", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.SapphireExchangeOrder", b =>
{
b.Property<string>("OrderId")
.HasColumnType("varchar(60)")
.HasColumnName("order_id")
.HasComment("사파이어 교환 주문 아이디 guid");
b.Property<ulong>("AccountId")
.HasColumnType("bigint unsigned")
.HasColumnName("account_id")
.HasComment("sso 계정 아이디");
b.Property<DateTime?>("CompletedAt")
.HasColumnType("timestamp")
.HasColumnName("completed_at")
.HasComment("사파이어 교환 주문 완료 시간");
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp")
.HasColumnName("created_at")
.HasComment("사파이어 교환 주문 시작 시간");
b.Property<sbyte>("OrderStatus")
.HasColumnType("tinyint")
.HasColumnName("order_status")
.HasComment("사파이어 교환 주문 상태");
b.Property<string>("PlanetId")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("planet_id")
.HasComment("플래닛 아이디");
b.Property<decimal>("PlanetMoneyIncDelta")
.HasColumnType("decimal(20, 0)")
.HasColumnName("planet_money_amount")
.HasComment("플래닛에서 발급한 재화 수량");
b.Property<decimal>("SapphireReducedDelta")
.HasColumnType("decimal(20, 0)")
.HasColumnName("sapphire_reduced_amount")
.HasComment("사파이어 차감 수량");
b.Property<string>("UserGuid")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("user_guid")
.HasComment("유저 아이디");
b.HasKey("OrderId");
b.HasIndex("AccountId");
b.HasIndex("CreatedAt");
b.HasIndex("OrderStatus");
b.HasIndex("PlanetId");
b.HasIndex("UserGuid");
b.ToTable("sapphire_exchange_order", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.PlanetItemExchangeOrder", b =>
{
b.HasOne("BrokerCore.DbEntity.PlanetInfo", null)
.WithMany()
.HasForeignKey("PlanetId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired()
.HasConstraintName("FK_PlanetExchangeOrder_PlanetInfo");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,264 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace BrokerApiCore.Migrations
{
/// <inheritdoc />
public partial class SchemaChanges_164908 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "planet_item_type",
table: "planet_item_exchange_order",
type: "varchar(50)",
maxLength: 50,
nullable: false,
comment: "플래닛 아이템 타입",
oldClrType: typeof(string),
oldType: "varchar(50)",
oldMaxLength: 50,
oldComment: "플래닛 아이템 타입")
.Annotation("MySql:CharSet", "utf8mb4")
.Annotation("Relational:ColumnOrder", 13)
.OldAnnotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("Relational:ColumnOrder", 12);
migrationBuilder.AlterColumn<int>(
name: "planet_item_quantity",
table: "planet_item_exchange_order",
type: "INT",
nullable: false,
comment: "플래닛 아이템 갯수",
oldClrType: typeof(int),
oldType: "INT",
oldComment: "플래닛 아이템 갯수")
.Annotation("Relational:ColumnOrder", 15)
.OldAnnotation("Relational:ColumnOrder", 14);
migrationBuilder.AlterColumn<string>(
name: "planet_item_id",
table: "planet_item_exchange_order",
type: "varchar(50)",
maxLength: 50,
nullable: false,
comment: "플래닛 아이템 아이디",
oldClrType: typeof(string),
oldType: "varchar(50)",
oldMaxLength: 50,
oldComment: "플래닛 아이템 아이디")
.Annotation("MySql:CharSet", "utf8mb4")
.Annotation("Relational:ColumnOrder", 14)
.OldAnnotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("Relational:ColumnOrder", 13);
migrationBuilder.AlterColumn<DateTime>(
name: "created_at",
table: "planet_item_exchange_order",
type: "TIMESTAMP",
nullable: false,
defaultValueSql: "CURRENT_TIMESTAMP",
comment: "교환 주문 시작 시간",
oldClrType: typeof(DateTime),
oldType: "TIMESTAMP",
oldDefaultValueSql: "CURRENT_TIMESTAMP",
oldComment: "교환 주문 시작 시간")
.Annotation("Relational:ColumnOrder", 16)
.OldAnnotation("Relational:ColumnOrder", 15);
migrationBuilder.AlterColumn<DateTime>(
name: "completed_at",
table: "planet_item_exchange_order",
type: "TIMESTAMP",
nullable: true,
comment: "교환 주문 완료 시간",
oldClrType: typeof(DateTime),
oldType: "TIMESTAMP",
oldNullable: true,
oldComment: "교환 주문 완료 시간")
.Annotation("Relational:ColumnOrder", 17)
.OldAnnotation("Relational:ColumnOrder", 16);
migrationBuilder.AlterColumn<string>(
name: "caliverse_item_type",
table: "planet_item_exchange_order",
type: "varchar(50)",
maxLength: 50,
nullable: false,
comment: "칼리버스 아이템 타입",
oldClrType: typeof(string),
oldType: "varchar(50)",
oldMaxLength: 50,
oldComment: "칼리버스 아이템 타입")
.Annotation("MySql:CharSet", "utf8mb4")
.Annotation("Relational:ColumnOrder", 10)
.OldAnnotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("Relational:ColumnOrder", 9);
migrationBuilder.AlterColumn<int>(
name: "caliverse_item_quantity",
table: "planet_item_exchange_order",
type: "INT",
nullable: false,
comment: "칼리버스 아이템 갯수",
oldClrType: typeof(int),
oldType: "INT",
oldComment: "칼리버스 아이템 갯수")
.Annotation("Relational:ColumnOrder", 12)
.OldAnnotation("Relational:ColumnOrder", 11);
migrationBuilder.AlterColumn<string>(
name: "caliverse_item_id",
table: "planet_item_exchange_order",
type: "varchar(50)",
maxLength: 50,
nullable: false,
comment: "칼리버스 아이템 아이디",
oldClrType: typeof(string),
oldType: "varchar(50)",
oldMaxLength: 50,
oldComment: "칼리버스 아이템 아이디")
.Annotation("MySql:CharSet", "utf8mb4")
.Annotation("Relational:ColumnOrder", 11)
.OldAnnotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("Relational:ColumnOrder", 10);
migrationBuilder.AddColumn<string>(
name: "nickname",
table: "planet_item_exchange_order",
type: "varchar(50)",
maxLength: 50,
nullable: false,
defaultValue: "",
comment: "유저 닉네임")
.Annotation("MySql:CharSet", "utf8mb4")
.Annotation("Relational:ColumnOrder", 9);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "nickname",
table: "planet_item_exchange_order");
migrationBuilder.AlterColumn<string>(
name: "planet_item_type",
table: "planet_item_exchange_order",
type: "varchar(50)",
maxLength: 50,
nullable: false,
comment: "플래닛 아이템 타입",
oldClrType: typeof(string),
oldType: "varchar(50)",
oldMaxLength: 50,
oldComment: "플래닛 아이템 타입")
.Annotation("MySql:CharSet", "utf8mb4")
.Annotation("Relational:ColumnOrder", 12)
.OldAnnotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("Relational:ColumnOrder", 13);
migrationBuilder.AlterColumn<int>(
name: "planet_item_quantity",
table: "planet_item_exchange_order",
type: "INT",
nullable: false,
comment: "플래닛 아이템 갯수",
oldClrType: typeof(int),
oldType: "INT",
oldComment: "플래닛 아이템 갯수")
.Annotation("Relational:ColumnOrder", 14)
.OldAnnotation("Relational:ColumnOrder", 15);
migrationBuilder.AlterColumn<string>(
name: "planet_item_id",
table: "planet_item_exchange_order",
type: "varchar(50)",
maxLength: 50,
nullable: false,
comment: "플래닛 아이템 아이디",
oldClrType: typeof(string),
oldType: "varchar(50)",
oldMaxLength: 50,
oldComment: "플래닛 아이템 아이디")
.Annotation("MySql:CharSet", "utf8mb4")
.Annotation("Relational:ColumnOrder", 13)
.OldAnnotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("Relational:ColumnOrder", 14);
migrationBuilder.AlterColumn<DateTime>(
name: "created_at",
table: "planet_item_exchange_order",
type: "TIMESTAMP",
nullable: false,
defaultValueSql: "CURRENT_TIMESTAMP",
comment: "교환 주문 시작 시간",
oldClrType: typeof(DateTime),
oldType: "TIMESTAMP",
oldDefaultValueSql: "CURRENT_TIMESTAMP",
oldComment: "교환 주문 시작 시간")
.Annotation("Relational:ColumnOrder", 15)
.OldAnnotation("Relational:ColumnOrder", 16);
migrationBuilder.AlterColumn<DateTime>(
name: "completed_at",
table: "planet_item_exchange_order",
type: "TIMESTAMP",
nullable: true,
comment: "교환 주문 완료 시간",
oldClrType: typeof(DateTime),
oldType: "TIMESTAMP",
oldNullable: true,
oldComment: "교환 주문 완료 시간")
.Annotation("Relational:ColumnOrder", 16)
.OldAnnotation("Relational:ColumnOrder", 17);
migrationBuilder.AlterColumn<string>(
name: "caliverse_item_type",
table: "planet_item_exchange_order",
type: "varchar(50)",
maxLength: 50,
nullable: false,
comment: "칼리버스 아이템 타입",
oldClrType: typeof(string),
oldType: "varchar(50)",
oldMaxLength: 50,
oldComment: "칼리버스 아이템 타입")
.Annotation("MySql:CharSet", "utf8mb4")
.Annotation("Relational:ColumnOrder", 9)
.OldAnnotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("Relational:ColumnOrder", 10);
migrationBuilder.AlterColumn<int>(
name: "caliverse_item_quantity",
table: "planet_item_exchange_order",
type: "INT",
nullable: false,
comment: "칼리버스 아이템 갯수",
oldClrType: typeof(int),
oldType: "INT",
oldComment: "칼리버스 아이템 갯수")
.Annotation("Relational:ColumnOrder", 11)
.OldAnnotation("Relational:ColumnOrder", 12);
migrationBuilder.AlterColumn<string>(
name: "caliverse_item_id",
table: "planet_item_exchange_order",
type: "varchar(50)",
maxLength: 50,
nullable: false,
comment: "칼리버스 아이템 아이디",
oldClrType: typeof(string),
oldType: "varchar(50)",
oldMaxLength: 50,
oldComment: "칼리버스 아이템 아이디")
.Annotation("MySql:CharSet", "utf8mb4")
.Annotation("Relational:ColumnOrder", 10)
.OldAnnotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("Relational:ColumnOrder", 11);
}
}
}

View File

@@ -0,0 +1,401 @@
// <auto-generated />
using System;
using BrokerCore.Repository.Context;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace BrokerApiCore.Migrations
{
[DbContext(typeof(MetaverseBrokerDbContext))]
partial class MetaverseBrokerDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.2")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder);
modelBuilder.Entity("BrokerCore.DbEntity.PlanetInfo", b =>
{
b.Property<string>("PlanetId")
.HasColumnType("varchar(50)")
.HasColumnName("planet_id");
b.Property<string>("CompanyName")
.IsRequired()
.HasColumnType("varchar(32)")
.HasColumnName("company_name");
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp")
.HasColumnName("created_at")
.HasDefaultValueSql("CURRENT_TIMESTAMP")
.HasComment("생성 시간");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("varchar(255)")
.HasColumnName("description");
b.Property<string>("PlanetName")
.IsRequired()
.HasColumnType("varchar(32)")
.HasColumnName("planet_name");
b.Property<string>("SecretKey")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("secret_key");
b.Property<string>("ServerType")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("server_type");
b.Property<DateTime>("UpdatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp")
.HasColumnName("updated_at")
.HasDefaultValueSql("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
.HasComment("수정 시간");
b.HasKey("PlanetId");
b.HasIndex("CompanyName");
b.HasIndex("PlanetName");
b.HasIndex("SecretKey");
b.ToTable("planet_info", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.PlanetItemExchangeOrder", b =>
{
b.Property<string>("OrderId")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("order_id")
.HasColumnOrder(1)
.HasComment("교환 주문 아이디 (GUID)");
b.Property<string>("AccountId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("account_id")
.HasColumnOrder(7)
.HasComment("SSO 아이디");
b.Property<int>("CaliverseItemDeltaAmount")
.HasColumnType("INT")
.HasColumnName("caliverse_item_quantity")
.HasColumnOrder(12)
.HasComment("칼리버스 아이템 갯수");
b.Property<string>("CaliverseItemId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("caliverse_item_id")
.HasColumnOrder(11)
.HasComment("칼리버스 아이템 아이디");
b.Property<string>("CaliverseItemType")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("caliverse_item_type")
.HasColumnOrder(10)
.HasComment("칼리버스 아이템 타입");
b.Property<DateTime?>("CompletedAt")
.HasColumnType("TIMESTAMP")
.HasColumnName("completed_at")
.HasColumnOrder(17)
.HasComment("교환 주문 완료 시간");
b.Property<DateTime>("CreatedAt")
.ValueGeneratedOnAdd()
.HasColumnType("TIMESTAMP")
.HasColumnName("created_at")
.HasColumnOrder(16)
.HasDefaultValueSql("CURRENT_TIMESTAMP")
.HasComment("교환 주문 시작 시간");
b.Property<int>("ExchangeMetaAmount")
.HasColumnType("INT")
.HasColumnName("exchange_meta_amount")
.HasColumnOrder(6)
.HasComment("교환 메타 수량");
b.Property<string>("ExchangeMetaId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("exchange_meta_id")
.HasColumnOrder(5)
.HasComment("교환 메타 아이디");
b.Property<string>("Nickname")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("nickname")
.HasColumnOrder(9)
.HasComment("유저 닉네임");
b.Property<string>("OrderStatus")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("order_status")
.HasColumnOrder(2)
.HasComment("교환 주문 상태");
b.Property<string>("PlanetId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("planet_id")
.HasColumnOrder(3)
.HasComment("플래닛 아이디");
b.Property<int>("PlanetItemDeltaAmount")
.HasColumnType("INT")
.HasColumnName("planet_item_quantity")
.HasColumnOrder(15)
.HasComment("플래닛 아이템 갯수");
b.Property<string>("PlanetItemId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("planet_item_id")
.HasColumnOrder(14)
.HasComment("플래닛 아이템 아이디");
b.Property<string>("PlanetItemType")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("planet_item_type")
.HasColumnOrder(13)
.HasComment("플래닛 아이템 타입");
b.Property<string>("SeasonId")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("season_id")
.HasColumnOrder(4)
.HasComment("시즌 아이디");
b.Property<string>("UserGuid")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("user_guid")
.HasColumnOrder(8)
.HasComment("유저 아이디 (GUID)");
b.HasKey("OrderId");
b.HasIndex("AccountId");
b.HasIndex("CreatedAt");
b.HasIndex("OrderStatus");
b.HasIndex("PlanetId");
b.HasIndex("SeasonId");
b.HasIndex("UserGuid");
b.ToTable("planet_item_exchange_order", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.PlanetItemExchangeOrderAmountTotalLimit", b =>
{
b.Property<string>("ExchangeMetaId")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("exchange_meta_id")
.HasComment("교환 메타 아이디");
b.Property<DateOnly>("ExchangeDate")
.HasColumnType("date")
.HasColumnName("exchange_date")
.HasComment("교환 일자");
b.Property<string>("SeasonId")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("season_id")
.HasComment("시즌 아이디");
b.Property<DateTime>("CreatedAt")
.HasColumnType("TIMESTAMP")
.HasColumnName("created_at")
.HasComment("생성 일자");
b.Property<int>("DailyAmount")
.HasColumnType("INT")
.HasColumnName("daily_amount")
.HasComment("일일 교환 메타 수량 합계");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("TIMESTAMP")
.HasColumnName("updated_at")
.HasComment("업데이트 일자");
b.HasKey("ExchangeMetaId", "ExchangeDate", "SeasonId");
b.HasIndex("ExchangeDate");
b.HasIndex("ExchangeMetaId");
b.HasIndex("SeasonId");
b.ToTable("planet_exchange_order_amount_total_limits", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.PlanetItemExchangeOrderAmountUserLimit", b =>
{
b.Property<string>("ExchangeMetaId")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("exchange_meta_id")
.HasComment("교환 메타 아이디");
b.Property<DateOnly>("ExchangeDate")
.HasColumnType("date")
.HasColumnName("exchange_date")
.HasComment("교환 일자");
b.Property<string>("SeasonId")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("season_id")
.HasComment("시즌 아이디");
b.Property<string>("UserGuid")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("user_guid")
.HasComment("유저 아이디 (GUID)");
b.Property<DateTime>("CreatedAt")
.HasColumnType("TIMESTAMP")
.HasColumnName("created_at")
.HasComment("생성 일자");
b.Property<int>("DailyAmount")
.HasColumnType("INT")
.HasColumnName("daily_amount")
.HasComment("사용자별 일일 교환 메타 수량");
b.Property<DateTime>("UpdatedAt")
.HasColumnType("TIMESTAMP")
.HasColumnName("updated_at")
.HasComment("업데이트 일자");
b.HasKey("ExchangeMetaId", "ExchangeDate", "SeasonId", "UserGuid");
b.HasIndex("ExchangeDate");
b.HasIndex("ExchangeMetaId");
b.HasIndex("SeasonId");
b.HasIndex("UserGuid");
b.ToTable("planet_exchange_order_amount_user_limits", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.SapphireExchangeOrder", b =>
{
b.Property<string>("OrderId")
.HasColumnType("varchar(60)")
.HasColumnName("order_id")
.HasComment("사파이어 교환 주문 아이디 guid");
b.Property<ulong>("AccountId")
.HasColumnType("bigint unsigned")
.HasColumnName("account_id")
.HasComment("sso 계정 아이디");
b.Property<DateTime?>("CompletedAt")
.HasColumnType("timestamp")
.HasColumnName("completed_at")
.HasComment("사파이어 교환 주문 완료 시간");
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp")
.HasColumnName("created_at")
.HasComment("사파이어 교환 주문 시작 시간");
b.Property<sbyte>("OrderStatus")
.HasColumnType("tinyint")
.HasColumnName("order_status")
.HasComment("사파이어 교환 주문 상태");
b.Property<string>("PlanetId")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("planet_id")
.HasComment("플래닛 아이디");
b.Property<decimal>("PlanetMoneyIncDelta")
.HasColumnType("decimal(20, 0)")
.HasColumnName("planet_money_amount")
.HasComment("플래닛에서 발급한 재화 수량");
b.Property<decimal>("SapphireReducedDelta")
.HasColumnType("decimal(20, 0)")
.HasColumnName("sapphire_reduced_amount")
.HasComment("사파이어 차감 수량");
b.Property<string>("UserGuid")
.IsRequired()
.HasColumnType("varchar(50)")
.HasColumnName("user_guid")
.HasComment("유저 아이디");
b.HasKey("OrderId");
b.HasIndex("AccountId");
b.HasIndex("CreatedAt");
b.HasIndex("OrderStatus");
b.HasIndex("PlanetId");
b.HasIndex("UserGuid");
b.ToTable("sapphire_exchange_order", (string)null);
});
modelBuilder.Entity("BrokerCore.DbEntity.PlanetItemExchangeOrder", b =>
{
b.HasOne("BrokerCore.DbEntity.PlanetInfo", null)
.WithMany()
.HasForeignKey("PlanetId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired()
.HasConstraintName("FK_PlanetExchangeOrder_PlanetInfo");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,50 @@
namespace BrokerCore.Repository;
using Context;
using DbEntity;
using Microsoft.EntityFrameworkCore;
using ServerBase;
using ServerCommon;
public class PlanetInfoRepo
{
private readonly MetaverseBrokerDbContext m_db;
public PlanetInfoRepo(MetaverseBrokerDbContext db)
{
m_db = db;
}
public async Task<(Result, PlanetInfo?)> findOne(string? id)
{
var result = new Result();
try
{
var value = await m_db.PlanetInfos.FirstAsync(x => x.PlanetId == id);
return (result, value);
}
catch (Exception ex)
{
result.setFail(ServerErrorCode.RdbError, ex.Message);
}
return (result, null);
}
public async Task<(Result, IEnumerable<PlanetInfo>?)> findAll()
{
var result = new Result();
try
{
var value = await m_db.PlanetInfos.ToListAsync();
return (result, value);
}
catch (Exception ex)
{
result.setFail(ServerErrorCode.RdbError, ex.Message);
}
return (result, null);
}
}

View File

@@ -0,0 +1,210 @@
using Microsoft.EntityFrameworkCore;
using ServerBase;
using ServerCommon;
namespace BrokerCore.Repository;
using DbEntity;
using Context;
public class PlanetItemExchangeOrderAmountTotalLimitRepo
{
private readonly MetaverseBrokerDbContext m_db_context;
public PlanetItemExchangeOrderAmountTotalLimitRepo(MetaverseBrokerDbContext dbContext)
{
m_db_context = dbContext;
}
// 총 교환 제한 추가
public async Task<Result> add(PlanetItemExchangeOrderAmountTotalLimit limit,
CancellationToken cancellationToken = default)
{
var result = new Result();
try
{
m_db_context.PlanetItemExchangeOrderAmountTotalLimits.Add(limit);
await m_db_context.SaveChangesAsync(cancellationToken);
}
catch (Exception e)
{
result.setFail(ServerErrorCode.RdbError, e.Message);
}
return result;
}
// 총 교환 제한 업데이트
public async Task<Result> update(PlanetItemExchangeOrderAmountTotalLimit limit,
CancellationToken cancellationToken = default)
{
var result = new Result();
try
{
m_db_context.PlanetItemExchangeOrderAmountTotalLimits.Update(limit);
await m_db_context.SaveChangesAsync(cancellationToken);
}
catch (Exception e)
{
result.setFail(ServerErrorCode.RdbError, e.Message);
}
return result;
}
public async Task<Result> increaseDailyAmount(
PlanetItemExchangeOrderAmountTotalLimit limit,
int increaseAmount,
CancellationToken cancellationToken = default)
{
var result = new Result();
try
{
limit.DailyAmount += increaseAmount;
// DailyAmount만 업데이트하기 위해 특정 열만 업데이트
var entity = m_db_context.Entry(limit);
entity.Property(x => x.DailyAmount).IsModified = true;
await m_db_context.SaveChangesAsync(cancellationToken);
}
catch (Exception e)
{
result.setFail(ServerErrorCode.RdbError, e.Message);
}
return result;
}
// 총 교환 제한 삭제
public async Task<Result> delete(PlanetItemExchangeOrderAmountTotalLimit limit,
CancellationToken cancellationToken = default)
{
var result = new Result();
try
{
m_db_context.PlanetItemExchangeOrderAmountTotalLimits.Remove(limit);
await m_db_context.SaveChangesAsync(cancellationToken);
}
catch (Exception e)
{
result.setFail(ServerErrorCode.RdbError, e.Message);
}
return result;
}
// 특정 교환 메타 아이디와 날짜에 대한 교환 제한 조회
public async Task<(Result, PlanetItemExchangeOrderAmountTotalLimit?)> findByExchangeMetaAndDateOrCreate(
string exchangeMetaId,
DateOnly exchangeDate,
string seasonId,
CancellationToken cancellationToken = default)
{
var result = new Result();
try
{
var limit = await m_db_context.PlanetItemExchangeOrderAmountTotalLimits
.Where(x =>
x.ExchangeMetaId == exchangeMetaId &&
x.ExchangeDate == exchangeDate &&
x.SeasonId == seasonId)
.FirstOrDefaultAsync(cancellationToken);
if (limit == null)
{
limit = new PlanetItemExchangeOrderAmountTotalLimit
{
ExchangeMetaId = exchangeMetaId,
ExchangeDate = exchangeDate,
SeasonId = seasonId,
DailyAmount = 0
};
await add(limit, cancellationToken);
}
return (result, limit);
}
catch (Exception e)
{
result.setFail(ServerErrorCode.RdbError, e.Message);
return (result, null);
}
}
public async Task<(Result, PlanetItemExchangeOrderAmountTotalLimit?)> findByExchangeMetaAndDate(
string exchangeMetaId,
DateOnly exchangeDate,
string seasonId,
CancellationToken cancellationToken = default)
{
var result = new Result();
try
{
var limit = await m_db_context.PlanetItemExchangeOrderAmountTotalLimits
.Where(x =>
x.ExchangeMetaId == exchangeMetaId &&
x.ExchangeDate == exchangeDate &&
x.SeasonId == seasonId)
.FirstOrDefaultAsync(cancellationToken);
return (result, limit);
}
catch (Exception e)
{
result.setFail(ServerErrorCode.RdbError, e.Message);
return (result, null);
}
}
// // 특정 교환 메타 아이디에 대한 모든 교환 제한 조회
// public async Task<(Result, IEnumerable<PlanetItemExchangeOrderAmountTotalLimit>?)> findByExchangeMeta(
// string exchangeMetaId,
// int pageIndex = 1,
// int pageSize = 20,
// CancellationToken cancellationToken = default)
// {
// var result = new Result();
// try
// {
// var limits = await m_db_context.PlanetItemExchangeOrderAmountTotalLimits
// .Where(x => x.ExchangeMetaId == exchangeMetaId)
// .OrderBy(x => x.ExchangeDate)
// .Skip((pageIndex - 1) * pageSize)
// .Take(pageSize)
// .ToArrayAsync(cancellationToken);
//
// return (result, limits);
// }
// catch (Exception e)
// {
// result.setFail(ServerErrorCode.RdbError, e.Message);
// return (result, null);
// }
// }
//
// // 특정 날짜에 대한 모든 교환 제한 조회
// public async Task<(Result, IEnumerable<PlanetItemExchangeOrderAmountTotalLimit>?)> findByDate(
// DateOnly exchangeDate,
// int pageIndex = 1,
// int pageSize = 20,
// CancellationToken cancellationToken = default)
// {
// var result = new Result();
// try
// {
// var limits = await m_db_context.PlanetItemExchangeOrderAmountTotalLimits
// .Where(x => x.ExchangeDate == exchangeDate)
// .OrderBy(x => x.ExchangeMetaId)
// .Skip((pageIndex - 1) * pageSize)
// .Take(pageSize)
// .ToArrayAsync(cancellationToken);
//
// return (result, limits);
// }
// catch (Exception e)
// {
// result.setFail(ServerErrorCode.RdbError, e.Message);
// return (result, null);
// }
// }
}

View File

@@ -0,0 +1,227 @@
using Microsoft.EntityFrameworkCore;
using ServerBase;
using ServerCommon;
namespace BrokerCore.Repository;
using DbEntity;
using Context;
public class PlanetItemExchangeOrderAmountUserLimitRepo
{
private readonly MetaverseBrokerDbContext m_db_context;
public PlanetItemExchangeOrderAmountUserLimitRepo(MetaverseBrokerDbContext dbContext)
{
m_db_context = dbContext;
}
// 사용자별 교환 제한 추가
public async Task<Result> add(PlanetItemExchangeOrderAmountUserLimit limit,
CancellationToken cancellationToken = default)
{
var result = new Result();
try
{
m_db_context.PlanetItemExchangeOrderAmountUserLimits.Add(limit);
await m_db_context.SaveChangesAsync(cancellationToken);
}
catch (Exception e)
{
result.setFail(ServerErrorCode.InternalServerError, e.Message);
}
return result;
}
// 사용자별 교환 제한 업데이트
public async Task<Result> update(PlanetItemExchangeOrderAmountUserLimit limit,
CancellationToken cancellationToken = default)
{
var result = new Result();
try
{
m_db_context.PlanetItemExchangeOrderAmountUserLimits.Update(limit);
await m_db_context.SaveChangesAsync(cancellationToken);
}
catch (Exception e)
{
result.setFail(ServerErrorCode.InternalServerError, e.Message);
}
return result;
}
// 사용자별 교환 제한 삭제
public async Task<Result> delete(PlanetItemExchangeOrderAmountUserLimit limit,
CancellationToken cancellationToken = default)
{
var result = new Result();
try
{
m_db_context.PlanetItemExchangeOrderAmountUserLimits.Remove(limit);
await m_db_context.SaveChangesAsync(cancellationToken);
}
catch (Exception e)
{
result.setFail(ServerErrorCode.InternalServerError, e.Message);
}
return result;
}
// 특정 사용자와 날짜에 대한 교환 제한 조회
public async Task<(Result, PlanetItemExchangeOrderAmountUserLimit?)> findByUserAndDate(
string exchangeMetaId,
string userGuid,
DateOnly exchangeDate,
string seasonId,
CancellationToken cancellationToken = default)
{
var result = new Result();
try
{
var limit = await m_db_context.PlanetItemExchangeOrderAmountUserLimits
.Where(x =>
x.ExchangeMetaId == exchangeMetaId &&
x.ExchangeDate == exchangeDate &&
x.SeasonId == seasonId &&
x.UserGuid == userGuid)
.FirstOrDefaultAsync(cancellationToken);
return (result, limit);
}
catch (Exception e)
{
result.setFail(ServerErrorCode.RdbError, e.Message);
return (result, null);
}
}
// // 특정 교환 메타 아이디에 대한 모든 교환 제한 조회
// public async Task<(Result, IEnumerable<PlanetItemExchangeOrderAmountUserLimit>?)> findByExchangeMeta(
// string exchangeMetaId,
// int pageIndex = 1,
// int pageSize = 20,
// CancellationToken cancellationToken = default)
// {
// var result = new Result();
// try
// {
// var limits = await m_db_context.PlanetItemExchangeOrderAmountUserLimits
// .Where(x => x.ExchangeMetaId == exchangeMetaId)
// .OrderBy(x => x.ExchangeDate)
// .Skip((pageIndex - 1) * pageSize)
// .Take(pageSize)
// .ToArrayAsync(cancellationToken);
//
// return (result, limits);
// }
// catch (Exception e)
// {
// result.setFail(ServerErrorCode.RdbError, e.Message);
// return (result, null);
// }
// }
//
// // 특정 날짜에 대한 모든 교환 제한 조회
// public async Task<(Result, IEnumerable<PlanetItemExchangeOrderAmountUserLimit>?)> findByDate(
// DateOnly exchangeDate,
// int pageIndex = 1,
// int pageSize = 20,
// CancellationToken cancellationToken = default)
// {
// var result = new Result();
// try
// {
// var limits = await m_db_context.PlanetItemExchangeOrderAmountUserLimits
// .Where(x => x.ExchangeDate == exchangeDate)
// .OrderBy(x => x.ExchangeMetaId)
// .Skip((pageIndex - 1) * pageSize)
// .Take(pageSize)
// .ToArrayAsync(cancellationToken);
//
// return (result, limits);
// }
// catch (Exception e)
// {
// result.setFail(ServerErrorCode.RdbError, e.Message);
// return (result, null);
// }
// }
//
// // 특정 사용자의 모든 교환 제한 조회
// public async Task<(Result, IEnumerable<PlanetItemExchangeOrderAmountUserLimit>?)> findByUser(
// string userGuid,
// int pageIndex = 1,
// int pageSize = 20,
// CancellationToken cancellationToken = default)
// {
// var result = new Result();
// try
// {
// var limits = await m_db_context.PlanetItemExchangeOrderAmountUserLimits
// .Where(x => x.UserGuid == userGuid)
// .OrderBy(x => x.ExchangeDate)
// .ThenBy(x => x.ExchangeMetaId)
// .Skip((pageIndex - 1) * pageSize)
// .Take(pageSize)
// .ToArrayAsync(cancellationToken);
//
// return (result, limits);
// }
// catch (Exception e)
// {
// result.setFail(ServerErrorCode.RdbError, e.Message);
// return (result, null);
// }
// }
public async Task increaseDailyAmount(PlanetItemExchangeOrderAmountUserLimit userLimit, int increaseAmount,
CancellationToken cancellationToken)
{
userLimit.DailyAmount += increaseAmount;
var entry = m_db_context.Entry(userLimit);
entry.Property(x => x.DailyAmount).IsModified = true;
await update(userLimit, cancellationToken);
}
public async Task<(Result, PlanetItemExchangeOrderAmountUserLimit?)> findByExchangeMetaAndDateOrCreate(
string orderExchangeMetaId, string orderUserGuid, DateOnly exchangeDate, string orderSeasonId,
CancellationToken cancellationToken)
{
var result = new Result();
try
{
var limit = await m_db_context.PlanetItemExchangeOrderAmountUserLimits
.Where(x =>
x.ExchangeMetaId == orderExchangeMetaId &&
x.ExchangeDate == exchangeDate &&
x.SeasonId == orderSeasonId &&
x.UserGuid == orderUserGuid)
.FirstOrDefaultAsync(cancellationToken);
if (limit is null)
{
limit = new PlanetItemExchangeOrderAmountUserLimit
{
ExchangeMetaId = orderExchangeMetaId,
UserGuid = orderUserGuid,
ExchangeDate = exchangeDate,
SeasonId = orderSeasonId,
DailyAmount = 0,
};
await add(limit, cancellationToken);
}
return (result, limit);
}
catch (Exception e)
{
result.setFail(ServerErrorCode.RdbError, e.Message);
return (result, null);
}
}
}

View File

@@ -0,0 +1,296 @@
using Microsoft.EntityFrameworkCore;
using ServerBase;
using ServerCommon;
namespace BrokerCore.Repository;
using Common;
using DbEntity;
using Context;
public class PlanetItemExchangeOrderRepo
{
private readonly MetaverseBrokerDbContext m_db_context;
public PlanetItemExchangeOrderRepo(MetaverseBrokerDbContext dbContext)
{
m_db_context = dbContext;
}
//================================================================================
// 교환 주문을 추가한다.
// 트랜잭션을 사용한다.
//================================================================================
public async Task<Result> add(PlanetItemExchangeOrder order, CancellationToken cancellationToken = default)
{
try
{
m_db_context.PlanetItemExchangeOrders.Add(order);
await m_db_context.SaveChangesAsync(cancellationToken);
}
catch (Exception e)
{
return new Result { ErrorCode = ServerErrorCode.RdbError, ResultString = e.Message };
}
return new Result();
}
// public async Task<Result> add(PlanetItemExchangeOrder order,
// CancellationToken cancellationToken = default)
// {
// var result = new Result();
//
// // 실행 전략 생성
// var strategy = m_db_context.Database.CreateExecutionStrategy();
//
// // 실행 전략을 사용하여 트랜잭션 작업을 실행
// await strategy.ExecuteAsync(async () =>
// {
// // 트랜잭션 시작
// await using var transaction = await m_db_context.Database.BeginTransactionAsync(cancellationToken);
// try
// {
// var order_date_utc = order.CreatedAt.ToUniversalTime().Date; // UTC 기준 주문일의 자정(00:00:00)
//
// // 단일 쿼리로 total_exchange_count와 user_exchange_count를 함께 조회
// var exchange_counts = await m_db_context.PlanetItemExchangeOrders
// .Where(x => x.PlanetId == order.PlanetId &&
// x.ExchangeMetaId == order.ExchangeMetaId &&
// x.CreatedAt >= order_date_utc && x.CreatedAt < order_date_utc.AddDays(1))
// .GroupBy(x => 1)
// .Select(g => new
// {
// TotalCount = g.Sum(x => x.ExchangeMetaAmount),
// UserCount = g.Where(x => x.UserGuid == order.UserGuid).Sum(x => x.ExchangeMetaAmount)
// })
// .FirstOrDefaultAsync(cancellationToken);
//
// var total_exchange_count = exchange_counts?.TotalCount ?? 0;
// var user_exchange_count = exchange_counts?.UserCount ?? 0;
//
// if (total_exchange_count + order.ExchangeMetaAmount > dailyLimit)
// {
// result.setFail(ServerErrorCode.ExchangeTotalOrderDailyLimitExceeded,
// $"일일 총 구매 제한 초과 => {order.ExchangeMetaId} Total exchange count {total_exchange_count} + order amount {order.ExchangeMetaAmount} > daily total limit {dailyLimit}");
// return;
// }
//
// if (user_exchange_count + order.ExchangeMetaAmount > dailyUserLimit)
// {
// result.setFail(ServerErrorCode.ExchangeUserOrderDailyLimitExceeded,
// $"일일 개인 구매 제한 초과 => {order.ExchangeMetaId} User exchange count {user_exchange_count} + order amount {order.ExchangeMetaAmount} > daily user limit {dailyUserLimit}");
// return;
// }
//
// m_db_context.PlanetItemExchangeOrders.Add(order);
// m_
//
// await m_db_context.SaveChangesAsync(cancellationToken);
// await transaction.CommitAsync(cancellationToken);
// }
// catch (Exception e)
// {
// result.setFail(ServerErrorCode.InternalServerError, e.Message);
// }
// });
//
// return result;
// }
public async Task<Result> delete(PlanetItemExchangeOrder order, CancellationToken cancellationToken = default)
{
var result = new Result();
try
{
m_db_context.PlanetItemExchangeOrders.Remove(order);
await m_db_context.SaveChangesAsync(cancellationToken);
}
catch (Exception e)
{
result.setFail(ServerErrorCode.InternalServerError, e.Message);
}
return result;
}
//================================================================================
// 교환 주문을 비동기로 업데이트한다.
// OrderId를 키로 사용한다.
// OrderType과 OrderCompletedAt만 업데이트한다.
//================================================================================
public async Task<(Result, PlanetItemExchangeOrder?)> findAndUpdateStatus(string orderId,
ExchangeOrderStatus orderStatus,
CancellationToken cancellationToken = default)
{
var result = new Result();
try
{
var order = await m_db_context.PlanetItemExchangeOrders.Where(x => x.OrderId == orderId)
.FirstOrDefaultAsync(cancellationToken);
if (order == null)
{
result.setFail(ServerErrorCode.ExchangeOrderIdNotFound, $"Order not found: {orderId}");
return (result, null);
}
order.OrderStatus = orderStatus;
order.CompletedAt = DateTime.UtcNow;
m_db_context.PlanetItemExchangeOrders.Attach(order);
m_db_context.Entry(order).Property(x => x.OrderStatus).IsModified = true;
m_db_context.Entry(order).Property(x => x.CompletedAt).IsModified = true;
await m_db_context.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
return (new Result(), order);
}
catch (Exception e)
{
// await transaction.RollbackAsync(cancellationToken).ConfigureAwait(false);
return (new Result { ResultString = e.Message }, null);
}
}
public async Task<(Result, PlanetItemExchangeOrder?)> findOne(string orderId,
ExchangeOrderStatus orderStatus,
CancellationToken cancellationToken = default)
{
try
{
var order = await m_db_context.PlanetItemExchangeOrders
.Where(x => x.OrderId == orderId && x.OrderStatus == orderStatus)
.FirstOrDefaultAsync(cancellationToken);
return (new Result(), order);
}
catch (Exception e)
{
return (new Result { ErrorCode = ServerErrorCode.RdbError, ResultString = e.Message }, null);
}
}
// public async Task<Result> updateForPending(SapphireExchangeOrder order,
// CancellationToken cancellationToken = default)
// {
// // await using var transaction = await m_db_context.Database.BeginTransactionAsync(cancellationToken);
// try
// {
// m_db_context.SapphireExchangeOrders.Attach(order);
// m_db_context.Entry(order).Property(x => x.OrderStatus).IsModified = true;
// await m_db_context.SaveChangesAsync(cancellationToken);
// // await transaction.CommitAsync(cancellationToken);
// return new Result();
// }
// catch (Exception e)
// {
// // await transaction.RollbackAsync(cancellationToken);
// return new Result { ResultString = e.Message };
// }
// }
//==========================================================================
//SELECT *
// FROM `sapphire_exchange_order`
// WHERE `PlanetId` = @planetId
// AND `UserGuid` = @userGuid
// AND (@orderStatus IS NULL OR `OrderStatus` = @orderStatus)
// ORDER BY `CreatedAt` ASC
// LIMIT @pageSize OFFSET @offset;
//==========================================================================
public async Task<(Result, IEnumerable<PlanetItemExchangeOrder>?, int)> findList(
string planetId,
string metaId,
string seasonId,
string userGuid,
ExchangeOrderStatus? orderStatus = null,
int pageIndex = 1,
int pageSize = 20,
string sortOrder = "asc",
CancellationToken cancellationToken = default)
{
var result = new Result();
try
{
var query = m_db_context.PlanetItemExchangeOrders.AsQueryable();
if (!string.IsNullOrEmpty(planetId))
{
query = query.Where(x => x.PlanetId == planetId);
}
if (!string.IsNullOrEmpty(metaId))
{
query = query.Where(x => x.ExchangeMetaId == metaId);
}
if (!string.IsNullOrEmpty(seasonId))
{
query = query.Where(x => x.SeasonId == seasonId);
}
if (!string.IsNullOrEmpty(userGuid))
{
query = query.Where(x => x.UserGuid == userGuid);
}
if (orderStatus.HasValue)
{
query = query.Where(x => x.OrderStatus == orderStatus);
}
query = sortOrder.ToLower() == "desc"
? query.OrderByDescending(o => o.CreatedAt)
: query.OrderBy(o => o.CreatedAt);
var orders = await query
.Skip((pageIndex - 1) * pageSize)
.Take(pageSize)
.ToArrayAsync(cancellationToken);
var total_count = await query.CountAsync(cancellationToken);
return (result, orders, total_count);
}
catch (Exception e)
{
result.setFail(ServerErrorCode.RdbError, e.Message);
return (result, null, 0);
}
}
//================================================================================
// 사파이어 교환 주문 목록을 비동기로 조회한다.
// OrderType과 PlanetId로 검색한다.
// Result, IEnumerable<>를 반환한다.
// 조건에 맞는 값이 없다면 빈 배열을 반환한다.
//================================================================================
public async Task<PaginatedList<PlanetItemExchangeOrder>> findPlanetItemExchangeOrders(int pageIndex, int pageSize)
{
var query = m_db_context.Set<PlanetItemExchangeOrder>().AsNoTracking();
var count = await query.CountAsync();
var items = await query
.OrderBy(o => o.CreatedAt)
.Skip((pageIndex - 1) * pageSize)
.Take(pageSize)
.ToListAsync();
return new PaginatedList<PlanetItemExchangeOrder>(items, count, pageIndex, pageSize);
}
public class PaginatedList<T> : List<T>
{
public int PageIndex { get; private set; }
public int TotalPages { get; private set; }
public int TotalCount { get; private set; }
public PaginatedList(List<T> items, int count, int pageIndex, int pageSize)
{
PageIndex = pageIndex;
TotalCount = count;
this.AddRange(items);
}
public bool HasPreviousPage => PageIndex > 1;
public bool HasNextPage => PageIndex < TotalPages;
}
}

View File

@@ -0,0 +1,240 @@
// using Microsoft.EntityFrameworkCore;
//
// using ServerCommon;
//
// namespace BrokerCore.Repository;
//
// using Common;
//
// using DbEntity;
// using Context;
//
// public class SapphireExchangeOrderRepo
// {
// private readonly MetaverseBrokerDbContext m_db_context;
//
// public SapphireExchangeOrderRepo(MetaverseBrokerDbContext dbContext)
// {
// m_db_context = dbContext;
// }
//
// //================================================================================
// // 사파이어 교환 주문을 추가한다.
// // 트랜잭션을 사용한다.
// //================================================================================
// public async Task<Result> add(SapphireExchangeOrder order, CancellationToken cancellationToken = default)
// {
// var result = new Result();
// try
// {
// m_db_context.SapphireExchangeOrders.Add(order);
// await m_db_context.SaveChangesAsync(cancellationToken);
// return result;
// }
// catch (Exception e)
// {
// result.setFail(ServerErrorCode.InternalServerError, e.Message);
// }
//
// return result;
// }
//
// public async Task<Result> delete(SapphireExchangeOrder order, CancellationToken cancellationToken = default)
// {
// var result = new Result();
// try
// {
// m_db_context.SapphireExchangeOrders.Remove(order);
// await m_db_context.SaveChangesAsync(cancellationToken);
// }
// catch (Exception e)
// {
// result.setFail(ServerErrorCode.InternalServerError, e.Message);
// }
//
// return result;
// }
//
// //================================================================================
// // 사파이어 교환 주문을 비동기로 업데이트한다.
// // 트랜잭션을 사용한다.
// // OrderId를 키로 사용한다.
// // OrderType과 OrderCompletedAt만 업데이트한다.
// //================================================================================
// public async Task<(Result, SapphireExchangeOrder?)> findAndComplete(string orderId,
// CancellationToken cancellationToken = default)
// {
// var result = new Result();
// // var transaction = await m_db_context.Database.BeginTransactionAsync(cancellationToken).ConfigureAwait(false);
// // await using var transaction1 = transaction.ConfigureAwait(false);
// try
// {
// var order = await m_db_context.SapphireExchangeOrders.Where(x => x.OrderId == orderId).FirstOrDefaultAsync(cancellationToken);
// Guard.Against.isNull(order, ServerErrorCode.ExchangeOrderIdNotFound, "Invalid orderId");
// if (order.OrderStatus != ExchangeOrderStatus.Pending)
// {
// result.setFail(ServerErrorCode.Success, $"Fail To Complete OrderStatus Not Pending: orderId {orderId}, order_status {order.OrderStatus}");
// return (result, order);
// }
//
// order.OrderStatus = ExchangeOrderStatus.Completed;
// order.CompletedAt = DateTime.Now;
// m_db_context.SapphireExchangeOrders.Attach(order);
// m_db_context.Entry(order).Property(x => x.OrderStatus).IsModified = true;
// m_db_context.Entry(order).Property(x => x.CompletedAt).IsModified = true;
// await m_db_context.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
// // await transaction.CommitAsync(cancellationToken).ConfigureAwait(false);
// return (new Result(), order);
// }
// catch (Exception e)
// {
// // await transaction.RollbackAsync(cancellationToken).ConfigureAwait(false);
// return (new Result { ResultString = e.Message }, null);
// }
// }
//
// // public async Task<Result> updateForPending(SapphireExchangeOrder order,
// // CancellationToken cancellationToken = default)
// // {
// // // await using var transaction = await m_db_context.Database.BeginTransactionAsync(cancellationToken);
// // try
// // {
// // m_db_context.SapphireExchangeOrders.Attach(order);
// // m_db_context.Entry(order).Property(x => x.OrderStatus).IsModified = true;
// // await m_db_context.SaveChangesAsync(cancellationToken);
// // // await transaction.CommitAsync(cancellationToken);
// // return new Result();
// // }
// // catch (Exception e)
// // {
// // // await transaction.RollbackAsync(cancellationToken);
// // return new Result { ResultString = e.Message };
// // }
// // }
// //==========================================================================
// //SELECT *
// // FROM `sapphire_exchange_order`
// // WHERE `PlanetId` = @planetId
// // AND `UserGuid` = @userGuid
// // AND (@orderStatus IS NULL OR `OrderStatus` = @orderStatus)
// // ORDER BY `CreatedAt` ASC
// // LIMIT @pageSize OFFSET @offset;
// //==========================================================================
// public async Task<(Result, IEnumerable<SapphireExchangeOrder>?)> findList(
// string planetId,
// string userGuid,
// ExchangeOrderStatus? orderStatus = null,
// int pageIndex = 1,
// int pageSize = 20,
// string sortOrder = "asc",
// CancellationToken cancellationToken = default)
// {
// var result = new Result();
// try
// {
// var query = m_db_context.SapphireExchangeOrders.AsQueryable();
//
// if (!string.IsNullOrEmpty(planetId))
// {
// query = query.Where(x => x.PlanetId == planetId);
// }
//
// if (!string.IsNullOrEmpty(userGuid))
// {
// query = query.Where(x => x.UserGuid == userGuid);
// }
//
// //orderStatus.HasValue는 orderStatus가 null일 때도 에러가 발생하지 않음. orderStatus가 null이면 HasValue는 false를 반환.
// if (orderStatus.HasValue)
// {
// query = query.Where(x => x.OrderStatus == orderStatus);
// }
//
// query = sortOrder.ToLower() == "desc"
// ? query.OrderByDescending(o => o.CreatedAt)
// : query.OrderBy(o => o.CreatedAt);
//
// var orders = await query
// .Skip((pageIndex - 1) * pageSize)
// .Take(pageSize)
// .ToArrayAsync(cancellationToken);
//
// return (result, orders);
// }
// catch (Exception e)
// {
// result.setFail(ServerErrorCode.DynamoDbException, e.Message);
// return (result, null);
// }
// }
//
// //================================================================================
// // 사파이어 교환 주문 목록을 비동기로 조회한다.
// // OrderType과 PlanetId로 검색한다.
// // Result, IEnumerable<>를 반환한다.
// // 조건에 맞는 값이 없다면 빈 배열을 반환한다.
// //================================================================================
// public async Task<(Result, IEnumerable<SapphireExchangeOrder>?)> findList_old(string planetId, string userGuid,
// ExchangeOrderStatus? orderStatus = null, int pageIndex = 1, int pageSize = 20, CancellationToken cancellationToken = default)
// {
// var result = new Result();
// try
// {
// if (orderStatus == null)
// {
// var orders = await m_db_context.SapphireExchangeOrders
// .OrderBy(o => o.CreatedAt)
// .Skip((pageIndex - 1) * pageSize)
// .Take(pageSize)
// .Where(x => x.PlanetId == planetId && x.UserGuid == userGuid).ToArrayAsync(cancellationToken);
// return (result, orders);
// }
// else
// {
// var orders = await m_db_context.SapphireExchangeOrders
// .Where(x => x.PlanetId == planetId && x.UserGuid == userGuid && x.OrderStatus == orderStatus)
// .Skip((pageIndex - 1) * pageSize)
// .Take(pageSize)
// .ToArrayAsync(cancellationToken);
// return (result, orders);
// }
// }
// catch (Exception e)
// {
// result.setFail(ServerErrorCode.RdbError, e.Message);
// return (result, null);
// }
// }
//
// public async Task<PaginatedList<SapphireExchangeOrder>> getSapphireExchangeOrders(int pageIndex, int pageSize)
// {
// var query = m_db_context.Set<SapphireExchangeOrder>().AsNoTracking();
//
// var count = await query.CountAsync();
// var items = await query
// .OrderBy(o => o.CreatedAt)
// .Skip((pageIndex - 1) * pageSize)
// .Take(pageSize)
// .ToListAsync();
//
// return new PaginatedList<SapphireExchangeOrder>(items, count, pageIndex, pageSize);
// }
//
// public class PaginatedList<T> : List<T>
// {
// public int PageIndex { get; private set; }
// public int TotalPages { get; private set; }
// public int TotalCount { get; private set; }
//
// public PaginatedList(List<T> items, int count, int pageIndex, int pageSize)
// {
// PageIndex = pageIndex;
// TotalCount = count;
//
// this.AddRange(items);
// }
//
// public bool HasPreviousPage => PageIndex > 1;
// public bool HasNextPage => PageIndex < TotalPages;
// }
// }

View File

@@ -0,0 +1,163 @@
namespace BrokerCore.DbEntity;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
public class PlanetExchangeOrderConfig : IEntityTypeConfiguration<PlanetItemExchangeOrder>
{
public void Configure(EntityTypeBuilder<PlanetItemExchangeOrder> builder)
{
builder.ToTable("planet_item_exchange_order");
builder.HasIndex(o => o.CreatedAt);
builder.HasIndex(o => o.OrderStatus);
builder.HasIndex(o => o.PlanetId);
builder.HasIndex(o => o.SeasonId);
builder.HasIndex(o => o.AccountId);
builder.HasIndex(o => o.UserGuid);
// 기본 키 (Primary Key)
builder.HasKey(o => o.OrderId);
builder.Property(o => o.OrderId)
.HasColumnOrder(1)
.HasColumnName("order_id")
.HasMaxLength(50)
.IsRequired()
.HasComment("교환 주문 아이디 (GUID)");
// 주문 상태 (Enum)
builder.Property(o => o.OrderStatus)
.HasColumnOrder(2)
.HasColumnName("order_status")
.IsRequired()
.HasConversion<string>()
.HasMaxLength(50)
.HasComment("교환 주문 상태");
// 플래닛 ID (string)
builder.Property(o => o.PlanetId)
.HasColumnOrder(3)
.HasColumnName("planet_id")
.HasMaxLength(50)
.IsRequired()
.HasComment("플래닛 아이디");
// PlanetInfo와의 외래 키 관계 설정
builder.HasOne<PlanetInfo>()
.WithMany()
.HasForeignKey(o => o.PlanetId)
.OnDelete(DeleteBehavior.Restrict) // 삭제 동작 정책을 Restrict로 설정
.HasConstraintName("FK_PlanetExchangeOrder_PlanetInfo");
builder.Property(o => o.SeasonId)
.HasColumnOrder(4)
.HasColumnName("season_id")
.HasMaxLength(50)
.IsRequired()
.HasComment("시즌 아이디");
builder.Property(o => o.ExchangeMetaId)
.HasColumnOrder(5)
.HasColumnName("exchange_meta_id")
.HasMaxLength(50)
.IsRequired()
.HasComment("교환 메타 아이디");
builder.Property(o => o.ExchangeMetaAmount)
.HasColumnOrder(6)
.HasColumnName("exchange_meta_amount")
.HasColumnType("INT")
.IsRequired()
.HasComment("교환 메타 수량");
// 계정 ID (ulong)
builder.Property(o => o.AccountId)
.HasColumnOrder(7)
.HasColumnName("account_id")
.HasMaxLength(50)
.IsRequired()
.HasComment("SSO 아이디");
// 사용자 GUID (string)
builder.Property(o => o.UserGuid)
.HasColumnOrder(8)
.HasColumnName("user_guid")
.HasMaxLength(50)
.IsRequired()
.HasComment("유저 아이디 (GUID)");
// 사용자 닉네임 (string)
builder.Property(o => o.Nickname)
.HasColumnOrder(9)
.HasColumnName("nickname")
.HasMaxLength(50)
.IsRequired()
.HasComment("유저 닉네임");
// 칼리버스 아이템 타입 (Enum)
builder.Property(o => o.CaliverseItemType)
.HasColumnOrder(10)
.HasColumnName("caliverse_item_type")
.IsRequired()
.HasConversion<string>()
.HasMaxLength(50)
.HasComment("칼리버스 아이템 타입");
// 칼리버스 아이템 ID (string)
builder.Property(o => o.CaliverseItemId)
.HasColumnOrder(11)
.HasColumnName("caliverse_item_id")
.HasMaxLength(50)
.IsRequired()
.HasComment("칼리버스 아이템 아이디");
// 칼리버스 아이템 수량 (long)
builder.Property(o => o.CaliverseItemDeltaAmount)
.HasColumnOrder(12)
.HasColumnName("caliverse_item_quantity")
.HasColumnType("INT")
.IsRequired()
.HasComment("칼리버스 아이템 갯수");
// 플래닛 아이템 타입 (Enum)
builder.Property(o => o.PlanetItemType)
.HasColumnOrder(13)
.HasColumnName("planet_item_type")
.IsRequired()
.HasConversion<string>()
.HasMaxLength(50)
.HasComment("플래닛 아이템 타입");
// 플래닛 아이템 ID (string)
builder.Property(o => o.PlanetItemId)
.HasColumnOrder(14)
.HasColumnName("planet_item_id")
.HasMaxLength(50)
.IsRequired()
.HasComment("플래닛 아이템 아이디");
// 플래닛 아이템 수량 (long)
builder.Property(o => o.PlanetItemDeltaAmount)
.HasColumnOrder(15)
.HasColumnName("planet_item_quantity")
.HasColumnType("INT")
.IsRequired()
.HasComment("플래닛 아이템 갯수");
// 생성 시간 (TIMESTAMP)
builder.Property(o => o.CreatedAt)
.HasColumnOrder(16)
.HasColumnName("created_at")
.HasColumnType("TIMESTAMP")
.IsRequired()
.HasDefaultValueSql("CURRENT_TIMESTAMP")
.HasComment("교환 주문 시작 시간");
// 완료 시간 (TIMESTAMP?) - Nullable
builder.Property(o => o.CompletedAt)
.HasColumnOrder(17)
.HasColumnName("completed_at")
.HasColumnType("TIMESTAMP")
.IsRequired(false)
.HasComment("교환 주문 완료 시간");
}
}

View File

@@ -0,0 +1,56 @@
namespace BrokerCore.Repository.SqlConfig;
using DbEntity;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
public class PlanetInfoConfig : IEntityTypeConfiguration<PlanetInfo>
{
public void Configure(EntityTypeBuilder<PlanetInfo> builder)
{
builder.ToTable("planet_info");
builder.HasKey(x => x.PlanetId);
builder.HasIndex(x => x.PlanetName);
builder.HasIndex(x => x.CompanyName);
builder.HasIndex(x => x.SecretKey);
builder.Property(x => x.PlanetId)
.IsRequired()
.HasColumnName("planet_id")
.HasColumnType("varchar(50)");
builder.Property(x => x.PlanetName)
.IsRequired()
.HasColumnName("planet_name")
.HasColumnType("varchar(32)");
builder.Property(x => x.CompanyName)
.IsRequired()
.HasColumnName("company_name")
.HasColumnType("varchar(32)");
builder.Property(x => x.SecretKey)
.IsRequired()
.HasColumnName("secret_key")
.HasColumnType("varchar(50)");
builder.Property(x => x.ServerType)
.IsRequired()
.HasColumnName("server_type")
.HasColumnType("varchar(50)");
builder.Property(x => x.Description)
.IsRequired()
.HasColumnName("description")
.HasColumnType("varchar(255)");
builder.Property(x => x.CreatedAt)
.HasColumnName("created_at")
.HasComment("생성 시간")
.HasColumnType("timestamp")
.IsRequired()
.HasDefaultValueSql("CURRENT_TIMESTAMP"); // MySQL 기본값
builder.Property(x => x.UpdatedAt)
.HasColumnName("updated_at")
.HasComment("수정 시간")
.HasColumnType("timestamp")
.IsRequired()
.HasDefaultValueSql("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"); // MySQL 기본값
}
}

View File

@@ -0,0 +1,63 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace BrokerApiCore.Repository.SqlConfig;
using BrokerCore.DbEntity;
public class PlanetItemExchangeOrderAmountTotalLimitConfig : IEntityTypeConfiguration<PlanetItemExchangeOrderAmountTotalLimit>
{
public void Configure(EntityTypeBuilder<PlanetItemExchangeOrderAmountTotalLimit> builder)
{
// 테이블 이름
builder.ToTable("planet_exchange_order_amount_total_limits");
// 인덱스
builder.HasIndex(o => o.ExchangeDate);
builder.HasIndex(o => o.ExchangeMetaId);
builder.HasIndex(o => o.SeasonId);
// 복합 기본 키 (Primary Key) - ExchangeMetaId에 PlanetId 속성이 있으므로 생략함
builder.HasKey(o => new { o.ExchangeMetaId, o.ExchangeDate, o.SeasonId});
// 교환 메타 아이디
builder.Property(o => o.ExchangeMetaId)
.HasColumnName("exchange_meta_id")
.HasMaxLength(50)
.IsRequired()
.HasComment("교환 메타 아이디");
// 교환 일자
builder.Property(o => o.ExchangeDate)
.HasColumnName("exchange_date")
.IsRequired()
.HasComment("교환 일자");
// 교환 메타 수량
builder.Property(o => o.DailyAmount)
.HasColumnName("daily_amount")
.HasColumnType("INT")
.IsRequired()
.HasComment("일일 교환 메타 수량 합계");
builder.Property(o => o.SeasonId)
.HasColumnName("season_id")
.HasMaxLength(50)
.IsRequired()
.HasComment("시즌 아이디");
builder.Property(o => o.CreatedAt)
.HasColumnName("created_at")
.HasColumnType("TIMESTAMP")
.IsRequired()
.HasComment("생성 일자");
builder.Property(o => o.UpdatedAt)
.HasColumnName("updated_at")
.HasColumnType("TIMESTAMP")
.IsRequired()
.HasComment("업데이트 일자");
}
}

View File

@@ -0,0 +1,72 @@

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace BrokerApiCore.Repository.SqlConfig;
using BrokerCore.DbEntity;
public class PlanetItemExchangeOrderAmountUserLimitConfig : IEntityTypeConfiguration<PlanetItemExchangeOrderAmountUserLimit>
{
public void Configure(EntityTypeBuilder<PlanetItemExchangeOrderAmountUserLimit> builder)
{
// 테이블 이름
builder.ToTable("planet_exchange_order_amount_user_limits");
// 인덱스
builder.HasIndex(o => o.ExchangeMetaId);
builder.HasIndex(o => o.ExchangeDate);
builder.HasIndex(o => o.SeasonId);
builder.HasIndex(o => o.UserGuid);
// 복합 기본 키 (Primary Key) - ExchangeMetaId에 PlanetId 속성이 있으므로 생략함
builder.HasKey(o => new { o.ExchangeMetaId, o.ExchangeDate, o.SeasonId, o.UserGuid });
// 교환 메타 아이디
builder.Property(o => o.ExchangeMetaId)
.HasColumnName("exchange_meta_id")
.HasMaxLength(50)
.IsRequired()
.HasComment("교환 메타 아이디");
// 교환 일자
builder.Property(o => o.ExchangeDate)
.HasColumnName("exchange_date")
.IsRequired()
.HasComment("교환 일자");
// 유저 아이디
builder.Property(o => o.UserGuid)
.HasColumnName("user_guid")
.HasMaxLength(50)
.IsRequired()
.HasComment("유저 아이디 (GUID)");
// 교환 메타 수량
builder.Property(o => o.DailyAmount)
.HasColumnName("daily_amount")
.HasColumnType("INT")
.IsRequired()
.HasComment("사용자별 일일 교환 메타 수량");
builder.Property(o => o.SeasonId)
.HasColumnName("season_id")
.HasMaxLength(50)
.IsRequired()
.HasComment("시즌 아이디");
builder.Property(o => o.CreatedAt)
.HasColumnName("created_at")
.HasColumnType("TIMESTAMP")
.IsRequired()
.HasComment("생성 일자");
builder.Property(o => o.UpdatedAt)
.HasColumnName("updated_at")
.HasColumnType("TIMESTAMP")
.IsRequired()
.HasComment("업데이트 일자");
}
}

View File

@@ -0,0 +1,67 @@
namespace BrokerCore.Repository.SqlConfig;
using DbEntity;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
public class SapphireExchangeOrderConfig : IEntityTypeConfiguration<SapphireExchangeOrder>
{
public void Configure(EntityTypeBuilder<SapphireExchangeOrder> builder)
{
builder.ToTable("sapphire_exchange_order");
builder.HasKey(x => x.OrderId);
builder.HasIndex(x => x.CreatedAt);
builder.HasIndex(x => x.OrderStatus);
builder.HasIndex(x => x.AccountId);
builder.HasIndex(x => x.UserGuid);
builder.HasIndex(x => x.PlanetId);
builder.Property(x => x.OrderId)
.HasColumnName("order_id")
.HasColumnType("varchar(60)")
.HasComment("사파이어 교환 주문 아이디 guid")
.IsRequired();
builder.Property(x => x.OrderStatus)
.HasColumnName("order_status")
.HasComment("사파이어 교환 주문 상태")
.HasColumnType("tinyint")
.IsRequired();
builder.Property(x => x.AccountId)
.HasColumnName("account_id")
.HasComment("sso 계정 아이디")
.HasColumnType("bigint unsigned")
.IsRequired();
builder.Property(x => x.UserGuid)
.HasColumnName("user_guid")
.HasComment("유저 아이디")
.HasColumnType("varchar(50)")
.IsRequired();
builder.Property(x => x.PlanetId)
.HasColumnName("planet_id")
.HasComment("플래닛 아이디")
.HasColumnType("varchar(50)")
.IsRequired();
builder.Property(x => x.SapphireReducedDelta)
.HasColumnName("sapphire_reduced_amount")
.HasComment("사파이어 차감 수량")
.HasColumnType("decimal(20, 0)")
.IsRequired();
builder.Property(x => x.PlanetMoneyIncDelta)
.HasColumnName("planet_money_amount")
.HasComment("플래닛에서 발급한 재화 수량")
.HasColumnType("decimal(20, 0)")
.IsRequired();
builder.Property(x => x.CreatedAt)
.HasColumnName("created_at")
.HasComment("사파이어 교환 주문 시작 시간")
.HasColumnType("timestamp")
.IsRequired();
builder.Property(x => x.CompletedAt)
.HasColumnName("completed_at")
.HasComment("사파이어 교환 주문 완료 시간")
.HasColumnType("timestamp")
.IsRequired(false);
}
}

View File

@@ -0,0 +1,71 @@
using ServerCore;
using ServerBase;
using ServerCommon;
using Microsoft.EntityFrameworkCore;
namespace BrokerCore.Repository.Context;
using BrokerApiCore.Repository.SqlConfig;
using DbEntity;
using Microsoft.EntityFrameworkCore.Design;
using SqlConfig;
public class MetaverseBrokerDbContext: DbContext
{
public DbSet<SapphireExchangeOrder> SapphireExchangeOrders { get; set; }
public DbSet<PlanetInfo> PlanetInfos { get; set; }
public DbSet<PlanetItemExchangeOrder> PlanetItemExchangeOrders { get; set; }
//PlanetItemExchangeOrderAmountUserLimit
public DbSet<PlanetItemExchangeOrderAmountUserLimit> PlanetItemExchangeOrderAmountUserLimits { get; set; }
//PlanetItemExchangeOrderAmountTotalLimit
public DbSet<PlanetItemExchangeOrderAmountTotalLimit> PlanetItemExchangeOrderAmountTotalLimits { get; set; }
public MetaverseBrokerDbContext(DbContextOptions<MetaverseBrokerDbContext> options) : base(options)
{
// base.Database.EnsureCreated();
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfiguration(new PlanetInfoConfig());
// todo PlanetExchangeOrderConfig으로 교체 예정
modelBuilder.ApplyConfiguration(new SapphireExchangeOrderConfig());
modelBuilder.ApplyConfiguration(new PlanetExchangeOrderConfig());
modelBuilder.ApplyConfiguration(new PlanetItemExchangeOrderAmountUserLimitConfig());
modelBuilder.ApplyConfiguration(new PlanetItemExchangeOrderAmountTotalLimitConfig());
base.OnModelCreating(modelBuilder);
}
}
// ef core 마이그레이션 도구에서 디자인타임에 사용함
public class MetaverseBrokerDbContextFactory : IDesignTimeDbContextFactory<MetaverseBrokerDbContext>
{
public MetaverseBrokerDbContext CreateDbContext(string[] args)
{
// nlog 설정
var nlog_config_path = "../../bin/Debug/Config/nlog.config";
var full_path = Path.GetFullPath(nlog_config_path);
Console.WriteLine("[MetaverseBrokerDbContextFactory] Full path: {0}", full_path);
Log.NLogFileName = full_path;
Log.initLog("BrokerApiServer", "Developer");
var server_config = new ServerConfigMetaverseBroker();
server_config.setConfigFilePath("../../bin/Debug/Config/ServerConfig.json");
server_config.tryLoadConfig().GetAwaiter().GetResult();
var connection_string = server_config.MetaverseBroker?.MetaverseBrokerDbLocal;
Console.WriteLine("[MetaverseBrokerDbContextFactory] Connection string: {0}", connection_string);
if (string.IsNullOrEmpty(connection_string)) { throw new ApplicationException("Connection string is empty."); }
var mysql_version = ServerVersion.AutoDetect(connection_string);
Console.WriteLine("[MetaverseBrokerDbContextFactory] Mysql vsersion: {0}", mysql_version.ToString());
// var mysql_version = ServerVersion.Create(new Version(11, 6, 2), ServerType.MariaDb);
var options_builder = new DbContextOptionsBuilder<MetaverseBrokerDbContext>();
options_builder.UseMySql(connection_string, mysql_version, builder => builder.EnableRetryOnFailure(3)).EnableDetailedErrors();
return new MetaverseBrokerDbContext(options_builder.Options);
}
}

View File

@@ -0,0 +1,31 @@
using Microsoft.EntityFrameworkCore;
namespace BrokerCore.Repository.Context;
using DbEntity;
public class SsoAccountDbContext: DbContext
{
private readonly DbContextOptions<SsoAccountDbContext> m_options;
public DbSet<SsoAccountInfo> SsoAccounts { get; set; }
// public DbSet<WalletUser> WalletUsers { get; set; }
public SsoAccountDbContext(DbContextOptions<SsoAccountDbContext> options) : base(options)
{
m_options = options;
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<SsoAccountInfo>(entity =>
{
entity.ToTable("wallet_user");
entity.HasNoKey();
entity.Property(x => x.Id).HasColumnName("id").HasColumnType("bigint unsigned");
entity.Property(x => x.AccessToken).HasColumnName("access_token").HasColumnType("bigint unsigned");
entity.Property(x => x.AccessTokenIgm).HasColumnName("access_igm_token").HasColumnType("bigint unsigned");
entity.Property(x => x.Email).HasColumnName("email").HasColumnType("varchar(500)");
});
// base.OnModelCreating(modelBuilder);
}
}

View File

@@ -0,0 +1,52 @@
using Microsoft.EntityFrameworkCore;
namespace BrokerCore.Repository;
using Context;
using DbEntity;
public class SsoAccountRepo
{
private readonly SsoAccountDbContext m_db_context;
public SsoAccountRepo(SsoAccountDbContext dbContext)
{
m_db_context = dbContext;
}
public async Task<(Result, SsoAccountInfo?)> findOne(ulong id)
{
try
{
var sso_account = await m_db_context.SsoAccounts.Where(x => x.Id == id).FirstOrDefaultAsync();
if (sso_account == null)
{
return (new Result { ErrorCode = ServerErrorCode.AccountIdNotFoundInSsoAccountDb, ResultString = "Not found SsoAccount" },
null);
}
return (new Result(), sso_account);
}
catch (Exception e)
{
return (new Result { ErrorCode = ServerErrorCode.RdbError, ResultString = e.Message },
null);
}
}
public async Task<(Result, SsoAccountInfo?)> findOneByEmail(string email)
{
try
{
var sso_account = await m_db_context.SsoAccounts.Where(x => x.Email == email).FirstOrDefaultAsync();
if (sso_account == null)
{
return (new Result { ErrorCode = ServerErrorCode.AccountIdNotFoundInSsoAccountDb, ResultString = "Not found SsoAccount" },
null);
}
return (new Result(), sso_account);
}
catch (Exception e)
{
return (new Result { ErrorCode = ServerErrorCode.RdbError, ResultString = e.Message },
null);
}
}
}

View File

@@ -0,0 +1,67 @@
using ServerCommon;
namespace BrokerCore.Repository;
using ServerCore; using ServerBase;
public class UserBaseDocRepo
{
private readonly DynamoDbClient m_dynamo_db_client;
public UserBaseDocRepo(DynamoDbClient dynamoDbClient)
{
this.m_dynamo_db_client = dynamoDbClient;
}
public async Task<(Result, UserBaseDoc?)> findUserBaseDoc(string userGuid)
{
var (result, primary_key_object) = await DynamoDBDocBaseHelper.makePrimaryKey<UserBaseDoc>(userGuid);
if (result.isFail() || primary_key_object == null)
{
return (result, null);
}
var config = m_dynamo_db_client.makeQueryConfigForReadByPKOnly(primary_key_object.PK);
// var (result, user_doc) = await m_dynamoDbClient.simpleQueryDocTypeWithQueryOperationConfig<UserBaseDoc>(config);
return await m_dynamo_db_client.simpleQueryDocTypeWithQueryOperationConfig<UserBaseDoc>(config);
}
public async Task<(Result, UserBaseAttrib?)> findUserBaseAttrib(string userGuid)
{
var (result, doc) = await findUserBaseDoc(userGuid);
return (result, doc?.getAttrib<UserBaseAttrib>());
}
public async Task<(Result, string)> findNickname(string userGuid)
{
var (result, found_nickname_attrib) = await NicknameDoc.findNicknameFromGuid(m_dynamo_db_client, userGuid);
if(result.isFail())
{
return (result, string.Empty);
}
NullReferenceCheckHelper.throwIfNull(found_nickname_attrib, () => $"found_nickname_attrib is null !!!, userGuid:{userGuid}");
return (result, found_nickname_attrib.Nickname);
}
//===================================================================================================
// 로그아웃 여부만 체크
// TODO: 레디스 캐시를 이용하여 로그인 여부를 체크하는 것이 더 효율적일 수 있음
//===================================================================================================
public bool isUserLoggedIn(UserBaseAttrib userAttrib)
{
return userAttrib.GameLoginDateTime > userAttrib.GameLogoutDateTime;
}
// public async Task<Result> insertUserBaseDoc(UserBaseAttrib userAttrib)
// {
// var user_doc = new UserBaseDoc(userAttrib.UserGuid);
// var user_attrib = user_doc.getAttrib<UserBaseAttrib>();
// NullReferenceCheckHelper.throwIfNull(user_attrib, () => $"insertUserBaseDoc : user_attrib is null !!! - {userAttrib.UserGuid}");
// user_attrib.UserGuid = userAttrib.UserGuid;
// user_attrib.AccountId = userAttrib.AccountId;
// user_attrib.EOA = userAttrib.EOA;
// user_attrib.SelectedCharacterGuid = userAttrib.SelectedCharacterGuid;
// user_attrib.IsIntroCompleted = userAttrib.IsIntroCompleted;
// return await m_dynamoDbClient.simpleInsertDocumentWithDocType(user_doc);
// }
}

View File

@@ -0,0 +1,155 @@

using ServerCore;
using ServerBase;
using ServerCommon;
using ServerCommon.BusinessLogDomain;
namespace BrokerCore.Services;
using Common;
public class EchoSystemService
{
private readonly IServerLogic m_server_logic;
private string m_user_guid = string.Empty;
CaliumEventRequest? m_calium_event_payload;
const int m_retry_count_max = 5;
const int m_retry_interval_ms = 1000;
public EchoSystemService(IServerLogic serverLogic)
{
m_server_logic = serverLogic;
}
private class CaliumEchoSystemFailBusinessLog : ILogInvokerEx
{
private readonly CaliumEchoSystemFailLogData m_data_to_log;
public CaliumEchoSystemFailBusinessLog(CaliumEchoSystemFailLogData log) : base(LogDomainType.CaliumEchoSystem)
{
m_data_to_log = log;
}
public override bool hasLog() => true;
protected override void fillup(ref BusinessLog.LogBody body)
{
body.append(new CaliumEchoSystemFailLogData(this, m_data_to_log));
}
}
public async Task createAndSetEventPayload(string accountId, string nickname, string userGuid,
long sapphireDelta, string serverType, string eventType, string subType = "BrokerApiServer")
{
m_user_guid = userGuid;
var calium_storage_attrib = await findCaliumStorage();
var calium_event_payload = new CaliumEventRequest
{
m_event_id = Guid.NewGuid().ToString("N"),
m_server_type = serverType,
m_event_type = eventType, // CaliumEventType.extra_get.ToString(),
// 확인용 문자열
m_sub_type = subType,
m_div_type = nickname,
m_div_id = accountId,
m_calium_delta = 0,
m_sapphire_delta = Convert.ToDouble(sapphireDelta),
m_current_epoch = calium_storage_attrib?.DailyEpoch ?? 0,
m_current_inflation_rate = calium_storage_attrib?.ExchangerStorage.DailyInflationRate ?? Convert.ToDouble(0)
};
m_calium_event_payload = calium_event_payload;
}
private async Task<CaliumStorageAttrib?> findCaliumStorage()
{
var dynamo_db_client = m_server_logic.getDynamoDbClient();
var (result_pk, primary_key_object) = await DynamoDBDocBaseHelper.makePrimaryKey<CaliumStorageDoc>(m_user_guid);
if (result_pk.isFail() || primary_key_object == null)
{
return null;
}
var config = dynamo_db_client.makeQueryConfigForReadByPKOnly(primary_key_object.PK);
var (result, doc) =
await dynamo_db_client.simpleQueryDocTypeWithQueryOperationConfig<CaliumStorageDoc>(config);
var attrib = doc?.getAttrib<CaliumStorageAttrib>();
return attrib;
}
public async Task<Result> processCaliumEvent(IWithLogActor logActor)
{
Guard.Against.isNull(m_calium_event_payload, ServerErrorCode.InternalServerError,
() => "m_calium_event_payload is null");
var server_config = m_server_logic.getServerConfig();
var url = server_config.EchoSystemConfig.BaseAddress;
var echo_system_requester = new EchoSystemRequester(url);
var result = new Result();
CaliumEventResponse? echo_system_response = null;
foreach (var _ in Enumerable.Range(0, m_retry_count_max))
{
(result, echo_system_response) = await echo_system_requester.postCaliumEvent(m_calium_event_payload);
if (result.isSuccess())
{
Log.getLogger().info("EchoSystemRequest Success");
break;
}
Log.getLogger().info("EchoSystemRequest Failed");
if (result.ErrorCode == ServerErrorCode.FailToGetEchoSystemHttpError)
{
await Task.Delay(m_retry_interval_ms);
}
}
if (result.isSuccess())
{
return result;
}
//========================================
// 여기서 부터 실패시 처리
//========================================
await insertEventFailDoc(m_user_guid);
Log.getLogger().info($"EchoSystemRequest Failed => Code: {echo_system_response?.m_code}");
BusinessLogger.collectLog(logActor, new CaliumEchoSystemFailBusinessLog(
new CaliumEchoSystemFailLogData
{
FailCode = echo_system_response?.m_code ?? string.Empty,
FailMessages = echo_system_response?.m_messages ?? [],
ReTry = false,
EventData = m_calium_event_payload
}));
return result;
}
// 칼리움 이벤트가 실패하면 CaliumEventDoc을 생성해서 채널 서버에 이 후에 처리하도록 유도한다.
private async Task insertEventFailDoc(string userGuid)
{
var dynamo_db_client = m_server_logic.getDynamoDbClient();
var request = m_calium_event_payload;
Guard.Against.isNull(request, ServerErrorCode.InternalServerError, () => "m_calium_event_payload is null");
var doc = new CaliumEventDoc(request.m_event_id);
var attrib = doc.getAttrib<CaliumEventAttrib>();
NullReferenceCheckHelper.throwIfNull(attrib, () => $"calium event attrib is null !!! - userGuid[{userGuid}]");
attrib.UserGuid = userGuid;
attrib.EventData.m_server_type = request.m_server_type;
attrib.EventData.m_event_type = request.m_event_type;
attrib.EventData.m_sub_type = request.m_sub_type;
attrib.EventData.m_div_type = request.m_div_type;
attrib.EventData.m_div_id = request.m_div_id;
attrib.EventData.m_calium_delta = request.m_calium_delta;
attrib.EventData.m_sapphire_delta = request.m_sapphire_delta;
attrib.EventData.m_current_epoch = request.m_current_epoch;
attrib.EventData.m_current_inflation_rate = request.m_current_inflation_rate;
attrib.Status = CaliumEventStatus.Regist;
await dynamo_db_client.simpleInsertDocumentWithDocType(doc);
}
}

View File

@@ -0,0 +1,92 @@

using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using Microsoft.IdentityModel.Tokens;
using ServerCore; using ServerBase;
namespace BrokerCore.Services;
using Common;
public class JwtGenerator
{
private readonly JwtOption m_jwt_option;
public JwtGenerator(JwtOption jwtOption)
{
m_jwt_option = jwtOption;
}
public JwtOption JwtOption => m_jwt_option;
// Access Token 생성
public string generateAccessToken(string planetId, string planetServerType, string? refreshToken = null)
{
// todo: 토큰 유효기간 설정
var issued_at = new DateTime(2025, 3, 1, 0, 0, 0, DateTimeKind.Utc);
var expires = issued_at.AddYears(1);
var security_key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(m_jwt_option.Secret));
var credentials = new SigningCredentials(security_key, SecurityAlgorithms.HmacSha256);
var claims = new[]
{
new Claim(JwtRegisteredClaimNames.Sid, planetId), // 사용자 ID
new Claim(JwtRegisteredClaimNames.Typ, planetServerType),
};
var header = new JwtHeader(credentials);
var payload = new JwtPayload(
issuer:null,
audience:null,
claims: claims,
notBefore: null, // 토큰이 유효 일시
expires: expires, // 토큰 만료 일시
issuedAt: issued_at // iat 발행일시
);
var token = new JwtSecurityToken(header, payload);
return new JwtSecurityTokenHandler().WriteToken(token);
}
}
public class JwtParser
{
private readonly JwtOption m_jwt_option;
public JwtParser(JwtOption jwtOption)
{
m_jwt_option = jwtOption;
}
public ClaimsPrincipal? parseToken(string token)
{
var token_handler = new JwtSecurityTokenHandler();
// 시크릿 키를 바이트 배열로 변환
var key = Encoding.UTF8.GetBytes(m_jwt_option.Secret);
// 토큰 검증 매개변수 설정
var validation_parameters = new TokenValidationParameters
{
ValidateIssuer = false,
ValidateAudience = false,
ValidIssuer = "",
ValidAudience = "",
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key)
};
try
{
// 토큰 검증 및 클레임 추출
var principal = token_handler.ValidateToken(token, validation_parameters, out var validated_token);
return principal;
}
catch (SecurityTokenException ex)
{
Log.getLogger().error($"JWT 파싱 에러 => {ex.Message}");
}
return null;
}
}

View File

@@ -0,0 +1,185 @@
// namespace BrokerCore.Services;
//
// using System.IdentityModel.Tokens.Jwt;
// using System.Security.Claims;
// using System.Security.Cryptography;
// using System.Text;
//
// using Microsoft.IdentityModel.Tokens;
//
// public interface IJwtUser
// {
// public string Id { get; }
// }
//
// public interface IJwtAuth
// {
//
// }
//
// public class RefreshToken
// {
// public int Id { get; set; }
// public string Token { get; set; } = string.Empty;
// public DateTime Created { get; set; } = DateTime.UtcNow;
// public DateTime Expires { get; set; }
// public bool IsExpired => DateTime.UtcNow >= Expires;
// public DateTime? Revoked { get; set; }
// public bool IsActive => Revoked == null && !IsExpired;
// public string? ReplacedByToken { get; set; }
// public string? ReasonRevoked { get; set; }
// public int UserId { get; set; }
// public IJwtUser User { get; set; } = null!;
// }
//
// public interface IJwtService<in TUser, TAuth> where TUser : class
// {
// string generateJwtToken(TUser user, string secretKey, int expirationMinutes = 15);
// string generateRefreshToken();
// int? validateJwtToken(string token);
// Task<TAuth> refreshTokenAsync(string token, string ipAddress);
// Task revokeTokenAsync(string token, string ipAddress, string? reason = null);
// }
// public class JwtService: IJwtService<IJwtUser, IJwtAuth>
// {
// private string m_secret_key = string.Empty;
// private int m_expiration_minutes = 15;
// private string m_issuer = string.Empty;
// private string m_audience = string.Empty;
//
// public string generateJwtToken(IJwtUser user)
// {
// if (user == null)
// throw new ArgumentNullException(nameof(user));
//
// if (string.IsNullOrEmpty(m_secret_key))
// throw new ArgumentNullException(nameof(m_secret_key));
//
// if (m_expiration_minutes <= 0)
// throw new ArgumentOutOfRangeException(nameof(m_expiration_minutes), "Expiration minutes must be greater than zero.");
//
// var token_handler = new JwtSecurityTokenHandler();
// var key = Encoding.ASCII.GetBytes(m_secret_key);
//
// var claims = new List<Claim>
// {
// new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
// // new Claim(ClaimTypes.Name, user.Username),
// // new Claim(ClaimTypes.Email, user.Email)
// // 필요한 경우 추가 클레임 정의 (역할 등)
// };
//
// var token_descriptor = new SecurityTokenDescriptor
// {
// Subject = new ClaimsIdentity(claims),
// Expires = DateTime.UtcNow.AddMinutes(15), // 액세스 토큰 만료 시간 (짧게 설정)
// Issuer = string.Empty,
// Audience = string.Empty,
// SigningCredentials = new SigningCredentials(
// new SymmetricSecurityKey(key),
// SecurityAlgorithms.HmacSha256Signature)
// };
//
// var token = token_handler.CreateToken(token_descriptor);
// return token_handler.WriteToken(token);
// }
//
// public string generateRefreshToken()
// {
// var random_number = new byte[16];
// using var rng = RandomNumberGenerator.Create();
// rng.GetBytes(random_number);
// return Convert.ToBase64String(random_number);
// }
//
// public int? validateJwtToken(string token)
// {
// if (string.IsNullOrEmpty(token))
// return null;
//
// var token_handler = new JwtSecurityTokenHandler();
// var key = Encoding.ASCII.GetBytes(m_secret_key);
//
// try
// {
// token_handler.ValidateToken(token, new TokenValidationParameters
// {
// ValidateIssuerSigningKey = true,
// IssuerSigningKey = new SymmetricSecurityKey(key),
// ValidateIssuer = true,
// ValidIssuer = this.m_issuer,
// ValidateAudience = true,
// ValidAudience = this.m_audience,
// // 시간 검증 설정
// ValidateLifetime = true,
// ClockSkew = TimeSpan.Zero
// }, out SecurityToken validated_token);
//
// var jwt_token = (JwtSecurityToken)validated_token;
// var user_id = int.Parse(jwt_token.Claims.First(x => x.Type == ClaimTypes.NameIdentifier).Value);
//
// return user_id;
// }
// catch
// {
// // 토큰 검증 실패
// return null;
// }
// }
//
// public Task<IJwtAuth> refreshTokenAsync(string token)
// {
// // 리프레시 토큰으로 유저 정보를 가져온다.
// var user;
//
// // 사용자가 없거나 토큰이 존재하지 않음
// if (user == null)
// throw new SecurityTokenException("Invalid token");
//
// var refreshToken = user.RefreshTokens.Single(x => x.Token == token);
//
// // 토큰이 더 이상 활성 상태가 아니면 오류
// if (!refreshToken.IsActive)
// throw new SecurityTokenException("Invalid token");
//
// // 새 리프레시 토큰 생성
// var newRefreshToken = generateRefreshTokenEntity();
//
// // 이전 토큰 폐기
// refreshToken.Revoked = DateTime.UtcNow;
// refreshToken.ReplacedByToken = newRefreshToken.Token;
// refreshToken.ReasonRevoked = "Replaced by new token";
//
// // 새 리프레시 토큰 추가
// user.RefreshTokens.Add(newRefreshToken);
// _context.Update(user);
// await _context.SaveChangesAsync();
//
// // 새 JWT 생성
// var jwtToken = generateJwtToken(user);
//
// return new
// {
// Id = user.Id,
// Username = user.Username,
// Email = user.Email,
// AccessToken = jwtToken,
// RefreshToken = newRefreshToken.Token
// };
// }
//
// public Task revokeTokenAsync(string token, string ipAddress, string? reason = null)
// {
// throw new NotImplementedException();
// }
//
// private RefreshToken generateRefreshTokenEntity()
// {
// return new RefreshToken
// {
// Token = generateRefreshToken(),
// Expires = DateTime.UtcNow.AddDays(32), // 리프레시 토큰 만료 시간 (길게 설정)
// Created = DateTime.UtcNow
// };
// }
// }

View File

@@ -0,0 +1,76 @@
namespace BrokerCore.Services;
using System.Security.Claims;
using BrokerBusinessLog;
using Microsoft.IdentityModel.JsonWebTokens;
using Repository;
using Common;
using ServerBase;
using ServerCommon;
public class PlanetService
{
private readonly PlanetInfoRepo m_planet_info_repo;
private readonly JwtGenerator m_jwt_generator;
private readonly JwtParser m_jwt_parser;
private PlanetProviderLogActor m_log_actor;
public PlanetService(PlanetInfoRepo planetInfoRepo, JwtGenerator jwtGenerator, JwtParser jwtParser)
{
m_planet_info_repo = planetInfoRepo;
m_jwt_generator = jwtGenerator;
m_jwt_parser = jwtParser;
}
public async Task<string?> auth(string planetId, string planetSecretKey)
{
var (result, planet_info) = await m_planet_info_repo.findOne(planetId);
Guard.Against.resultFail(result, ServerErrorCode.PlanetIdNotFound, () => "플래닛의 id가 존재하지 않음");
Guard.Against.isNull(planet_info, ServerErrorCode.PlanetIdNotFound, () => "플래닛의 id가 존재하지 않음");
Guard.Against.isFalse(planet_info.SecretKey == planetSecretKey,
ServerErrorCode.PlanetSecretKeyDoesNotMatched, () => "플래닛에 제공한 엑세스키와 맞지 않음");
var access_token = m_jwt_generator.generateAccessToken(planetId, planet_info.ServerType);
// 비즈니스 로그
m_log_actor = new PlanetProviderLogActor(planetId);
BusinessLogger.collectLog(m_log_actor,
new PlanetProviderAuthBusinessLog(
new LogActionEx(LogActionType.BrokerApiPlanetAuth),
new PlanetProviderAuthLogData { PlanetId = planetId, ExpireDateTime = DateTime.UtcNow }));
return access_token;
}
public (string, string) validate(string jwt)
{
if (jwt == m_jwt_generator.JwtOption.JwtTestPassToken)
{
return ("new_earth", "caliverse");
}
var principal = m_jwt_parser.parseToken(jwt);
Guard.Against.isNull(principal, ServerErrorCode.InvalidPlanetJwt, () => "jwt parsing error");
var exp_claim = principal.FindFirst(JwtRegisteredClaimNames.Exp)?.Value;
Guard.Against.isNull(principal, ServerErrorCode.InvalidPlanetJwt, () => "no JwtRegisteredClaimNames.Exp value");
var exp_time = DateTimeOffset.FromUnixTimeSeconds(long.Parse(exp_claim ?? string.Empty));
Guard.Against.isFalse(exp_time > DateTimeOffset.UtcNow, ServerErrorCode.ExpiredPlanetJwt,
() => "Jwt has expired");
var planet_id = principal.FindFirstValue(JwtRegisteredClaimNames.Sid);
Guard.Against.isNullOrEmptyOrWhiteSpace(planet_id, ServerErrorCode.InvalidPlanetJwt,
() => "jwt parsing error no sub");
var planet_server_type = principal.FindFirstValue(JwtRegisteredClaimNames.Typ);
Guard.Against.isNullOrEmptyOrWhiteSpace(planet_server_type, ServerErrorCode.InvalidPlanetJwt,
() => "jwt parsing error no typ");
return (planet_id, planet_server_type);
}
}

View File

@@ -0,0 +1,80 @@
namespace BrokerCore.Services;
using Common;
using DbEntity;
using ServerBase;
using ServerCommon;
using MetaAssets;
using Repository;
public class DailyAmountLimitChecker
{
private readonly PlanetItemExchangeOrderAmountTotalLimitRepo m_planet_item_exchange_order_amount_total_limit;
private readonly PlanetItemExchangeOrderAmountUserLimitRepo m_planet_item_exchange_order_amount_user_limit;
public DailyAmountLimitChecker(
PlanetItemExchangeOrderAmountTotalLimitRepo planetItemExchangeOrderAmountTotalLimit,
PlanetItemExchangeOrderAmountUserLimitRepo planetItemExchangeOrderAmountUserLimit)
{
m_planet_item_exchange_order_amount_total_limit = planetItemExchangeOrderAmountTotalLimit;
m_planet_item_exchange_order_amount_user_limit = planetItemExchangeOrderAmountUserLimit;
}
public async Task<(Result result,
PlanetItemExchangeOrderAmountTotalLimit? totalLimit,
PlanetItemExchangeOrderAmountUserLimit? userLimit)>
dailyLimitCheck(PlanetItemExchangeOrder order,
PlanetItemExchangePolicyMetaData exchangePolicy, CancellationToken cancellationToken = default)
{
var result = new Result();
PlanetItemExchangeOrderAmountTotalLimit? total_limit = null;
PlanetItemExchangeOrderAmountUserLimit? user_limit = null;
try
{
var exchange_date = DateOnly.FromDateTime(order.CreatedAt.ToUniversalTime());
var total_daily_limit = exchangePolicy.DailyTotalAmountLimit;
(result, total_limit) =
await m_planet_item_exchange_order_amount_total_limit.findByExchangeMetaAndDateOrCreate(
order.ExchangeMetaId,
exchange_date,
order.SeasonId,
cancellationToken);
Guard.Against.resultFail(result);
Guard.Against.isNull(total_limit, ServerErrorCode.RdbError,
()=>"PlanetItemExchangeOrderAmountTotalLimit not found");
Guard.Against.isTrue(total_limit.DailyAmount + order.ExchangeMetaAmount > total_daily_limit,
ServerErrorCode.ExchangeTotalOrderDailyLimitExceeded,
()=>$"Daily total amount limit exceeded [{exchangePolicy.ID}] => current_total_daily_limit:{total_limit.DailyAmount} + order.ExchangeMetaAmount:{order.ExchangeMetaAmount} > total_daily_limit:{total_daily_limit}"
);
var user_daily_limit = exchangePolicy.DailyUserAmountLimit;
(result, user_limit) =
await m_planet_item_exchange_order_amount_user_limit.findByExchangeMetaAndDateOrCreate(order.ExchangeMetaId,
order.UserGuid, exchange_date, order.SeasonId, cancellationToken);
Guard.Against.resultFail(result);
Guard.Against.isNull(user_limit, ServerErrorCode.RdbError,
()=>"PlanetItemExchangeOrderAmountUserLimit not found");
Guard.Against.isTrue(user_limit.DailyAmount + order.ExchangeMetaAmount > user_daily_limit,
ServerErrorCode.ExchangeUserOrderDailyLimitExceeded,
()=>$"Daily user amount limit exceeded [{exchangePolicy.ID}] => current_user_daily_limit:{user_limit.DailyAmount} + order.ExchangeMetaAmount:{order.ExchangeMetaAmount} > user_daily_limit:{user_daily_limit}"
);
}
catch (ApiException ex)
{
result.setFail((ServerErrorCode)ex.ErrorCode, ex.Message);
return (result, total_limit, user_limit);
}
catch (Exception ex)
{
result.setFail(ServerErrorCode.InternalServerError, ex.Message);
return (result, total_limit, user_limit);
}
return (result, total_limit, user_limit);
}
}

View File

@@ -0,0 +1,16 @@
namespace BrokerCore.Services;
using DbEntity;
using Entity;
public interface IOrderCompletionStrategy
{
Task<PlanetItemExchangeOrder> completeOrder(
PlanetUserEntity planetUserEntity,
PlanetItemExchangeOrder order_created,
CancellationToken cancellationToken = default);
}

View File

@@ -0,0 +1,14 @@
using BrokerCore.DbEntity;
using MetaAssets;
namespace BrokerCore.Services;
public interface IOrderCreationStrategy
{
Task<(Result, PlanetItemExchangeOrder)> createOrder(
PlanetItemExchangeOrder order,
string planetServerType,
PlanetItemExchangePolicyMetaData exchangePolicy,
CancellationToken cancellationToken);
}

View File

@@ -0,0 +1,9 @@
using ServerCommon;
namespace BrokerCore.Services;
public interface IOrderStrategyProvider
{
IOrderCreationStrategy? getCreationStrategy(CaliverseItemType itemType);
IOrderCompletionStrategy? getCompletionStrategy(CaliverseItemType itemType);
}

View File

@@ -0,0 +1,54 @@
using Microsoft.Extensions.DependencyInjection;
using ServerCommon;
using System.Collections.Concurrent;
namespace BrokerCore.Services;
public class OrderStrategyProvider : IOrderStrategyProvider
{
private readonly IServiceProvider m_service_provider;
private readonly ConcurrentDictionary<CaliverseItemType, Type> m_creation_strategy_map;
private readonly ConcurrentDictionary<CaliverseItemType, Type> m_completion_strategy_map;
public OrderStrategyProvider(IServiceProvider serviceProvider)
{
m_service_provider = serviceProvider;
// 전략 맵핑 초기화
m_creation_strategy_map = new ConcurrentDictionary<CaliverseItemType, Type>
{
[CaliverseItemType.Currency] = typeof(CurrencyExchangeCreationStrategy),
[CaliverseItemType.CaliverseProduct] = typeof(ProductExchangeCreationStrategy)
};
m_completion_strategy_map = new ConcurrentDictionary<CaliverseItemType, Type>
{
[CaliverseItemType.Currency] = typeof(CurrencyOrderCompletionStrategy),
[CaliverseItemType.CaliverseProduct] = typeof(ProductOrderCompletionStrategy)
};
}
public IOrderCreationStrategy? getCreationStrategy(CaliverseItemType itemType)
{
if (m_creation_strategy_map.TryGetValue(itemType, out var strategy_type))
{
return m_service_provider.GetService(strategy_type) as IOrderCreationStrategy;
}
// 기본 전략 반환
return m_service_provider.GetService<CurrencyExchangeCreationStrategy>();
}
public IOrderCompletionStrategy? getCompletionStrategy(CaliverseItemType itemType)
{
if (m_completion_strategy_map.TryGetValue(itemType, out var strategy_type))
{
return m_service_provider.GetService(strategy_type) as IOrderCompletionStrategy;
}
// 기본 전략 반환
return m_service_provider.GetService<CurrencyOrderCompletionStrategy>();
}
}

View File

@@ -0,0 +1,218 @@
namespace BrokerCore.Services;
using ServerCommon;
using Common;
using DbEntity;
using Repository;
using Entity;
using System.Collections.Generic;
using BrokerBusinessLog;
using MetaAssets;
using ServerCore; using ServerBase;
public class PlanetItemExchangeService
{
readonly PlanetUserEntity m_planet_user;
private readonly IOrderStrategyProvider m_strategies;
private readonly BrokerMetaTableRef m_meta_table_ref;
private readonly PlanetItemExchangeOrderRepo m_planet_item_exchange_repo;
private readonly DynamoDbClient m_dynamo_db_client;
public PlanetItemExchangeService(
IServerLogic serverLogic,
PlanetUserEntity planetUser,
IOrderStrategyProvider strategies,
BrokerMetaTableRef metaTableRef,
PlanetItemExchangeOrderRepo planetItemExchangeOrderRepo)
{
m_planet_user = planetUser;
m_strategies = strategies;
m_meta_table_ref = metaTableRef;
m_planet_user.onInit().Wait();
m_planet_item_exchange_repo = planetItemExchangeOrderRepo;
m_dynamo_db_client = serverLogic.getDynamoDbClient();
}
public PlanetUserEntity PlanetUser => m_planet_user;
//===================================================================================================
// 로그아웃 여부만 체크
//===================================================================================================
public bool isUserLoggedIn()
{
var user_attribute = m_planet_user.getEntityAttributeNotNull<UserAttribute>();
return user_attribute.GameLoginDateTime > user_attribute.GameLogoutDateTime;
}
//===================================================================================================
// 유저 인증 및 account, user, nickname 정보 읽음
//===================================================================================================
public async Task validateAndGetUser(
string accountId, string userGuid, string planetId
)
{
m_planet_user.setPlanetId(planetId);
var action = m_planet_user.getEntityActionNotNull<UserAuthAction>();
if (!string.IsNullOrEmpty(accountId))
{
var result = await action.findAndSetAllAttributeByAccountId(accountId);
Guard.Against.resultFail(result);
}
else
{
var result = await action.findAndSetAllAttributeByUserGuid(userGuid);
Guard.Against.resultFail(result);
}
}
//=============================================================================================
// 현재 재화 요청
//=============================================================================================
public async Task<double> getCurrencyAmount(string currencyTypeString)
{
var currency_type = currencyTypeString.convertEnumTypeAndValueStringToEnum(CurrencyType.None);
Guard.Against.isFalse(currency_type != CurrencyType.None, ServerErrorCode.InvalidRequest,
() => "Invalid currency type");
CurrencyControlHelper.setDbConnector(m_dynamo_db_client);
var user_guid = m_planet_user.getEntityAttributeNotNull<AccountAttribute>().UserGuid;
var (result, current_sapphire_amount_double) =
await CurrencyControlHelper.getMoneyByUserGuid(user_guid, currency_type);
Guard.Against.resultFail(result);
return current_sapphire_amount_double;
}
//=============================================================================================
// 교환 주문 조회
//=============================================================================================
public async Task<(IEnumerable<PlanetItemExchangeOrder>, int)> findOrderList(
string planetId,
string metaId,
string seasonId,
string userGuid,
ExchangeOrderStatus? orderStatus = null,
int pageIndex = 1,
int pageSize = 20,
string sortOrder = "asc",
CancellationToken cancellationToken = default)
{
var (result, orders, total_count) =
await m_planet_item_exchange_repo.findList(
planetId,
metaId,
seasonId,
userGuid,
orderStatus,
pageIndex,
pageSize,
sortOrder,
cancellationToken);
Guard.Against.resultFail(result, ServerErrorCode.RdbError, () => result.ResultString);
Guard.Against.isNull(orders, ServerErrorCode.RdbError, () => result.ResultString);
return (orders, total_count);
}
//=============================================================================================
// 교환 주문 생성
//=============================================================================================
public async Task<(Result, PlanetItemExchangeOrder)> createOrder(
string planetId,
string seasonId,
string planetServerType,
string exchangeMetaId,
int exchangeMetaAmount,
CancellationToken cancellationToken = default)
{
// 메타 테이블에서 교환 정보 가져오기
m_meta_table_ref.MetaTable.PlanetItemExchangePolicyMetaTable.PlanetItemExchangePolicyDataListbyID
.TryGetValue(exchangeMetaId, out var exchange_policy);
Guard.Against.isNull(exchange_policy, ServerErrorCode.MetaIdInvalid,
() => $"Invalid ExchangeMetaId:{exchangeMetaId}");
// 주문 내역 생성
var order = makeExchangeOrderInfo(planetId, seasonId, exchange_policy, exchangeMetaAmount);
// 아이템 유형에 따라 전략 선택
var caliverse_item_type =
exchange_policy.CaliverseItemType.convertEnumTypeAndValueStringToEnum(CaliverseItemType.None);
var strategy = m_strategies.getCreationStrategy(caliverse_item_type);
Guard.Against.isNull(strategy, ServerErrorCode.InternalServerError,
() => "createOrder Invalid Item Type Strategy");
var (result, order_info) =
await strategy.createOrder(order, planetServerType, exchange_policy, cancellationToken);
Guard.Against.resultFail(result, ServerErrorCode.InternalServerError, () => result.ResultString);
// 비즈니스 로그 작성
BusinessLogger.collectLog(m_planet_user,
new PlanetItemExchangeBusinessLog(new LogActionEx(LogActionType.BrokerApiUserExchangeOrderCreated),
Helpers.createFromExchangeOrderLog(order)));
return (result, order_info);
}
//=============================================================================================
// 교환 주문 완료
// 주문 상태가 Pending 이어야 한다.
//=============================================================================================
public async Task<PlanetItemExchangeOrder> completeOrder(
string orderId, CancellationToken cancellationToken = default)
{
// 생성 주문 조회
var (result, order_created) =
await m_planet_item_exchange_repo.findOne(orderId, ExchangeOrderStatus.Pending, cancellationToken);
Guard.Against.resultFail(result);
Guard.Against.isNull(order_created, ServerErrorCode.ExchangeOrderIdNotFound, () => "Invalid Order Id");
// 주문 타입에 맞는 전략 선택 후 완료 처리
var strategy = m_strategies.getCompletionStrategy(order_created.CaliverseItemType);
Guard.Against.isNull(strategy, ServerErrorCode.InternalServerError, () => "completeOrder Invalid Order Type");
var order_completed = await strategy.completeOrder(m_planet_user, order_created, cancellationToken);
// 비즈니스 로그 작성
BusinessLogger.collectLog(m_planet_user,
new PlanetItemExchangeBusinessLog(new LogActionEx(LogActionType.BrokerApiUserExchangeOrderCompleted),
Helpers.createFromExchangeOrderLog(order_completed)));
return order_completed;
}
private PlanetItemExchangeOrder makeExchangeOrderInfo(
string planetId,
string seasonId,
PlanetItemExchangePolicyMetaData exchangePolicy,
int exchangeMetaAmount)
{
var now = DateTime.UtcNow;
return new PlanetItemExchangeOrder
{
OrderId = $"{now:yyMMdd}{Guid.NewGuid():N}",
OrderStatus = ExchangeOrderStatus.Pending,
SeasonId = seasonId,
PlanetId = planetId,
AccountId = m_planet_user.AccountId,
UserGuid = m_planet_user.UserGuid,
Nickname = m_planet_user.Nickname,
CaliverseItemType =
exchangePolicy.CaliverseItemType.convertEnumTypeAndValueStringToEnum(CaliverseItemType.None),
CaliverseItemId = exchangePolicy.CaliverseItemId,
CaliverseItemDeltaAmount = exchangeMetaAmount * exchangePolicy.CaliverseItemAmount,
PlanetItemType = exchangePolicy.PlanetItemType.convertEnumTypeAndValueStringToEnum(PlanetItemType.None),
PlanetItemId = exchangePolicy.PlanetItemId,
PlanetItemDeltaAmount = exchangeMetaAmount * exchangePolicy.PlanetItemAmount,
CreatedAt = now,
CompletedAt = null,
ExchangeMetaId = exchangePolicy.ID,
ExchangeMetaAmount = exchangeMetaAmount,
};
}
}

View File

@@ -0,0 +1,27 @@
using Microsoft.Extensions.DependencyInjection;
namespace BrokerCore.Services;
using Entity;
public static class ServiceCollectionExtensions
{
public static IServiceCollection addExchangeServices(this IServiceCollection services)
{
services.AddScoped<PlanetUserEntity>();
// 전략 등록
services.AddScoped<CurrencyExchangeCreationStrategy>();
services.AddScoped<ProductExchangeCreationStrategy>();
services.AddScoped<CurrencyOrderCompletionStrategy>();
services.AddScoped<ProductOrderCompletionStrategy>();
// 전략 제공자 등록
services.AddScoped<IOrderStrategyProvider, OrderStrategyProvider>();
// 서비스 등록
services.AddScoped<EchoSystemService>();
// services.AddScoped<SapphireExchangeService>();
services.AddScoped<PlanetItemExchangeService>();
return services;
}
}

View File

@@ -0,0 +1,163 @@
using BrokerCore.DbEntity;
using BrokerCore.Entity;
using BrokerCore.Repository;
using Microsoft.Extensions.Logging;
// using Polly;
// using Polly.Retry;
using MetaAssets;
using ServerCommon;
namespace BrokerCore.Services;
using Common;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
using Repository.Context;
using ServerCore; using ServerBase;
//=========================================================================================
// 플래닛의 아이템을 칼리버스 재화로 교환하는 주문 생성
// Broker의 rdb(순수 교환 정보)와 DynamoDB(유저의 게임정보)를 사용하여 교환 주문을 생성한다.
// 유저의 게임 정보에서 재화가 차감되면
//=========================================================================================
public class CurrencyExchangeCreationStrategy : IOrderCreationStrategy
{
private readonly PlanetUserEntity m_planet_user_entity;
private readonly MetaverseBrokerDbContext m_broker_db_context;
private readonly PlanetItemExchangeOrderRepo m_planet_item_exchange_repo;
private readonly PlanetItemExchangeOrderAmountTotalLimitRepo m_planet_item_exchange_order_amount_total_limit;
private readonly PlanetItemExchangeOrderAmountUserLimitRepo m_planet_item_exchange_order_amount_user_limit;
private readonly DynamoDbClient m_dynamo_db_client;
private readonly EchoSystemService m_echo_system_service;
private readonly ILogger<CurrencyExchangeCreationStrategy>? m_logger;
public CurrencyExchangeCreationStrategy(
IServerLogic serverLogic,
PlanetUserEntity planetUserEntity,
MetaverseBrokerDbContext brokerDbContext,
PlanetItemExchangeOrderRepo planetItemExchangeRepo,
PlanetItemExchangeOrderAmountTotalLimitRepo planetItemExchangeOrderAmountTotalLimit,
PlanetItemExchangeOrderAmountUserLimitRepo planetItemExchangeOrderAmountUserLimit,
EchoSystemService echoSystemService,
ILogger<CurrencyExchangeCreationStrategy>? logger = null!)
{
m_planet_user_entity = planetUserEntity;
m_broker_db_context = brokerDbContext;
m_planet_item_exchange_repo = planetItemExchangeRepo;
m_planet_item_exchange_order_amount_total_limit = planetItemExchangeOrderAmountTotalLimit;
m_planet_item_exchange_order_amount_user_limit = planetItemExchangeOrderAmountUserLimit;
m_dynamo_db_client = serverLogic.getDynamoDbClient();
m_echo_system_service = echoSystemService;
m_logger = logger;
}
public async Task<(Result, PlanetItemExchangeOrder)> createOrder(
PlanetItemExchangeOrder order,
string planetServerType,
PlanetItemExchangePolicyMetaData exchangePolicy, CancellationToken cancellationToken = default)
{
var exchange_date = DateOnly.FromDateTime(order.CreatedAt.ToUniversalTime());
var exchange_amount = order.ExchangeMetaAmount;
var strategy = m_broker_db_context.Database.CreateExecutionStrategy();
var execute_result = await strategy.ExecuteAsync<Result>(async () =>
{
var transaction_result = new Result();
await using var transaction = await m_broker_db_context.Database.BeginTransactionAsync(cancellationToken);
try
{
var daily_limit_checker = new DailyAmountLimitChecker(
m_planet_item_exchange_order_amount_total_limit,
m_planet_item_exchange_order_amount_user_limit);
var (result, total_limit, user_limit) = await daily_limit_checker.dailyLimitCheck(order, exchangePolicy, cancellationToken);
// 신규 주문 정보 삽입
await m_planet_item_exchange_repo.add(order, cancellationToken);
Guard.Against.resultFail(result);
Guard.Against.isNull(total_limit, ServerErrorCode.RdbError,
()=>"PlanetItemExchangeOrderAmountTotalLimit not found");
Guard.Against.isNull(user_limit, ServerErrorCode.RdbError,
()=>"PlanetItemExchangeOrderAmountUserLimit not found");
var (currency_result, _) = await updateCurrency(exchange_amount, exchangePolicy);
Guard.Against.resultFail(currency_result);
await m_planet_item_exchange_order_amount_total_limit.increaseDailyAmount(total_limit,
exchange_amount, cancellationToken);
await m_planet_item_exchange_order_amount_user_limit.increaseDailyAmount(user_limit,
exchange_amount, cancellationToken);
await transaction.CommitAsync(cancellationToken);
// 사파이어 처리인 경우 에코시스템에 통보
if (string.Equals(exchangePolicy.CaliverseItemId, CurrencyType.Sapphire.ToString(),
StringComparison.OrdinalIgnoreCase))
{
var sapphire_delta = exchange_amount * exchangePolicy.CaliverseItemAmount;
_ = notifyToEchoSystemEvent(planetServerType, sapphire_delta).ConfigureAwait(false);
}
}
catch
{
if (transaction.GetDbTransaction().Connection is not null)
{
await transaction.RollbackAsync(cancellationToken);
}
throw;
}
return transaction_result;
});
return (execute_result, order);
}
private async Task<(Result, long)> updateCurrency(
int exchangeMetaAmount,
PlanetItemExchangePolicyMetaData exchangePolicy)
{
var currency_delta = exchangeMetaAmount * exchangePolicy.CaliverseItemAmount;
CurrencyControlHelper.setDbConnector(m_dynamo_db_client);
var (result, current_sapphire_amount_double) =
await CurrencyControlHelper.spendMoneyByUserGuid(getUserGuid(), CurrencyType.Sapphire, currency_delta);
var current_sapphire_amount = Convert.ToInt64(current_sapphire_amount_double);
return (result, current_sapphire_amount);
}
//===========================================================================================
// 사파이어 처리인 경우 외부에 있는 에코시스템에 이벤트를 통보하여야 한다.
//===========================================================================================
private async Task notifyToEchoSystemEvent(
string planetServerType,
long sapphireDelta)
{
try
{
await m_echo_system_service.createAndSetEventPayload(
accountId: getUserAccountId(),
nickname: getUserNickname(),
userGuid: getUserGuid(),
sapphireDelta,
planetServerType,
CaliumEventType.extra_get.ToString()
);
_ = await m_echo_system_service.processCaliumEvent(m_planet_user_entity);
}
catch (Exception ex)
{
m_logger?.LogError(ex, "Failed to process calium event");
throw;
}
}
private string getUserAccountId() =>
m_planet_user_entity.getEntityAttributeNotNull<AccountAttribute>().AccountId;
private string getUserGuid() =>
m_planet_user_entity.getEntityAttributeNotNull<AccountAttribute>().UserGuid;
private string getUserNickname() =>
m_planet_user_entity.getEntityAttributeNotNull<NicknameAttribute>().Nickname;
}

View File

@@ -0,0 +1,28 @@
namespace BrokerCore.Services;
using Common;
using DbEntity;
using Entity;
using Repository;
// 화폐(Currency) 주문 완료 전략
public class CurrencyOrderCompletionStrategy : IOrderCompletionStrategy
{
private readonly PlanetItemExchangeOrderRepo m_planet_item_exchange_repo;
public CurrencyOrderCompletionStrategy(PlanetItemExchangeOrderRepo planetItemExchangeOrderRepo)
{
m_planet_item_exchange_repo = planetItemExchangeOrderRepo;
}
public async Task<PlanetItemExchangeOrder> completeOrder(PlanetUserEntity planetUserEntity,
PlanetItemExchangeOrder orderCreated,
CancellationToken cancellationToken = default)
{
var (result, order_completed) =
await m_planet_item_exchange_repo.findAndUpdateStatus(orderCreated.OrderId, ExchangeOrderStatus.Completed, cancellationToken);
Guard.Against.resultFail(result);
Guard.Against.isNull(order_completed, ServerErrorCode.InvalidRequest,
()=>"CurrencyOrderCompletionStrategy => Order not found");
return order_completed;
}
}

View File

@@ -0,0 +1,89 @@
namespace BrokerCore.Services;
using Common;
using DbEntity;
using Repository;
using MetaAssets;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
using Repository.Context;
public class ProductExchangeCreationStrategy : IOrderCreationStrategy
{
private readonly MetaverseBrokerDbContext m_broker_db_context;
private readonly PlanetItemExchangeOrderAmountTotalLimitRepo m_planet_item_exchange_order_amount_total_limit;
private readonly PlanetItemExchangeOrderAmountUserLimitRepo m_planet_item_exchange_order_amount_user_limit;
private readonly PlanetItemExchangeOrderRepo m_planet_item_exchange_repo;
public ProductExchangeCreationStrategy(
MetaverseBrokerDbContext brokerDbContext,
PlanetItemExchangeOrderAmountTotalLimitRepo planetItemExchangeOrderAmountTotalLimit,
PlanetItemExchangeOrderAmountUserLimitRepo planetItemExchangeOrderAmountUserLimit,
PlanetItemExchangeOrderRepo planetItemExchangeRepo)
{
m_broker_db_context = brokerDbContext;
m_planet_item_exchange_order_amount_total_limit = planetItemExchangeOrderAmountTotalLimit;
m_planet_item_exchange_order_amount_user_limit = planetItemExchangeOrderAmountUserLimit;
m_planet_item_exchange_repo = planetItemExchangeRepo;
}
public async Task<(Result, PlanetItemExchangeOrder)> createOrder(
PlanetItemExchangeOrder order,
string planetServerType,
PlanetItemExchangePolicyMetaData exchangePolicy,
CancellationToken cancellationToken = default)
{
var exchange_date = DateOnly.FromDateTime(order.CreatedAt.ToUniversalTime());
var strategy = m_broker_db_context.Database.CreateExecutionStrategy();
var execute_result = await strategy.ExecuteAsync<Result>(async () =>
{
Result result = null!;
await using var transaction = await m_broker_db_context.Database.BeginTransactionAsync(cancellationToken);
try
{
var daily_limit_checker = new DailyAmountLimitChecker(
m_planet_item_exchange_order_amount_total_limit,
m_planet_item_exchange_order_amount_user_limit);
(result, var total_limit, var user_limit) = await daily_limit_checker.dailyLimitCheck(order, exchangePolicy, cancellationToken);
// 신규 주문 정보 삽입
await m_planet_item_exchange_repo.add(order, cancellationToken);
Guard.Against.resultFail(result);
Guard.Against.isNull(total_limit, ServerErrorCode.RdbError,
()=>"PlanetItemExchangeOrderAmountTotalLimit not found");
Guard.Against.isNull(user_limit, ServerErrorCode.RdbError,
()=>"PlanetItemExchangeOrderAmountUserLimit not found");
// 신규 주문 정보 삽입
await m_planet_item_exchange_repo.add(order, cancellationToken);
await m_planet_item_exchange_order_amount_total_limit.increaseDailyAmount(total_limit,
order.ExchangeMetaAmount, cancellationToken);
await m_planet_item_exchange_order_amount_user_limit.increaseDailyAmount(user_limit,
order.ExchangeMetaAmount, cancellationToken);
await transaction.CommitAsync(cancellationToken);
}
catch(Exception ex)
{
if (transaction.GetDbTransaction().Connection is not null)
{
await transaction.RollbackAsync(cancellationToken);
}
return new Result
{
ErrorCode = ServerErrorCode.InternalServerError,
ResultString = $"ProductExchangeCreationStrategy Transaction Error => {ex.Message}"
};
}
return result;
});
return (execute_result, order);
}
}

View File

@@ -0,0 +1,152 @@
using ServerCore;
using ServerBase;
using ServerCommon;
namespace BrokerCore.Services;
using BrokerBusinessLog;
using Common;
using DbEntity;
using Entity;
using Entity.Actions;
using MetaAssets;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
using Repository;
using Repository.Context;
// 아이템 주문 완료 전략
public class ProductOrderCompletionStrategy : IOrderCompletionStrategy
{
private PlanetUserEntity m_planet_user_entity;
private readonly BrokerMetaTableRef m_meta_table_ref;
private readonly IServerLogic m_server_logic;
private readonly MetaverseBrokerDbContext m_broker_db_context;
private readonly PlanetItemExchangeOrderRepo m_planet_item_exchange_repo;
public ProductOrderCompletionStrategy(
BrokerMetaTableRef metaTableRef,
IServerLogic serverLogic,
MetaverseBrokerDbContext brokerDbContext,
PlanetItemExchangeOrderRepo planetItemExchangeRepo
)
{
m_meta_table_ref = metaTableRef;
m_server_logic = serverLogic;
m_broker_db_context = brokerDbContext;
m_planet_item_exchange_repo = planetItemExchangeRepo;
}
public async Task<PlanetItemExchangeOrder> completeOrder(
PlanetUserEntity planetUserEntity,
PlanetItemExchangeOrder orderCreated,
CancellationToken cancellationToken = default)
{
m_planet_user_entity = planetUserEntity;
// 메타데이터 조회
var exchange_policy = getExchangePolicyMeta(orderCreated.ExchangeMetaId);
var product_meta = getProductMeta(exchange_policy.CaliverseItemId);
var mail_meta = getSystemMailMeta(product_meta.SystemMail_First);
// 메일 발송 처리
var broker_mail = new BrokerMailEntity(m_planet_user_entity, m_server_logic);
var init_result = await broker_mail.onInit();
Guard.Against.resultFail(init_result, init_result.ErrorCode, ()=>"BrokerMail onInit error");
var mail_send_action = broker_mail.getEntityActionNotNull<BrokerMailSendAction>();
var mail_option = mail_send_action.createSystemSendMailOptionByMeta(product_meta, mail_meta,
m_planet_user_entity.UserGuid,
m_planet_user_entity.Nickname, orderCreated.ExchangeMetaAmount);
//==============================================================================================
// rdb 트랜잭션 시작
// 주문 완료 처리 임시
// 메일 발송
// 메일 발송 완료 시 주문 완료 처리 커밋
// TODO: 재시도 전략 연구?
//==============================================================================================
PlanetItemExchangeOrder order_completed_result_object = null!;
var strategy = m_broker_db_context.Database.CreateExecutionStrategy();
var transaction_result = await strategy.ExecuteAsync(async () =>
{
await using var transaction =
await m_broker_db_context.Database.BeginTransactionAsync(System.Data.IsolationLevel.RepeatableRead,
cancellationToken);
var (order_update_result, order_completed) = await m_planet_item_exchange_repo.findAndUpdateStatus(
orderCreated.OrderId, ExchangeOrderStatus.Completed,
cancellationToken);
if (order_update_result.isFail())
{
await transaction.RollbackAsync(cancellationToken);
return order_update_result;
}
try
{
var mail_send_result = await mail_send_action.sendMail(mail_option,
async () => await transaction.CommitAsync(cancellationToken),
async () => await transaction.RollbackAsync(cancellationToken)
);
if (mail_send_result.isFail())
{
await transaction.RollbackAsync(cancellationToken);
return mail_send_result;
}
else if (order_completed is not null)
{
order_completed_result_object = order_completed;
}
}
catch (Exception ex)
{
if (transaction.GetDbTransaction().Connection is not null)
{
await transaction.RollbackAsync(cancellationToken);
}
return new Result
{
ErrorCode = ServerErrorCode.InternalServerError,
ResultString = $"ProductOrderCompletionStrategy Transaction Error => {ex.Message}"
};
}
return new Result();
});
Guard.Against.resultFail(transaction_result);
return order_completed_result_object;
}
private PlanetItemExchangePolicyMetaData getExchangePolicyMeta(string exchangeMetaId)
{
m_meta_table_ref.MetaTable.PlanetItemExchangePolicyMetaTable.PlanetItemExchangePolicyDataListbyID.TryGetValue(
exchangeMetaId, out var policy_meta);
Guard.Against.isNull(policy_meta, ServerErrorCode.MetaIdInvalid,
()=>"planet_item_exchange_policy_meta not found");
return policy_meta;
}
private ProductMetaData getProductMeta(string productMetaIdString)
{
var product_meta_id = Convert.ToInt32(productMetaIdString);
m_meta_table_ref.MetaTable.ProductMetaTable.ProductMetaDataListbyId.TryGetValue(product_meta_id,
out var product_meta);
Guard.Against.isNull(product_meta, ServerErrorCode.MetaIdInvalid, ()=>"product meta not found");
return product_meta;
}
private SystemMailMetaData getSystemMailMeta(string systemMailDataId)
{
m_meta_table_ref.MetaTable.SystemMailMetaTable.SystemMailMetaDataListbyKey.TryGetValue(systemMailDataId,
out var mail_data);
Guard.Against.isNull(mail_data, ServerErrorCode.MetaIdInvalid, ()=>"system_mail_meta not found");
return mail_data;
}
}

View File

@@ -0,0 +1,212 @@
using System.IdentityModel.Tokens.Jwt;
using System.Text;
using Microsoft.IdentityModel.Tokens;
using ServerCore; using ServerBase;
using ServerCommon;
namespace BrokerCore.Services;
using BrokerBusinessLog;
using Repository;
using Common;
using Entity;
public class UserAuthService
{
private readonly PlanetUserEntity m_planet_user_entity;
private readonly SsoAccountRepo m_sso_account_repo;
private readonly IServerLogic m_server_logic;
public string AccountId
=> m_planet_user_entity.getEntityAttributeNotNull<AccountAttribute>().AccountId;
// public string Email { get; set; } = string.Empty;
public string UserGuid
=> m_planet_user_entity.getEntityAttributeNotNull<AccountAttribute>().UserGuid;
public string Nickname
=> m_planet_user_entity.getEntityAttributeNotNull<NicknameAttribute>().Nickname;
public IServerLogic ServerLogic => m_server_logic;
public PlanetUserEntity PlanetUserEntity => m_planet_user_entity;
private ServerConfigMetaverseBroker? getServerConfig()
{
return m_server_logic.getServerConfig() as ServerConfigMetaverseBroker;
}
public UserAuthService(SsoAccountRepo ssoAccountRepo, IServerLogic serverLogic)
{
m_sso_account_repo = ssoAccountRepo;
m_server_logic = serverLogic;
m_planet_user_entity = new PlanetUserEntity(serverLogic);
m_planet_user_entity.onInit().Wait();
}
public async Task<Result> authByWebPortalToken(string webPortalToken, string? planetId = null)
{
if (planetId is not null)
{
m_planet_user_entity.setPlanetId(planetId);
}
var m_sso_jwt_secret_key = getServerConfig()?.SsoAccountAuthJwtSecretKey ?? string.Empty;
Guard.Against.isNullOrEmptyOrWhiteSpace(m_sso_jwt_secret_key, ServerErrorCode.InternalServerError,
()=>"SSO JWT secret key is required in server config");
var jwt_result = verifySsoAccountAuthJwt(webPortalToken,
m_sso_jwt_secret_key,
out var account_id, out var account_type, out var access_token);
if (jwt_result.isFail())
{
var error_msg = $"Broker Api Failed to Auth From Jwt !!! : {jwt_result.toBasicString()}, {webPortalToken}";
Log.getLogger().error(error_msg);
return jwt_result;
}
var result = await authByAccount(account_id);
if (result.isSuccess())
{
if (planetId is not null)
{
// BrokerBusinessLogger.collectLog(m_planet_user_entity, LogActionType.BrokerApiUserLogin, new UserAuthLogInfo
// {
// AccountId = account_id,
// UserGuid = UserGuid,
// Nickname = Nickname,
// });
BusinessLogger.collectLog(m_planet_user_entity,
new PlanetUserAuthBusinessLog(
new PlanetUserAuthLogData { AccountId = account_id, UserGuid = UserGuid, Nickname = Nickname, },
LogActionType.BrokerApiUserLogin));
}
}
return result;
}
public async Task<Result> authFromEmail(string email)
{
var (result, sso_account) = await m_sso_account_repo.findOneByEmail(email);
Guard.Against.resultFail(result);
Guard.Against.isNull(sso_account, ServerErrorCode.AccountNotFound, ()=>"sso account not found");
result = await authByAccount(sso_account.Id.ToString());
Guard.Against.resultFail(result);
Guard.Against.isNull(sso_account, ServerErrorCode.UserNotFound, ()=>"user not found");
return result;
}
// todo: JwtParser를 사용해서 수정할 것
private Result verifySsoAccountAuthJwt(string ssoJwt
, string ssoJwtSecret
, out string id, out AccountType accountType, out UInt64 accessToken)
{
id = string.Empty;
accountType = AccountType.None;
accessToken = 0;
var result = new Result();
var err_msg = string.Empty;
try
{
var token_handler = new JwtSecurityTokenHandler();
var validation_parameters = getValidationUserTokenParameters(ssoJwtSecret);
var claim = token_handler.ValidateToken(ssoJwt, validation_parameters, out var validated_token);
// account id
id = claim.Claims.FirstOrDefault(x => x.Type == "id")?.Value ?? string.Empty;
// account type
accountType = claim.Claims.FirstOrDefault(x => x.Type == "accountType")?.Value
?.convertEnumTypeAndValueStringToEnum(AccountType.None) ?? AccountType.None;
// access token
var access_token_string = claim.Claims.FirstOrDefault(x => x.Type == "accessToken")?.Value;
accessToken = Convert.ToUInt64(access_token_string);
}
catch (SecurityTokenExpiredException e)
{
err_msg = $"Expired WebAuthJWT !!! : SecurityTokenExpiredException:{e}";
result.setFail(ServerErrorCode.ExpiredUserJwt, err_msg);
}
catch (SecurityTokenException e)
{
err_msg = $"Failed to verify WebAuthJWT !!! : SecurityTokenException:{e}";
result.setFail(ServerErrorCode.InvalidUserJwt, err_msg);
}
catch (Exception e)
{
err_msg = $"Exception !!!, WebAuthJWT !!! : Exception:{e}";
result.setFail(ServerErrorCode.InvalidUserJwt, err_msg);
}
if (result.isFail())
{
result = verifyForTestUserToken(ssoJwt, ssoJwtSecret, out id, out accountType, out accessToken);
}
Guard.Against.resultFail(result);
return result;
}
// 치트를 허용하도록 처리함
private Result verifyForTestUserToken(string ssoJwt
, string ssoJwtSecret
, out string id, out AccountType accountType, out UInt64 accessToken)
{
var splits = ssoJwt.Split('|');
if (splits.Length < 1 || splits[1] != ssoJwtSecret)
{
id = string.Empty;
accountType = AccountType.None;
accessToken = 0;
return new Result
{
ErrorCode = ServerErrorCode.InvalidUserJwt, ResultString = "Failed to verify WebAuthJWT"
};
}
id = splits[0];
accountType = AccountType.None;
try
{
accessToken = Convert.ToUInt64(id);
}
catch (Exception e)
{
accessToken = 0;
}
return new Result();
}
private static TokenValidationParameters getValidationUserTokenParameters(string sdsoAccountAuthJwtSecretKey)
{
return new TokenValidationParameters()
{
ValidateLifetime = true,
ValidateAudience = false,
ValidateIssuer = false,
ValidIssuer = "",
ValidAudience = "",
IssuerSigningKey =
new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(
sdsoAccountAuthJwtSecretKey))
};
}
public async Task<Result> authByAccount(string accountId)
{
var action = m_planet_user_entity.getEntityActionNotNull<UserAuthAction>();
return await action.findAndSetAllAttributeByAccountId(accountId);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\user\.nuget\packages\</NuGetPackageFolders>
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.10.1</NuGetToolVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<SourceRoot Include="C:\Users\user\.nuget\packages\" />
</ItemGroup>
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<Import Project="$(NuGetPackageRoot)microsoft.extensions.configuration.usersecrets\8.0.0\buildTransitive\net6.0\Microsoft.Extensions.Configuration.UserSecrets.props" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.configuration.usersecrets\8.0.0\buildTransitive\net6.0\Microsoft.Extensions.Configuration.UserSecrets.props')" />
<Import Project="$(NuGetPackageRoot)microsoft.entityframeworkcore\8.0.2\buildTransitive\net8.0\Microsoft.EntityFrameworkCore.props" Condition="Exists('$(NuGetPackageRoot)microsoft.entityframeworkcore\8.0.2\buildTransitive\net8.0\Microsoft.EntityFrameworkCore.props')" />
<Import Project="$(NuGetPackageRoot)microsoft.entityframeworkcore.design\8.0.2\build\net8.0\Microsoft.EntityFrameworkCore.Design.props" Condition="Exists('$(NuGetPackageRoot)microsoft.entityframeworkcore.design\8.0.2\build\net8.0\Microsoft.EntityFrameworkCore.Design.props')" />
</ImportGroup>
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<PkgMongoDB_Analyzer Condition=" '$(PkgMongoDB_Analyzer)' == '' ">C:\Users\user\.nuget\packages\mongodb.analyzer\1.5.0</PkgMongoDB_Analyzer>
<PkgAWSSDK_Core Condition=" '$(PkgAWSSDK_Core)' == '' ">C:\Users\user\.nuget\packages\awssdk.core\3.7.402.39</PkgAWSSDK_Core>
<PkgAWSSDK_S3 Condition=" '$(PkgAWSSDK_S3)' == '' ">C:\Users\user\.nuget\packages\awssdk.s3\3.7.416.9</PkgAWSSDK_S3>
<PkgAWSSDK_OpenSearchService Condition=" '$(PkgAWSSDK_OpenSearchService)' == '' ">C:\Users\user\.nuget\packages\awssdk.opensearchservice\3.7.404.75</PkgAWSSDK_OpenSearchService>
<PkgAWSSDK_DynamoDBv2 Condition=" '$(PkgAWSSDK_DynamoDBv2)' == '' ">C:\Users\user\.nuget\packages\awssdk.dynamodbv2\3.7.406.21</PkgAWSSDK_DynamoDBv2>
<PkgAWSSDK_CloudWatchLogs Condition=" '$(PkgAWSSDK_CloudWatchLogs)' == '' ">C:\Users\user\.nuget\packages\awssdk.cloudwatchlogs\3.7.305.15</PkgAWSSDK_CloudWatchLogs>
<PkgAWSSDK_EC2 Condition=" '$(PkgAWSSDK_EC2)' == '' ">C:\Users\user\.nuget\packages\awssdk.ec2\3.7.330.4</PkgAWSSDK_EC2>
<PkgMicrosoft_CodeAnalysis_Analyzers Condition=" '$(PkgMicrosoft_CodeAnalysis_Analyzers)' == '' ">C:\Users\user\.nuget\packages\microsoft.codeanalysis.analyzers\3.3.3</PkgMicrosoft_CodeAnalysis_Analyzers>
<PkgMicrosoft_EntityFrameworkCore_Tools Condition=" '$(PkgMicrosoft_EntityFrameworkCore_Tools)' == '' ">C:\Users\user\.nuget\packages\microsoft.entityframeworkcore.tools\8.0.2</PkgMicrosoft_EntityFrameworkCore_Tools>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<Import Project="$(NuGetPackageRoot)system.text.json\8.0.0\buildTransitive\net6.0\System.Text.Json.targets" Condition="Exists('$(NuGetPackageRoot)system.text.json\8.0.0\buildTransitive\net6.0\System.Text.Json.targets')" />
<Import Project="$(NuGetPackageRoot)microsoft.extensions.configuration.usersecrets\8.0.0\buildTransitive\net6.0\Microsoft.Extensions.Configuration.UserSecrets.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.configuration.usersecrets\8.0.0\buildTransitive\net6.0\Microsoft.Extensions.Configuration.UserSecrets.targets')" />
<Import Project="$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\8.0.2\buildTransitive\net6.0\Microsoft.Extensions.Logging.Abstractions.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\8.0.2\buildTransitive\net6.0\Microsoft.Extensions.Logging.Abstractions.targets')" />
<Import Project="$(NuGetPackageRoot)microsoft.extensions.options\8.0.0\buildTransitive\net6.0\Microsoft.Extensions.Options.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.options\8.0.0\buildTransitive\net6.0\Microsoft.Extensions.Options.targets')" />
<Import Project="$(NuGetPackageRoot)microsoft.extensions.configuration.binder\8.0.0\buildTransitive\netstandard2.0\Microsoft.Extensions.Configuration.Binder.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.configuration.binder\8.0.0\buildTransitive\netstandard2.0\Microsoft.Extensions.Configuration.Binder.targets')" />
</ImportGroup>
</Project>

View File

@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")]

View File

@@ -0,0 +1,13 @@
is_global = true
build_property.TargetFramework = net8.0
build_property.TargetPlatformMinVersion =
build_property.UsingMicrosoftNETSdkWeb =
build_property.ProjectTypeGuids =
build_property.InvariantGlobalization =
build_property.PlatformNeutralAssembly =
build_property.EnforceExtendedAnalyzerRules =
build_property._SupportedPlatformList = Linux,macOS,Windows
build_property.RootNamespace = BrokerApiCore
build_property.ProjectDir = D:\03.SVN\03.caliverse\Server\CaliServer\BrokerApiCore\
build_property.EnableComHosting =
build_property.EnableGeneratedComInterfaceComImportInterop =

View File

@@ -0,0 +1,8 @@
// <auto-generated/>
global using global::System;
global using global::System.Collections.Generic;
global using global::System.IO;
global using global::System.Linq;
global using global::System.Net.Http;
global using global::System.Threading;
global using global::System.Threading.Tasks;

Binary file not shown.

View File

@@ -0,0 +1 @@
31f453acdb007aaf7d2517378d8093b646c277a4a6b5f1ed8ec5c16415ffb929

Some files were not shown because too many files have changed in this diff Show More