-- AlterTable
ALTER TABLE `permission` MODIFY `key` ENUM('READ', 'WRITE', 'ADMIN', 'USERS_READ', 'USERS_WRITE', 'USERS_BAN', 'USERS_UNBAN', 'USERS_DISABLE', 'USERS_ENABLE', 'USERS_KYC_VERIFY', 'USERS_RESET_PASSWORD', 'WALLETS_READ', 'WALLETS_WRITE', 'WALLETS_FREEZE', 'WALLETS_UNFREEZE', 'WALLETS_ADJUST_BALANCE', 'ORDERS_READ', 'ORDERS_CANCEL', 'ORDERS_RESOLVE_DISPUTE', 'ORDERS_RELEASE_FUNDS', 'REPORTS_READ', 'REPORTS_EXPORT', 'ANALYTICS_READ', 'SUPPORT_READ', 'SUPPORT_WRITE', 'SUPPORT_ASSIGN', 'SUPPORT_CLOSE', 'ANNOUNCEMENTS_READ', 'ANNOUNCEMENTS_WRITE', 'ANNOUNCEMENTS_DELETE', 'ROLES_READ', 'ROLES_WRITE', 'PERMISSIONS_READ', 'PERMISSIONS_WRITE', 'LOGS_READ', 'LOGS_DELETE', 'LOGS_EXPORT', 'LOGS_ARCHIVE', 'SYSTEM_READ', 'SYSTEM_WRITE', 'REFERRAL_READ', 'REFERRAL_WRITE', 'COMMISSION_READ', 'COMMISSION_WRITE', 'RULES_READ', 'RULES_WRITE', 'WITHDRAWAL_RULES_READ', 'WITHDRAWAL_RULES_WRITE', 'DEPOSIT_RULES_READ', 'DEPOSIT_RULES_WRITE', 'TRADING_RULES_READ', 'TRADING_RULES_WRITE', 'SECURITY_ALERTS_READ', 'SECURITY_ALERTS_WRITE', 'SECURITY_ALERTS_RESOLVE', 'APPROVAL_REQUESTS_READ', 'APPROVAL_REQUESTS_APPROVE', 'APPROVAL_REQUESTS_REJECT', 'FEATURE_FLAGS_READ', 'FEATURE_FLAGS_WRITE', 'EMERGENCY_CONTROLS_READ', 'EMERGENCY_CONTROLS_WRITE', 'SYSTEM_HEALTH_READ', 'APPEALS_READ', 'APPEALS_MANAGE') NOT NULL;

-- CreateTable
CREATE TABLE `LedgerEntry` (
    `id` VARCHAR(191) NOT NULL,
    `createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
    `updatedAt` DATETIME(3) NOT NULL,
    `transactionId` VARCHAR(64) NOT NULL,
    `userId` VARCHAR(191) NOT NULL,
    `amount` DECIMAL(30, 10) NOT NULL,
    `type` ENUM('CREDIT', 'DEBIT', 'CORRECTION', 'FEE', 'FINE', 'REVERSAL', 'COMMISSION', 'REFERRAL', 'BONUS', 'SUBSCRIPTION', 'PURCHASE_REWARD', 'ADMIN_ADJUSTMENT') NOT NULL,
    `reason` VARCHAR(191) NOT NULL,
    `ruleId` VARCHAR(191) NULL,
    `beforeBalance` DECIMAL(30, 10) NOT NULL,
    `afterBalance` DECIMAL(30, 10) NOT NULL,
    `timestamp` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
    `actorId` VARCHAR(191) NULL,
    `referenceOrderId` VARCHAR(191) NULL,
    `metadata` JSON NULL,

    UNIQUE INDEX `LedgerEntry_transactionId_key`(`transactionId`),
    INDEX `LedgerEntry_userId_idx`(`userId`),
    INDEX `LedgerEntry_transactionId_idx`(`transactionId`),
    INDEX `LedgerEntry_type_idx`(`type`),
    INDEX `LedgerEntry_timestamp_idx`(`timestamp`),
    INDEX `LedgerEntry_userId_timestamp_idx`(`userId`, `timestamp`),
    INDEX `LedgerEntry_ruleId_idx`(`ruleId`),
    PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- CreateTable
CREATE TABLE `LedgerIdempotencyKey` (
    `id` VARCHAR(191) NOT NULL,
    `createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
    `key` VARCHAR(191) NOT NULL,
    `ledgerEntryId` VARCHAR(64) NOT NULL,
    `expiresAt` DATETIME(3) NOT NULL,

    UNIQUE INDEX `LedgerIdempotencyKey_key_key`(`key`),
    INDEX `LedgerIdempotencyKey_key_idx`(`key`),
    INDEX `LedgerIdempotencyKey_expiresAt_idx`(`expiresAt`),
    PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- CreateTable
CREATE TABLE `LedgerAuditLog` (
    `id` VARCHAR(191) NOT NULL,
    `createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
    `ledgerEntryId` VARCHAR(191) NOT NULL,
    `action` VARCHAR(191) NOT NULL,
    `actorId` VARCHAR(191) NULL,
    `actorRole` VARCHAR(191) NULL,
    `details` JSON NULL,
    `ipAddress` VARCHAR(191) NULL,
    `userAgent` VARCHAR(191) NULL,

    INDEX `LedgerAuditLog_ledgerEntryId_idx`(`ledgerEntryId`),
    INDEX `LedgerAuditLog_action_idx`(`action`),
    INDEX `LedgerAuditLog_actorId_idx`(`actorId`),
    INDEX `LedgerAuditLog_createdAt_idx`(`createdAt`),
    PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- CreateTable
CREATE TABLE `Fine` (
    `id` VARCHAR(191) NOT NULL,
    `createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
    `updatedAt` DATETIME(3) NOT NULL,
    `userId` VARCHAR(191) NOT NULL,
    `amount` DECIMAL(30, 10) NOT NULL,
    `reason` VARCHAR(191) NOT NULL,
    `effectiveDate` DATETIME(3) NOT NULL,
    `expiryDate` DATETIME(3) NOT NULL,
    `status` ENUM('PENDING', 'ACTIVE', 'PAID', 'EXPIRED', 'CANCELLED') NOT NULL DEFAULT 'PENDING',
    `paidAt` DATETIME(3) NULL,
    `metadata` JSON NULL,

    INDEX `Fine_userId_idx`(`userId`),
    INDEX `Fine_status_idx`(`status`),
    INDEX `Fine_effectiveDate_idx`(`effectiveDate`),
    INDEX `Fine_expiryDate_idx`(`expiryDate`),
    PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- CreateTable
CREATE TABLE `Restriction` (
    `id` VARCHAR(191) NOT NULL,
    `createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
    `updatedAt` DATETIME(3) NOT NULL,
    `userId` VARCHAR(191) NOT NULL,
    `type` ENUM('SELL', 'BUY', 'WITHDRAW', 'TRANSFER') NOT NULL,
    `reason` VARCHAR(191) NOT NULL,
    `effectiveDate` DATETIME(3) NOT NULL,
    `expiryDate` DATETIME(3) NOT NULL,
    `status` VARCHAR(191) NOT NULL DEFAULT 'ACTIVE',
    `metadata` JSON NULL,

    INDEX `Restriction_userId_idx`(`userId`),
    INDEX `Restriction_type_idx`(`type`),
    INDEX `Restriction_status_idx`(`status`),
    INDEX `Restriction_effectiveDate_idx`(`effectiveDate`),
    INDEX `Restriction_expiryDate_idx`(`expiryDate`),
    PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- CreateTable
CREATE TABLE `Subscription` (
    `id` VARCHAR(191) NOT NULL,
    `createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
    `updatedAt` DATETIME(3) NOT NULL,
    `userId` VARCHAR(191) NOT NULL,
    `planId` VARCHAR(191) NOT NULL,
    `status` ENUM('ACTIVE', 'EXPIRED', 'GRACE', 'TERMINATED') NOT NULL DEFAULT 'ACTIVE',
    `startDate` DATETIME(3) NOT NULL,
    `endDate` DATETIME(3) NOT NULL,
    `gracePeriodEnd` DATETIME(3) NULL,
    `renewalCount` INTEGER NOT NULL DEFAULT 0,
    `lastPaymentId` VARCHAR(191) NULL,
    `cancelledAt` DATETIME(3) NULL,
    `metadata` JSON NULL,

    INDEX `Subscription_userId_idx`(`userId`),
    INDEX `Subscription_status_idx`(`status`),
    INDEX `Subscription_endDate_idx`(`endDate`),
    UNIQUE INDEX `Subscription_userId_key`(`userId`),
    PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- CreateTable
CREATE TABLE `RewardRule` (
    `id` VARCHAR(191) NOT NULL,
    `createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
    `updatedAt` DATETIME(3) NOT NULL,
    `name` VARCHAR(191) NOT NULL,
    `type` ENUM('PURCHASE_REWARD', 'REFERRAL_COMMISSION', 'BONUS', 'FINE') NOT NULL,
    `isActive` BOOLEAN NOT NULL DEFAULT true,
    `priority` INTEGER NOT NULL DEFAULT 0,
    `config` JSON NOT NULL,
    `effectiveDate` DATETIME(3) NOT NULL,
    `expiryDate` DATETIME(3) NOT NULL,
    `metadata` JSON NULL,

    INDEX `RewardRule_type_idx`(`type`),
    INDEX `RewardRule_isActive_idx`(`isActive`),
    INDEX `RewardRule_priority_idx`(`priority`),
    INDEX `RewardRule_effectiveDate_expiryDate_idx`(`effectiveDate`, `expiryDate`),
    PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- CreateTable
CREATE TABLE `RewardApplication` (
    `id` VARCHAR(191) NOT NULL,
    `createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
    `userId` VARCHAR(191) NOT NULL,
    `ruleId` VARCHAR(191) NOT NULL,
    `type` ENUM('PURCHASE_REWARD', 'REFERRAL_COMMISSION', 'BONUS', 'FINE') NOT NULL,
    `amount` DECIMAL(30, 10) NOT NULL,
    `currency` VARCHAR(191) NOT NULL DEFAULT 'USD',
    `status` VARCHAR(191) NOT NULL DEFAULT 'PENDING',
    `appliedAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
    `referenceId` VARCHAR(191) NULL,
    `metadata` JSON NULL,

    INDEX `RewardApplication_userId_idx`(`userId`),
    INDEX `RewardApplication_ruleId_idx`(`ruleId`),
    INDEX `RewardApplication_type_idx`(`type`),
    INDEX `RewardApplication_status_idx`(`status`),
    INDEX `RewardApplication_createdAt_idx`(`createdAt`),
    PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- CreateTable
CREATE TABLE `MinimumBalanceConfig` (
    `id` VARCHAR(191) NOT NULL,
    `createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
    `updatedAt` DATETIME(3) NOT NULL,
    `actionType` VARCHAR(191) NOT NULL DEFAULT 'GLOBAL',
    `minAmount` DECIMAL(30, 10) NOT NULL,
    `currency` VARCHAR(191) NOT NULL DEFAULT 'USD',
    `isActive` BOOLEAN NOT NULL DEFAULT true,
    `appliesToRoles` JSON NULL,
    `startAt` DATETIME(3) NULL,
    `endAt` DATETIME(3) NULL,
    `metadata` JSON NULL,

    INDEX `MinimumBalanceConfig_actionType_idx`(`actionType`),
    INDEX `MinimumBalanceConfig_isActive_idx`(`isActive`),
    INDEX `MinimumBalanceConfig_startAt_endAt_idx`(`startAt`, `endAt`),
    PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- AddForeignKey
ALTER TABLE `TradingControlRange` ADD CONSTRAINT `TradingControlRange_createdById_fkey` FOREIGN KEY (`createdById`) REFERENCES `User`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE `TradingControlRange` ADD CONSTRAINT `TradingControlRange_updatedById_fkey` FOREIGN KEY (`updatedById`) REFERENCES `User`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE `BuyCommission` ADD CONSTRAINT `BuyCommission_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE `BuyCommission` ADD CONSTRAINT `BuyCommission_orderId_fkey` FOREIGN KEY (`orderId`) REFERENCES `Order`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE `ReferralCommission` ADD CONSTRAINT `ReferralCommission_referrerId_fkey` FOREIGN KEY (`referrerId`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE `ReferralCommission` ADD CONSTRAINT `ReferralCommission_referredId_fkey` FOREIGN KEY (`referredId`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE `ReferralCommission` ADD CONSTRAINT `ReferralCommission_orderId_fkey` FOREIGN KEY (`orderId`) REFERENCES `Order`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE `ReferralCommission` ADD CONSTRAINT `ReferralCommission_tradeId_fkey` FOREIGN KEY (`tradeId`) REFERENCES `Trade`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE `LedgerEntry` ADD CONSTRAINT `LedgerEntry_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE `Fine` ADD CONSTRAINT `Fine_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE `Restriction` ADD CONSTRAINT `Restriction_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE `Subscription` ADD CONSTRAINT `Subscription_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE `Subscription` ADD CONSTRAINT `Subscription_planId_fkey` FOREIGN KEY (`planId`) REFERENCES `SubscriptionPlan`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;

-- RenameIndex
ALTER TABLE `tradingcontrolrange` RENAME INDEX `idx_trading_control_created_by` TO `TradingControlRange_createdById_idx`;

-- RenameIndex
ALTER TABLE `tradingcontrolrange` RENAME INDEX `idx_trading_control_is_active` TO `TradingControlRange_isActive_idx`;

-- RenameIndex
ALTER TABLE `tradingcontrolrange` RENAME INDEX `idx_trading_control_start_end` TO `TradingControlRange_startAt_endAt_idx`;

-- RenameIndex
ALTER TABLE `tradingcontrolrange` RENAME INDEX `idx_trading_control_status` TO `TradingControlRange_status_idx`;
