using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Infrastructure.Migrations.AppDb
{
///
public partial class AddConsumableItemsAndProfileCooldown : Migration
{
///
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn(
name: "GameID",
table: "Product",
type: "int",
nullable: true,
comment: "게임 ID (선택 — null=플랫폼 직접판매)",
oldClrType: typeof(int),
oldType: "int");
migrationBuilder.AddColumn(
name: "DurationDays",
table: "Product",
type: "int",
nullable: false,
defaultValue: 0,
comment: "소모품 효과 지속일 (0=즉시소모)");
migrationBuilder.AddColumn(
name: "ItemKind",
table: "Product",
type: "tinyint",
nullable: true,
comment: "소모품 종류 (null=일반상품, 5~11=소모품)");
migrationBuilder.AddColumn(
name: "LastThumbChangedAt",
table: "Member",
type: "datetime2",
nullable: true);
migrationBuilder.AddColumn(
name: "Account_ChangeThumbDay",
table: "Config",
type: "int",
nullable: true,
comment: "프로필 이미지 갱신 주기(일)");
migrationBuilder.CreateTable(
name: "MemberItem",
columns: table => new
{
ID = table.Column(type: "int", nullable: false, comment: "PK")
.Annotation("SqlServer:Identity", "1, 1"),
MemberID = table.Column(type: "int", nullable: false, comment: "회원 ID"),
ProductID = table.Column(type: "int", nullable: false, comment: "상품 ID"),
OrderItemID = table.Column(type: "int", nullable: false, comment: "발급 근거 주문항목 ID"),
Kind = table.Column(type: "tinyint", nullable: false, comment: "아이템 종류 (5~11)"),
DurationDays = table.Column(type: "int", nullable: false, defaultValue: 0, comment: "효과 지속일 (0=즉시소모)"),
AcquiredAt = table.Column(type: "datetime2", nullable: false, comment: "획득 일시"),
UsedAt = table.Column(type: "datetime2", nullable: true, comment: "소모/활성 일시 (null=미사용)"),
RevokedAt = table.Column(type: "datetime2", nullable: true, comment: "회수 일시 (환불)"),
RowVersion = table.Column(type: "rowversion", rowVersion: true, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_MemberItem", x => x.ID);
table.ForeignKey(
name: "FK_MemberItem_Member_MemberID",
column: x => x.MemberID,
principalTable: "Member",
principalColumn: "ID",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_MemberItem_Product_ProductID",
column: x => x.ProductID,
principalTable: "Product",
principalColumn: "ID",
onDelete: ReferentialAction.Restrict);
},
comment: "계정 귀속 소모품 아이템");
migrationBuilder.CreateTable(
name: "MemberItemUsageLog",
columns: table => new
{
ID = table.Column(type: "int", nullable: false, comment: "PK")
.Annotation("SqlServer:Identity", "1, 1"),
MemberID = table.Column(type: "int", nullable: false, comment: "회원 ID"),
MemberItemID = table.Column(type: "int", nullable: false, comment: "MemberItem ID"),
ProductID = table.Column(type: "int", nullable: false, comment: "상품 ID"),
Kind = table.Column(type: "tinyint", nullable: false, comment: "아이템 종류"),
Action = table.Column(type: "tinyint", nullable: false, comment: "액션 (1=Used, 2=Revoked)"),
Detail = table.Column(type: "nvarchar(300)", maxLength: 300, nullable: true, comment: "결과 요약"),
CreatedAt = table.Column(type: "datetime2", nullable: false, comment: "등록 일시")
},
constraints: table =>
{
table.PrimaryKey("PK_MemberItemUsageLog", x => x.ID);
},
comment: "소모품 아이템 사용/회수 로그");
migrationBuilder.CreateTable(
name: "MemberThumbChangeLog",
columns: table => new
{
ID = table.Column(type: "int", nullable: false, comment: "PK")
.Annotation("SqlServer:Identity", "1, 1"),
MemberID = table.Column(type: "int", nullable: false, comment: "회원 ID"),
BeforeThumb = table.Column(type: "nvarchar(500)", maxLength: 500, nullable: true, comment: "이전 이미지"),
AfterThumb = table.Column(type: "nvarchar(500)", maxLength: 500, nullable: true, comment: "바꾼 이미지"),
Referer = table.Column(type: "nvarchar(max)", nullable: true, comment: "이전 페이지 주소"),
IpAddress = table.Column(type: "nvarchar(45)", maxLength: 45, nullable: true, comment: "IP Address (IPv6 호환)"),
UserAgent = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true, comment: "User Agent"),
CreatedAt = table.Column(type: "datetime2", nullable: false, comment: "등록 일시")
},
constraints: table =>
{
table.PrimaryKey("PK_MemberThumbChangeLog", x => x.ID);
table.ForeignKey(
name: "FK_MemberThumbChangeLog_Member_MemberID",
column: x => x.MemberID,
principalTable: "Member",
principalColumn: "ID",
onDelete: ReferentialAction.Cascade);
},
comment: "프로필 이미지 변경 내역");
migrationBuilder.CreateIndex(
name: "IX_Product_ItemKind_IsActive",
table: "Product",
columns: new[] { "ItemKind", "IsActive" });
migrationBuilder.CreateIndex(
name: "IX_MemberItem_MemberID_Kind_UsedAt",
table: "MemberItem",
columns: new[] { "MemberID", "Kind", "UsedAt" });
migrationBuilder.CreateIndex(
name: "IX_MemberItem_OrderItemID",
table: "MemberItem",
column: "OrderItemID");
migrationBuilder.CreateIndex(
name: "IX_MemberItem_ProductID",
table: "MemberItem",
column: "ProductID");
migrationBuilder.CreateIndex(
name: "IX_MemberItemUsageLog_MemberID_CreatedAt",
table: "MemberItemUsageLog",
columns: new[] { "MemberID", "CreatedAt" });
migrationBuilder.CreateIndex(
name: "IX_MemberThumbChangeLog_MemberID",
table: "MemberThumbChangeLog",
column: "MemberID");
// 기존 Config 싱글턴에 프로필(닉네임·한마디·이미지) 90일 쿨다운 활성화 — Wave 3 P3 결정 #3.
// Name/Intro 는 미설정(NULL)일 때만 90 으로, Thumb 는 신규 컬럼이라 전부 90 으로 채운다.
migrationBuilder.Sql(@"
UPDATE [Config]
SET [Account_ChangeNameDay] = COALESCE([Account_ChangeNameDay], 90),
[Account_ChangeIntroDay] = COALESCE([Account_ChangeIntroDay], 90),
[Account_ChangeThumbDay] = 90
WHERE [Account_ChangeThumbDay] IS NULL;");
}
///
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "MemberItem");
migrationBuilder.DropTable(
name: "MemberItemUsageLog");
migrationBuilder.DropTable(
name: "MemberThumbChangeLog");
migrationBuilder.DropIndex(
name: "IX_Product_ItemKind_IsActive",
table: "Product");
migrationBuilder.DropColumn(
name: "DurationDays",
table: "Product");
migrationBuilder.DropColumn(
name: "ItemKind",
table: "Product");
migrationBuilder.DropColumn(
name: "LastThumbChangedAt",
table: "Member");
migrationBuilder.DropColumn(
name: "Account_ChangeThumbDay",
table: "Config");
migrationBuilder.AlterColumn(
name: "GameID",
table: "Product",
type: "int",
nullable: false,
defaultValue: 0,
comment: "게임 ID (필수)",
oldClrType: typeof(int),
oldType: "int",
oldNullable: true,
oldComment: "게임 ID (선택 — null=플랫폼 직접판매)");
}
}
}