using System; using Microsoft.EntityFrameworkCore.Migrations; #nullable disable namespace Infrastructure.Migrations.AppDb { /// public partial class AddDeveloperPortalSchema : Migration { /// protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.AlterColumn( name: "Price", table: "Product", type: "int", nullable: false, comment: "판매가 (KRW)", oldClrType: typeof(int), oldType: "int", oldComment: "정가 (P)"); migrationBuilder.AlterColumn( name: "DiscountValue", table: "Product", type: "int", nullable: false, oldClrType: typeof(int), oldType: "int", oldComment: "할인 값 (Percent: 0..99, Amount: 0..Price)"); migrationBuilder.AlterColumn( name: "DiscountType", table: "Product", type: "tinyint", nullable: false, oldClrType: typeof(byte), oldType: "tinyint", oldComment: "할인 모드 (0=None, 1=Percent, 2=Amount)"); migrationBuilder.CreateTable( name: "ApiApplication", columns: table => new { ID = table.Column(type: "int", nullable: false) .Annotation("SqlServer:Identity", "1, 1"), OwnerMemberID = table.Column(type: "int", nullable: false), Name = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: false), Description = table.Column(type: "nvarchar(500)", maxLength: 500, nullable: true), HomepageUrl = table.Column(type: "nvarchar(500)", maxLength: 500, nullable: true), LogoPath = table.Column(type: "nvarchar(500)", maxLength: 500, nullable: true), Status = table.Column(type: "int", nullable: false), CreatedAt = table.Column(type: "datetime2", nullable: false), UpdatedAt = table.Column(type: "datetime2", nullable: true), ApprovedAt = table.Column(type: "datetime2", nullable: true), SuspendedAt = table.Column(type: "datetime2", nullable: true) }, constraints: table => { table.PrimaryKey("PK_ApiApplication", x => x.ID); table.ForeignKey( name: "FK_ApiApplication_Member_OwnerMemberID", column: x => x.OwnerMemberID, principalTable: "Member", principalColumn: "ID", onDelete: ReferentialAction.Cascade); }, comment: "개발자 API 앱"); migrationBuilder.CreateTable( name: "ApiPersonalAccessToken", columns: table => new { ID = table.Column(type: "bigint", nullable: false) .Annotation("SqlServer:Identity", "1, 1"), OwnerMemberID = table.Column(type: "int", nullable: false), Name = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: false), TokenHash = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), TokenHint = table.Column(type: "nvarchar(4)", maxLength: 4, nullable: false), ScopesCsv = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: false), CreatedAt = table.Column(type: "datetime2", nullable: false), ExpiresAt = table.Column(type: "datetime2", nullable: true), LastUsedAt = table.Column(type: "datetime2", nullable: true), RevokedAt = table.Column(type: "datetime2", nullable: true) }, constraints: table => { table.PrimaryKey("PK_ApiPersonalAccessToken", x => x.ID); table.ForeignKey( name: "FK_ApiPersonalAccessToken_Member_OwnerMemberID", column: x => x.OwnerMemberID, principalTable: "Member", principalColumn: "ID", onDelete: ReferentialAction.Cascade); }, comment: "Personal Access Token (PAT)"); migrationBuilder.CreateTable( name: "ApiRequestLog", columns: table => new { ID = table.Column(type: "bigint", nullable: false) .Annotation("SqlServer:Identity", "1, 1"), ApplicationID = table.Column(type: "int", nullable: true), PatID = table.Column(type: "bigint", nullable: true), Endpoint = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: false), Method = table.Column(type: "nvarchar(10)", maxLength: 10, nullable: false), StatusCode = table.Column(type: "int", nullable: false), ResponseMs = table.Column(type: "int", nullable: false), IpAddress = table.Column(type: "nvarchar(45)", maxLength: 45, nullable: true), RequestedAt = table.Column(type: "datetime2", nullable: false) }, constraints: table => { table.PrimaryKey("PK_ApiRequestLog", x => x.ID); }, comment: "공개 API 호출 로그"); migrationBuilder.CreateTable( name: "ApiApplicationScope", columns: table => new { ID = table.Column(type: "int", nullable: false) .Annotation("SqlServer:Identity", "1, 1"), ApplicationID = table.Column(type: "int", nullable: false), Scope = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), CreatedAt = table.Column(type: "datetime2", nullable: false) }, constraints: table => { table.PrimaryKey("PK_ApiApplicationScope", x => x.ID); table.ForeignKey( name: "FK_ApiApplicationScope_ApiApplication_ApplicationID", column: x => x.ApplicationID, principalTable: "ApiApplication", principalColumn: "ID", onDelete: ReferentialAction.Cascade); }, comment: "앱이 요청한 scope 목록"); migrationBuilder.CreateTable( name: "ApiCredential", columns: table => new { ID = table.Column(type: "int", nullable: false) .Annotation("SqlServer:Identity", "1, 1"), ApplicationID = table.Column(type: "int", nullable: false), ClientID = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), SecretHash = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), SecretHint = table.Column(type: "nvarchar(4)", maxLength: 4, nullable: false), Status = table.Column(type: "int", nullable: false), CreatedAt = table.Column(type: "datetime2", nullable: false), LastUsedAt = table.Column(type: "datetime2", nullable: true), RevokedAt = table.Column(type: "datetime2", nullable: true) }, constraints: table => { table.PrimaryKey("PK_ApiCredential", x => x.ID); table.ForeignKey( name: "FK_ApiCredential_ApiApplication_ApplicationID", column: x => x.ApplicationID, principalTable: "ApiApplication", principalColumn: "ID", onDelete: ReferentialAction.Cascade); }, comment: "OAuth2 Client Credentials"); migrationBuilder.CreateTable( name: "ApiRateLimit", columns: table => new { ID = table.Column(type: "int", nullable: false) .Annotation("SqlServer:Identity", "1, 1"), ApplicationID = table.Column(type: "int", nullable: false), LimitPerMinute = table.Column(type: "int", nullable: false), CreatedAt = table.Column(type: "datetime2", nullable: false), UpdatedAt = table.Column(type: "datetime2", nullable: false) }, constraints: table => { table.PrimaryKey("PK_ApiRateLimit", x => x.ID); table.ForeignKey( name: "FK_ApiRateLimit_ApiApplication_ApplicationID", column: x => x.ApplicationID, principalTable: "ApiApplication", principalColumn: "ID", onDelete: ReferentialAction.Cascade); }, comment: "앱별 Rate Limit override"); migrationBuilder.CreateIndex( name: "IX_ApiApplication_OwnerMemberID", table: "ApiApplication", column: "OwnerMemberID"); migrationBuilder.CreateIndex( name: "IX_ApiApplication_Status", table: "ApiApplication", column: "Status"); migrationBuilder.CreateIndex( name: "IX_ApiApplicationScope_ApplicationID_Scope", table: "ApiApplicationScope", columns: new[] { "ApplicationID", "Scope" }, unique: true); migrationBuilder.CreateIndex( name: "IX_ApiCredential_ApplicationID", table: "ApiCredential", column: "ApplicationID"); migrationBuilder.CreateIndex( name: "IX_ApiCredential_ClientID", table: "ApiCredential", column: "ClientID", unique: true); migrationBuilder.CreateIndex( name: "IX_ApiPersonalAccessToken_OwnerMemberID", table: "ApiPersonalAccessToken", column: "OwnerMemberID"); migrationBuilder.CreateIndex( name: "IX_ApiPersonalAccessToken_TokenHash", table: "ApiPersonalAccessToken", column: "TokenHash", unique: true); migrationBuilder.CreateIndex( name: "IX_ApiRateLimit_ApplicationID", table: "ApiRateLimit", column: "ApplicationID", unique: true); migrationBuilder.CreateIndex( name: "IX_ApiRequestLog_ApplicationID", table: "ApiRequestLog", column: "ApplicationID"); migrationBuilder.CreateIndex( name: "IX_ApiRequestLog_PatID", table: "ApiRequestLog", column: "PatID"); migrationBuilder.CreateIndex( name: "IX_ApiRequestLog_RequestedAt", table: "ApiRequestLog", column: "RequestedAt"); } /// protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.DropTable( name: "ApiApplicationScope"); migrationBuilder.DropTable( name: "ApiCredential"); migrationBuilder.DropTable( name: "ApiPersonalAccessToken"); migrationBuilder.DropTable( name: "ApiRateLimit"); migrationBuilder.DropTable( name: "ApiRequestLog"); migrationBuilder.DropTable( name: "ApiApplication"); migrationBuilder.AlterColumn( name: "Price", table: "Product", type: "int", nullable: false, comment: "정가 (P)", oldClrType: typeof(int), oldType: "int", oldComment: "판매가 (KRW)"); migrationBuilder.AlterColumn( name: "DiscountValue", table: "Product", type: "int", nullable: false, comment: "할인 값 (Percent: 0..99, Amount: 0..Price)", oldClrType: typeof(int), oldType: "int"); migrationBuilder.AlterColumn( name: "DiscountType", table: "Product", type: "tinyint", nullable: false, comment: "할인 모드 (0=None, 1=Percent, 2=Amount)", oldClrType: typeof(byte), oldType: "tinyint"); } } }