littleshop/LittleShop/Migrations/20250922025753_AddProductMultiBuysTable.cs
SysAdmin 622bdcf111 🔒 SECURITY: Emergency fixes and hardening
EMERGENCY FIXES:
 DELETE MockSilverPayService.cs - removed fake payment system
 REMOVE mock service registration - no fake payments possible
 GENERATE new JWT secret - replaced hardcoded key
 FIX HttpClient disposal - proper resource management

SECURITY HARDENING:
 ADD production guards - prevent mock services in production
 CREATE environment configs - separate dev/prod settings
 ADD config validation - fail fast on misconfiguration

IMPACT:
- Mock payment system completely eliminated
- JWT authentication now uses secure keys
- Production deployment now validated on startup
- Resource leaks fixed in TeleBot currency API

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-22 05:45:49 +01:00

1025 lines
52 KiB
C#

using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace LittleShop.Migrations
{
/// <inheritdoc />
public partial class AddProductMultiBuysTable : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Bots",
columns: table => new
{
Id = table.Column<Guid>(type: "TEXT", nullable: false),
BotKey = table.Column<string>(type: "TEXT", maxLength: 256, nullable: false),
Name = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
Description = table.Column<string>(type: "TEXT", maxLength: 500, nullable: false),
Type = table.Column<int>(type: "INTEGER", nullable: false),
Status = table.Column<int>(type: "INTEGER", nullable: false),
Settings = table.Column<string>(type: "TEXT", nullable: false),
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
LastSeenAt = table.Column<DateTime>(type: "TEXT", nullable: true),
LastConfigSyncAt = table.Column<DateTime>(type: "TEXT", nullable: true),
IsActive = table.Column<bool>(type: "INTEGER", nullable: false),
Version = table.Column<string>(type: "TEXT", maxLength: 50, nullable: false),
IpAddress = table.Column<string>(type: "TEXT", maxLength: 50, nullable: false),
PlatformUsername = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
PlatformDisplayName = table.Column<string>(type: "TEXT", maxLength: 200, nullable: false),
PlatformId = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
PersonalityName = table.Column<string>(type: "TEXT", maxLength: 50, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Bots", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Categories",
columns: table => new
{
Id = table.Column<Guid>(type: "TEXT", nullable: false),
Name = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
Description = table.Column<string>(type: "TEXT", maxLength: 500, nullable: true),
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
UpdatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
IsActive = table.Column<bool>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Categories", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Customers",
columns: table => new
{
Id = table.Column<Guid>(type: "TEXT", nullable: false),
TelegramUserId = table.Column<long>(type: "INTEGER", nullable: false),
TelegramUsername = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
TelegramDisplayName = table.Column<string>(type: "TEXT", maxLength: 200, nullable: false),
TelegramFirstName = table.Column<string>(type: "TEXT", maxLength: 50, nullable: false),
TelegramLastName = table.Column<string>(type: "TEXT", maxLength: 50, nullable: false),
Email = table.Column<string>(type: "TEXT", maxLength: 100, nullable: true),
PhoneNumber = table.Column<string>(type: "TEXT", maxLength: 20, nullable: true),
AllowMarketing = table.Column<bool>(type: "INTEGER", nullable: false),
AllowOrderUpdates = table.Column<bool>(type: "INTEGER", nullable: false),
Language = table.Column<string>(type: "TEXT", maxLength: 10, nullable: false),
Timezone = table.Column<string>(type: "TEXT", maxLength: 10, nullable: false),
TotalOrders = table.Column<int>(type: "INTEGER", nullable: false),
TotalSpent = table.Column<decimal>(type: "decimal(18,2)", nullable: false),
AverageOrderValue = table.Column<decimal>(type: "decimal(18,2)", nullable: false),
FirstOrderDate = table.Column<DateTime>(type: "TEXT", nullable: false),
LastOrderDate = table.Column<DateTime>(type: "TEXT", nullable: false),
CustomerNotes = table.Column<string>(type: "TEXT", maxLength: 2000, nullable: true),
IsBlocked = table.Column<bool>(type: "INTEGER", nullable: false),
BlockReason = table.Column<string>(type: "TEXT", maxLength: 500, nullable: true),
RiskScore = table.Column<int>(type: "INTEGER", nullable: false),
SuccessfulOrders = table.Column<int>(type: "INTEGER", nullable: false),
CancelledOrders = table.Column<int>(type: "INTEGER", nullable: false),
DisputedOrders = table.Column<int>(type: "INTEGER", nullable: false),
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
UpdatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
LastActiveAt = table.Column<DateTime>(type: "TEXT", nullable: false),
DataRetentionDate = table.Column<DateTime>(type: "TEXT", nullable: true),
IsActive = table.Column<bool>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Customers", x => x.Id);
});
migrationBuilder.CreateTable(
name: "ShippingRates",
columns: table => new
{
Id = table.Column<Guid>(type: "TEXT", nullable: false),
Name = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
Description = table.Column<string>(type: "TEXT", maxLength: 500, nullable: true),
Country = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
MinWeight = table.Column<decimal>(type: "decimal(18,2)", nullable: false),
MaxWeight = table.Column<decimal>(type: "decimal(18,2)", nullable: false),
Price = table.Column<decimal>(type: "decimal(18,2)", nullable: false),
MinDeliveryDays = table.Column<int>(type: "INTEGER", nullable: false),
MaxDeliveryDays = table.Column<int>(type: "INTEGER", nullable: false),
IsActive = table.Column<bool>(type: "INTEGER", nullable: false),
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
UpdatedAt = table.Column<DateTime>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ShippingRates", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Users",
columns: table => new
{
Id = table.Column<Guid>(type: "TEXT", nullable: false),
Username = table.Column<string>(type: "TEXT", maxLength: 50, nullable: false),
PasswordHash = table.Column<string>(type: "TEXT", nullable: false),
Email = table.Column<string>(type: "TEXT", maxLength: 100, nullable: true),
Role = table.Column<string>(type: "TEXT", maxLength: 50, nullable: false),
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
IsActive = table.Column<bool>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Users", x => x.Id);
});
migrationBuilder.CreateTable(
name: "BotMetrics",
columns: table => new
{
Id = table.Column<Guid>(type: "TEXT", nullable: false),
BotId = table.Column<Guid>(type: "TEXT", nullable: false),
MetricType = table.Column<int>(type: "INTEGER", nullable: false),
Value = table.Column<decimal>(type: "TEXT", nullable: false),
Metadata = table.Column<string>(type: "TEXT", nullable: false),
RecordedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
Category = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
Description = table.Column<string>(type: "TEXT", maxLength: 500, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_BotMetrics", x => x.Id);
table.ForeignKey(
name: "FK_BotMetrics_Bots_BotId",
column: x => x.BotId,
principalTable: "Bots",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "BotSessions",
columns: table => new
{
Id = table.Column<Guid>(type: "TEXT", nullable: false),
BotId = table.Column<Guid>(type: "TEXT", nullable: false),
SessionIdentifier = table.Column<string>(type: "TEXT", maxLength: 256, nullable: false),
Platform = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
StartedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
LastActivityAt = table.Column<DateTime>(type: "TEXT", nullable: false),
EndedAt = table.Column<DateTime>(type: "TEXT", nullable: true),
OrderCount = table.Column<int>(type: "INTEGER", nullable: false),
MessageCount = table.Column<int>(type: "INTEGER", nullable: false),
TotalSpent = table.Column<decimal>(type: "TEXT", nullable: false),
Language = table.Column<string>(type: "TEXT", maxLength: 50, nullable: false),
Country = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
IsAnonymous = table.Column<bool>(type: "INTEGER", nullable: false),
Metadata = table.Column<string>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_BotSessions", x => x.Id);
table.ForeignKey(
name: "FK_BotSessions_Bots_BotId",
column: x => x.BotId,
principalTable: "Bots",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "Products",
columns: table => new
{
Id = table.Column<Guid>(type: "TEXT", nullable: false),
Name = table.Column<string>(type: "TEXT", maxLength: 200, nullable: false),
Description = table.Column<string>(type: "TEXT", nullable: false),
Price = table.Column<decimal>(type: "decimal(18,2)", nullable: false),
Weight = table.Column<decimal>(type: "decimal(18,4)", nullable: false),
WeightUnit = table.Column<int>(type: "INTEGER", nullable: false),
StockQuantity = table.Column<int>(type: "INTEGER", nullable: false),
CategoryId = table.Column<Guid>(type: "TEXT", nullable: false),
IsActive = table.Column<bool>(type: "INTEGER", nullable: false),
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
UpdatedAt = table.Column<DateTime>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Products", x => x.Id);
table.ForeignKey(
name: "FK_Products_Categories_CategoryId",
column: x => x.CategoryId,
principalTable: "Categories",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "BotContacts",
columns: table => new
{
Id = table.Column<Guid>(type: "TEXT", nullable: false),
BotId = table.Column<Guid>(type: "TEXT", nullable: false),
TelegramUserId = table.Column<long>(type: "INTEGER", nullable: false),
TelegramUsername = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
DisplayName = table.Column<string>(type: "TEXT", maxLength: 200, nullable: false),
FirstName = table.Column<string>(type: "TEXT", maxLength: 50, nullable: false),
LastName = table.Column<string>(type: "TEXT", maxLength: 50, nullable: false),
FirstContactDate = table.Column<DateTime>(type: "TEXT", nullable: false),
LastContactDate = table.Column<DateTime>(type: "TEXT", nullable: false),
TotalInteractions = table.Column<int>(type: "INTEGER", nullable: false),
LastKnownLanguage = table.Column<string>(type: "TEXT", nullable: false),
Status = table.Column<int>(type: "INTEGER", nullable: false),
StatusReason = table.Column<string>(type: "TEXT", nullable: true),
CustomerId = table.Column<Guid>(type: "TEXT", nullable: true),
IsRecovered = table.Column<bool>(type: "INTEGER", nullable: false),
RecoveredFromBotId = table.Column<Guid>(type: "TEXT", nullable: true),
RecoveredAt = table.Column<DateTime>(type: "TEXT", nullable: true),
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
UpdatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
IsActive = table.Column<bool>(type: "INTEGER", nullable: false),
EncryptedContactData = table.Column<string>(type: "TEXT", maxLength: 500, nullable: true),
Preferences = table.Column<string>(type: "TEXT", maxLength: 500, nullable: true),
Notes = table.Column<string>(type: "TEXT", maxLength: 1000, nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_BotContacts", x => x.Id);
table.ForeignKey(
name: "FK_BotContacts_Bots_BotId",
column: x => x.BotId,
principalTable: "Bots",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_BotContacts_Customers_CustomerId",
column: x => x.CustomerId,
principalTable: "Customers",
principalColumn: "Id");
});
migrationBuilder.CreateTable(
name: "Orders",
columns: table => new
{
Id = table.Column<Guid>(type: "TEXT", nullable: false),
CustomerId = table.Column<Guid>(type: "TEXT", nullable: true),
IdentityReference = table.Column<string>(type: "TEXT", maxLength: 100, nullable: true),
Status = table.Column<int>(type: "INTEGER", nullable: false),
TotalAmount = table.Column<decimal>(type: "decimal(18,2)", nullable: false),
Currency = table.Column<string>(type: "TEXT", maxLength: 10, nullable: false),
ShippingName = table.Column<string>(type: "TEXT", maxLength: 200, nullable: false),
ShippingAddress = table.Column<string>(type: "TEXT", maxLength: 500, nullable: false),
ShippingCity = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
ShippingPostCode = table.Column<string>(type: "TEXT", maxLength: 20, nullable: false),
ShippingCountry = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
Notes = table.Column<string>(type: "TEXT", maxLength: 500, nullable: true),
TrackingNumber = table.Column<string>(type: "TEXT", maxLength: 100, nullable: true),
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
UpdatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
PaidAt = table.Column<DateTime>(type: "TEXT", nullable: true),
AcceptedAt = table.Column<DateTime>(type: "TEXT", nullable: true),
PackingStartedAt = table.Column<DateTime>(type: "TEXT", nullable: true),
DispatchedAt = table.Column<DateTime>(type: "TEXT", nullable: true),
ExpectedDeliveryDate = table.Column<DateTime>(type: "TEXT", nullable: true),
ActualDeliveryDate = table.Column<DateTime>(type: "TEXT", nullable: true),
OnHoldAt = table.Column<DateTime>(type: "TEXT", nullable: true),
AcceptedByUser = table.Column<string>(type: "TEXT", maxLength: 100, nullable: true),
PackedByUser = table.Column<string>(type: "TEXT", maxLength: 100, nullable: true),
DispatchedByUser = table.Column<string>(type: "TEXT", maxLength: 100, nullable: true),
OnHoldReason = table.Column<string>(type: "TEXT", maxLength: 500, nullable: true),
ShippedAt = table.Column<DateTime>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Orders", x => x.Id);
table.ForeignKey(
name: "FK_Orders_Customers_CustomerId",
column: x => x.CustomerId,
principalTable: "Customers",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "PushSubscriptions",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Endpoint = table.Column<string>(type: "TEXT", nullable: false),
P256DH = table.Column<string>(type: "TEXT", nullable: false),
Auth = table.Column<string>(type: "TEXT", nullable: false),
UserId = table.Column<Guid>(type: "TEXT", nullable: true),
CustomerId = table.Column<Guid>(type: "TEXT", nullable: true),
SubscribedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
LastUsedAt = table.Column<DateTime>(type: "TEXT", nullable: true),
IsActive = table.Column<bool>(type: "INTEGER", nullable: false),
UserAgent = table.Column<string>(type: "TEXT", nullable: true),
IpAddress = table.Column<string>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_PushSubscriptions", x => x.Id);
table.ForeignKey(
name: "FK_PushSubscriptions_Customers_CustomerId",
column: x => x.CustomerId,
principalTable: "Customers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_PushSubscriptions_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "ProductMultiBuys",
columns: table => new
{
Id = table.Column<Guid>(type: "TEXT", nullable: false),
ProductId = table.Column<Guid>(type: "TEXT", nullable: false),
Name = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
Description = table.Column<string>(type: "TEXT", nullable: false),
Quantity = table.Column<int>(type: "INTEGER", nullable: false),
Price = table.Column<decimal>(type: "decimal(18,2)", nullable: false),
PricePerUnit = table.Column<decimal>(type: "decimal(18,2)", nullable: false),
SortOrder = table.Column<int>(type: "INTEGER", nullable: false),
IsActive = table.Column<bool>(type: "INTEGER", nullable: false),
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
UpdatedAt = table.Column<DateTime>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ProductMultiBuys", x => x.Id);
table.ForeignKey(
name: "FK_ProductMultiBuys_Products_ProductId",
column: x => x.ProductId,
principalTable: "Products",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "ProductPhotos",
columns: table => new
{
Id = table.Column<Guid>(type: "TEXT", nullable: false),
ProductId = table.Column<Guid>(type: "TEXT", nullable: false),
FileName = table.Column<string>(type: "TEXT", maxLength: 500, nullable: false),
FilePath = table.Column<string>(type: "TEXT", maxLength: 1000, nullable: false),
AltText = table.Column<string>(type: "TEXT", maxLength: 100, nullable: true),
SortOrder = table.Column<int>(type: "INTEGER", nullable: false),
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ProductPhotos", x => x.Id);
table.ForeignKey(
name: "FK_ProductPhotos_Products_ProductId",
column: x => x.ProductId,
principalTable: "Products",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "ProductVariants",
columns: table => new
{
Id = table.Column<Guid>(type: "TEXT", nullable: false),
ProductId = table.Column<Guid>(type: "TEXT", nullable: false),
Name = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
VariantType = table.Column<string>(type: "TEXT", maxLength: 50, nullable: false),
SortOrder = table.Column<int>(type: "INTEGER", nullable: false),
IsActive = table.Column<bool>(type: "INTEGER", nullable: false),
StockLevel = table.Column<int>(type: "INTEGER", nullable: false),
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
UpdatedAt = table.Column<DateTime>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ProductVariants", x => x.Id);
table.ForeignKey(
name: "FK_ProductVariants_Products_ProductId",
column: x => x.ProductId,
principalTable: "Products",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "BotActivities",
columns: table => new
{
Id = table.Column<Guid>(type: "TEXT", nullable: false),
BotId = table.Column<Guid>(type: "TEXT", nullable: false),
SessionIdentifier = table.Column<string>(type: "TEXT", maxLength: 256, nullable: false),
UserDisplayName = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
ActivityType = table.Column<string>(type: "TEXT", maxLength: 50, nullable: false),
ActivityDescription = table.Column<string>(type: "TEXT", maxLength: 500, nullable: false),
ProductId = table.Column<Guid>(type: "TEXT", nullable: true),
ProductName = table.Column<string>(type: "TEXT", maxLength: 200, nullable: false),
OrderId = table.Column<Guid>(type: "TEXT", nullable: true),
CategoryName = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
Value = table.Column<decimal>(type: "TEXT", nullable: true),
Quantity = table.Column<int>(type: "INTEGER", nullable: true),
Platform = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
DeviceType = table.Column<string>(type: "TEXT", maxLength: 50, nullable: false),
Location = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
Timestamp = table.Column<DateTime>(type: "TEXT", nullable: false),
Metadata = table.Column<string>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_BotActivities", x => x.Id);
table.ForeignKey(
name: "FK_BotActivities_Bots_BotId",
column: x => x.BotId,
principalTable: "Bots",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_BotActivities_Orders_OrderId",
column: x => x.OrderId,
principalTable: "Orders",
principalColumn: "Id",
onDelete: ReferentialAction.SetNull);
table.ForeignKey(
name: "FK_BotActivities_Products_ProductId",
column: x => x.ProductId,
principalTable: "Products",
principalColumn: "Id",
onDelete: ReferentialAction.SetNull);
});
migrationBuilder.CreateTable(
name: "CryptoPayments",
columns: table => new
{
Id = table.Column<Guid>(type: "TEXT", nullable: false),
OrderId = table.Column<Guid>(type: "TEXT", nullable: false),
Currency = table.Column<int>(type: "INTEGER", nullable: false),
WalletAddress = table.Column<string>(type: "TEXT", maxLength: 500, nullable: false),
RequiredAmount = table.Column<decimal>(type: "decimal(18,8)", nullable: false),
PaidAmount = table.Column<decimal>(type: "decimal(18,8)", nullable: false),
Status = table.Column<int>(type: "INTEGER", nullable: false),
BTCPayInvoiceId = table.Column<string>(type: "TEXT", maxLength: 200, nullable: true),
SilverPayOrderId = table.Column<string>(type: "TEXT", maxLength: 200, nullable: true),
TransactionHash = table.Column<string>(type: "TEXT", maxLength: 200, nullable: true),
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
PaidAt = table.Column<DateTime>(type: "TEXT", nullable: true),
ExpiresAt = table.Column<DateTime>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_CryptoPayments", x => x.Id);
table.ForeignKey(
name: "FK_CryptoPayments_Orders_OrderId",
column: x => x.OrderId,
principalTable: "Orders",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "CustomerMessages",
columns: table => new
{
Id = table.Column<Guid>(type: "TEXT", nullable: false),
CustomerId = table.Column<Guid>(type: "TEXT", nullable: false),
OrderId = table.Column<Guid>(type: "TEXT", nullable: true),
AdminUserId = table.Column<Guid>(type: "TEXT", nullable: true),
Direction = table.Column<int>(type: "INTEGER", nullable: false),
Type = table.Column<int>(type: "INTEGER", nullable: false),
Subject = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
Content = table.Column<string>(type: "TEXT", maxLength: 4000, nullable: false),
Status = table.Column<int>(type: "INTEGER", nullable: false),
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
SentAt = table.Column<DateTime>(type: "TEXT", nullable: true),
DeliveredAt = table.Column<DateTime>(type: "TEXT", nullable: true),
ReadAt = table.Column<DateTime>(type: "TEXT", nullable: true),
FailedAt = table.Column<DateTime>(type: "TEXT", nullable: true),
FailureReason = table.Column<string>(type: "TEXT", maxLength: 500, nullable: true),
RetryCount = table.Column<int>(type: "INTEGER", nullable: false),
NextRetryAt = table.Column<DateTime>(type: "TEXT", nullable: true),
ParentMessageId = table.Column<Guid>(type: "TEXT", nullable: true),
ThreadId = table.Column<Guid>(type: "TEXT", nullable: true),
Platform = table.Column<string>(type: "TEXT", maxLength: 100, nullable: false),
PlatformMessageId = table.Column<string>(type: "TEXT", maxLength: 200, nullable: true),
Priority = table.Column<int>(type: "INTEGER", nullable: false),
ScheduledFor = table.Column<DateTime>(type: "TEXT", nullable: true),
ExpiresAt = table.Column<DateTime>(type: "TEXT", nullable: true),
RequiresResponse = table.Column<bool>(type: "INTEGER", nullable: false),
IsUrgent = table.Column<bool>(type: "INTEGER", nullable: false),
IsMarketing = table.Column<bool>(type: "INTEGER", nullable: false),
IsAutoGenerated = table.Column<bool>(type: "INTEGER", nullable: false),
AutoGenerationTrigger = table.Column<string>(type: "TEXT", maxLength: 100, nullable: true),
IsArchived = table.Column<bool>(type: "INTEGER", nullable: false),
ArchivedAt = table.Column<DateTime>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_CustomerMessages", x => x.Id);
table.ForeignKey(
name: "FK_CustomerMessages_CustomerMessages_ParentMessageId",
column: x => x.ParentMessageId,
principalTable: "CustomerMessages",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_CustomerMessages_Customers_CustomerId",
column: x => x.CustomerId,
principalTable: "Customers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_CustomerMessages_Orders_OrderId",
column: x => x.OrderId,
principalTable: "Orders",
principalColumn: "Id",
onDelete: ReferentialAction.SetNull);
table.ForeignKey(
name: "FK_CustomerMessages_Users_AdminUserId",
column: x => x.AdminUserId,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.SetNull);
});
migrationBuilder.CreateTable(
name: "Reviews",
columns: table => new
{
Id = table.Column<Guid>(type: "TEXT", nullable: false),
ProductId = table.Column<Guid>(type: "TEXT", nullable: false),
CustomerId = table.Column<Guid>(type: "TEXT", nullable: false),
OrderId = table.Column<Guid>(type: "TEXT", nullable: false),
Rating = table.Column<int>(type: "INTEGER", nullable: false),
Title = table.Column<string>(type: "TEXT", maxLength: 100, nullable: true),
Comment = table.Column<string>(type: "TEXT", maxLength: 2000, nullable: true),
IsVerifiedPurchase = table.Column<bool>(type: "INTEGER", nullable: false),
IsApproved = table.Column<bool>(type: "INTEGER", nullable: false),
IsActive = table.Column<bool>(type: "INTEGER", nullable: false),
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
UpdatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
ApprovedAt = table.Column<DateTime>(type: "TEXT", nullable: true),
ApprovedByUserId = table.Column<Guid>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Reviews", x => x.Id);
table.ForeignKey(
name: "FK_Reviews_Customers_CustomerId",
column: x => x.CustomerId,
principalTable: "Customers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_Reviews_Orders_OrderId",
column: x => x.OrderId,
principalTable: "Orders",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_Reviews_Products_ProductId",
column: x => x.ProductId,
principalTable: "Products",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_Reviews_Users_ApprovedByUserId",
column: x => x.ApprovedByUserId,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.SetNull);
});
migrationBuilder.CreateTable(
name: "OrderItems",
columns: table => new
{
Id = table.Column<Guid>(type: "TEXT", nullable: false),
OrderId = table.Column<Guid>(type: "TEXT", nullable: false),
ProductId = table.Column<Guid>(type: "TEXT", nullable: false),
ProductMultiBuyId = table.Column<Guid>(type: "TEXT", nullable: true),
SelectedVariant = table.Column<string>(type: "TEXT", maxLength: 100, nullable: true),
Quantity = table.Column<int>(type: "INTEGER", nullable: false),
UnitPrice = table.Column<decimal>(type: "decimal(18,2)", nullable: false),
TotalPrice = table.Column<decimal>(type: "decimal(18,2)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_OrderItems", x => x.Id);
table.ForeignKey(
name: "FK_OrderItems_Orders_OrderId",
column: x => x.OrderId,
principalTable: "Orders",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_OrderItems_ProductMultiBuys_ProductMultiBuyId",
column: x => x.ProductMultiBuyId,
principalTable: "ProductMultiBuys",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_OrderItems_Products_ProductId",
column: x => x.ProductId,
principalTable: "Products",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateIndex(
name: "IX_BotActivities_ActivityType",
table: "BotActivities",
column: "ActivityType");
migrationBuilder.CreateIndex(
name: "IX_BotActivities_BotId_Timestamp",
table: "BotActivities",
columns: new[] { "BotId", "Timestamp" });
migrationBuilder.CreateIndex(
name: "IX_BotActivities_OrderId",
table: "BotActivities",
column: "OrderId");
migrationBuilder.CreateIndex(
name: "IX_BotActivities_ProductId",
table: "BotActivities",
column: "ProductId");
migrationBuilder.CreateIndex(
name: "IX_BotActivities_SessionIdentifier",
table: "BotActivities",
column: "SessionIdentifier");
migrationBuilder.CreateIndex(
name: "IX_BotActivities_Timestamp",
table: "BotActivities",
column: "Timestamp");
migrationBuilder.CreateIndex(
name: "IX_BotContacts_BotId",
table: "BotContacts",
column: "BotId");
migrationBuilder.CreateIndex(
name: "IX_BotContacts_CustomerId",
table: "BotContacts",
column: "CustomerId");
migrationBuilder.CreateIndex(
name: "IX_BotMetrics_BotId_RecordedAt",
table: "BotMetrics",
columns: new[] { "BotId", "RecordedAt" });
migrationBuilder.CreateIndex(
name: "IX_BotMetrics_MetricType",
table: "BotMetrics",
column: "MetricType");
migrationBuilder.CreateIndex(
name: "IX_Bots_BotKey",
table: "Bots",
column: "BotKey",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_Bots_Name",
table: "Bots",
column: "Name");
migrationBuilder.CreateIndex(
name: "IX_Bots_Status",
table: "Bots",
column: "Status");
migrationBuilder.CreateIndex(
name: "IX_BotSessions_BotId_SessionIdentifier",
table: "BotSessions",
columns: new[] { "BotId", "SessionIdentifier" });
migrationBuilder.CreateIndex(
name: "IX_BotSessions_LastActivityAt",
table: "BotSessions",
column: "LastActivityAt");
migrationBuilder.CreateIndex(
name: "IX_BotSessions_StartedAt",
table: "BotSessions",
column: "StartedAt");
migrationBuilder.CreateIndex(
name: "IX_CryptoPayments_BTCPayInvoiceId",
table: "CryptoPayments",
column: "BTCPayInvoiceId");
migrationBuilder.CreateIndex(
name: "IX_CryptoPayments_OrderId",
table: "CryptoPayments",
column: "OrderId");
migrationBuilder.CreateIndex(
name: "IX_CryptoPayments_WalletAddress",
table: "CryptoPayments",
column: "WalletAddress");
migrationBuilder.CreateIndex(
name: "IX_CustomerMessages_AdminUserId",
table: "CustomerMessages",
column: "AdminUserId");
migrationBuilder.CreateIndex(
name: "IX_CustomerMessages_CustomerId_CreatedAt",
table: "CustomerMessages",
columns: new[] { "CustomerId", "CreatedAt" });
migrationBuilder.CreateIndex(
name: "IX_CustomerMessages_Direction",
table: "CustomerMessages",
column: "Direction");
migrationBuilder.CreateIndex(
name: "IX_CustomerMessages_OrderId",
table: "CustomerMessages",
column: "OrderId");
migrationBuilder.CreateIndex(
name: "IX_CustomerMessages_ParentMessageId",
table: "CustomerMessages",
column: "ParentMessageId");
migrationBuilder.CreateIndex(
name: "IX_CustomerMessages_ScheduledFor",
table: "CustomerMessages",
column: "ScheduledFor");
migrationBuilder.CreateIndex(
name: "IX_CustomerMessages_Status",
table: "CustomerMessages",
column: "Status");
migrationBuilder.CreateIndex(
name: "IX_CustomerMessages_ThreadId",
table: "CustomerMessages",
column: "ThreadId");
migrationBuilder.CreateIndex(
name: "IX_CustomerMessages_Type",
table: "CustomerMessages",
column: "Type");
migrationBuilder.CreateIndex(
name: "IX_Customers_CreatedAt",
table: "Customers",
column: "CreatedAt");
migrationBuilder.CreateIndex(
name: "IX_Customers_DataRetentionDate",
table: "Customers",
column: "DataRetentionDate");
migrationBuilder.CreateIndex(
name: "IX_Customers_Email",
table: "Customers",
column: "Email");
migrationBuilder.CreateIndex(
name: "IX_Customers_LastActiveAt",
table: "Customers",
column: "LastActiveAt");
migrationBuilder.CreateIndex(
name: "IX_Customers_TelegramUserId",
table: "Customers",
column: "TelegramUserId",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_Customers_TelegramUsername",
table: "Customers",
column: "TelegramUsername");
migrationBuilder.CreateIndex(
name: "IX_OrderItems_OrderId",
table: "OrderItems",
column: "OrderId");
migrationBuilder.CreateIndex(
name: "IX_OrderItems_ProductId",
table: "OrderItems",
column: "ProductId");
migrationBuilder.CreateIndex(
name: "IX_OrderItems_ProductMultiBuyId",
table: "OrderItems",
column: "ProductMultiBuyId");
migrationBuilder.CreateIndex(
name: "IX_Orders_CreatedAt",
table: "Orders",
column: "CreatedAt");
migrationBuilder.CreateIndex(
name: "IX_Orders_CustomerId",
table: "Orders",
column: "CustomerId");
migrationBuilder.CreateIndex(
name: "IX_Orders_IdentityReference",
table: "Orders",
column: "IdentityReference");
migrationBuilder.CreateIndex(
name: "IX_ProductMultiBuys_IsActive",
table: "ProductMultiBuys",
column: "IsActive");
migrationBuilder.CreateIndex(
name: "IX_ProductMultiBuys_ProductId_Quantity",
table: "ProductMultiBuys",
columns: new[] { "ProductId", "Quantity" },
unique: true);
migrationBuilder.CreateIndex(
name: "IX_ProductMultiBuys_ProductId_SortOrder",
table: "ProductMultiBuys",
columns: new[] { "ProductId", "SortOrder" });
migrationBuilder.CreateIndex(
name: "IX_ProductPhotos_ProductId",
table: "ProductPhotos",
column: "ProductId");
migrationBuilder.CreateIndex(
name: "IX_Products_CategoryId",
table: "Products",
column: "CategoryId");
migrationBuilder.CreateIndex(
name: "IX_ProductVariants_IsActive",
table: "ProductVariants",
column: "IsActive");
migrationBuilder.CreateIndex(
name: "IX_ProductVariants_ProductId_Name",
table: "ProductVariants",
columns: new[] { "ProductId", "Name" },
unique: true);
migrationBuilder.CreateIndex(
name: "IX_ProductVariants_ProductId_SortOrder",
table: "ProductVariants",
columns: new[] { "ProductId", "SortOrder" });
migrationBuilder.CreateIndex(
name: "IX_PushSubscriptions_CustomerId",
table: "PushSubscriptions",
column: "CustomerId");
migrationBuilder.CreateIndex(
name: "IX_PushSubscriptions_Endpoint",
table: "PushSubscriptions",
column: "Endpoint",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_PushSubscriptions_IsActive",
table: "PushSubscriptions",
column: "IsActive");
migrationBuilder.CreateIndex(
name: "IX_PushSubscriptions_SubscribedAt",
table: "PushSubscriptions",
column: "SubscribedAt");
migrationBuilder.CreateIndex(
name: "IX_PushSubscriptions_UserId",
table: "PushSubscriptions",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_Reviews_ApprovedByUserId",
table: "Reviews",
column: "ApprovedByUserId");
migrationBuilder.CreateIndex(
name: "IX_Reviews_CreatedAt",
table: "Reviews",
column: "CreatedAt");
migrationBuilder.CreateIndex(
name: "IX_Reviews_CustomerId",
table: "Reviews",
column: "CustomerId");
migrationBuilder.CreateIndex(
name: "IX_Reviews_CustomerId_ProductId",
table: "Reviews",
columns: new[] { "CustomerId", "ProductId" },
unique: true);
migrationBuilder.CreateIndex(
name: "IX_Reviews_IsActive",
table: "Reviews",
column: "IsActive");
migrationBuilder.CreateIndex(
name: "IX_Reviews_IsApproved",
table: "Reviews",
column: "IsApproved");
migrationBuilder.CreateIndex(
name: "IX_Reviews_OrderId",
table: "Reviews",
column: "OrderId");
migrationBuilder.CreateIndex(
name: "IX_Reviews_ProductId",
table: "Reviews",
column: "ProductId");
migrationBuilder.CreateIndex(
name: "IX_Reviews_ProductId_IsApproved_IsActive",
table: "Reviews",
columns: new[] { "ProductId", "IsApproved", "IsActive" });
migrationBuilder.CreateIndex(
name: "IX_Reviews_Rating",
table: "Reviews",
column: "Rating");
migrationBuilder.CreateIndex(
name: "IX_Users_Username",
table: "Users",
column: "Username",
unique: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "BotActivities");
migrationBuilder.DropTable(
name: "BotContacts");
migrationBuilder.DropTable(
name: "BotMetrics");
migrationBuilder.DropTable(
name: "BotSessions");
migrationBuilder.DropTable(
name: "CryptoPayments");
migrationBuilder.DropTable(
name: "CustomerMessages");
migrationBuilder.DropTable(
name: "OrderItems");
migrationBuilder.DropTable(
name: "ProductPhotos");
migrationBuilder.DropTable(
name: "ProductVariants");
migrationBuilder.DropTable(
name: "PushSubscriptions");
migrationBuilder.DropTable(
name: "Reviews");
migrationBuilder.DropTable(
name: "ShippingRates");
migrationBuilder.DropTable(
name: "Bots");
migrationBuilder.DropTable(
name: "ProductMultiBuys");
migrationBuilder.DropTable(
name: "Orders");
migrationBuilder.DropTable(
name: "Users");
migrationBuilder.DropTable(
name: "Products");
migrationBuilder.DropTable(
name: "Customers");
migrationBuilder.DropTable(
name: "Categories");
}
}
}