"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.InitialSchema1700000000000 = void 0;
const typeorm_1 = require("typeorm");
class InitialSchema1700000000000 {
    constructor() {
        this.name = 'InitialSchema1700000000000';
    }
    async up(queryRunner) {
        await queryRunner.query(`CREATE EXTENSION IF NOT EXISTS "uuid-ossp"`);
        await queryRunner.createTable(new typeorm_1.Table({
            name: 'businesses',
            columns: [
                { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' },
                { name: 'name', type: 'varchar', length: '255', isUnique: true },
                { name: 'slug', type: 'varchar', length: '255', isUnique: true },
                { name: 'logo', type: 'varchar', length: '500', isNullable: true },
                { name: 'email', type: 'varchar', length: '255', isNullable: true },
                { name: 'phone', type: 'varchar', length: '20', isNullable: true },
                { name: 'address', type: 'text', isNullable: true },
                { name: 'city', type: 'varchar', length: '100', isNullable: true },
                { name: 'country', type: 'varchar', length: '100', isNullable: true },
                { name: 'website', type: 'varchar', length: '500', isNullable: true },
                { name: 'taxId', type: 'varchar', length: '50', isNullable: true },
                { name: 'isActive', type: 'boolean', default: true },
                { name: 'isSuspended', type: 'boolean', default: false },
                { name: 'suspendedReason', type: 'text', isNullable: true },
                { name: 'subscriptionId', type: 'uuid', isNullable: true },
                { name: 'subscriptionStartDate', type: 'timestamptz', isNullable: true },
                { name: 'subscriptionEndDate', type: 'timestamptz', isNullable: true },
                { name: 'settings', type: 'jsonb', isNullable: true },
                { name: 'maxRouters', type: 'int', default: 10 },
                { name: 'maxLocations', type: 'int', default: 5 },
                { name: 'maxStaff', type: 'int', default: 50 },
                { name: 'maxCustomers', type: 'int', default: 1000 },
                { name: 'createdAt', type: 'timestamptz', default: 'now()' },
                { name: 'updatedAt', type: 'timestamptz', default: 'now()' },
            ],
        }), true);
        await queryRunner.createIndex('businesses', new typeorm_1.TableIndex({ name: 'IDX_businesses_name', columnNames: ['name'] }));
        await queryRunner.createIndex('businesses', new typeorm_1.TableIndex({ name: 'IDX_businesses_slug', columnNames: ['slug'], isUnique: true }));
        await queryRunner.createTable(new typeorm_1.Table({
            name: 'subscription_plans',
            columns: [
                { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' },
                { name: 'name', type: 'varchar', length: '255' },
                { name: 'slug', type: 'varchar', length: '255', isUnique: true },
                { name: 'description', type: 'text', isNullable: true },
                { name: 'priceKes', type: 'decimal', precision: 12, scale: 2 },
                { name: 'billingCycle', type: 'enum', enum: ['MONTHLY', 'QUARTERLY', 'ANNUAL'], default: `'MONTHLY'` },
                { name: 'maxRouters', type: 'int', default: 10 },
                { name: 'maxLocations', type: 'int', default: 5 },
                { name: 'maxStaff', type: 'int', default: 50 },
                { name: 'maxCustomers', type: 'int', default: 1000 },
                { name: 'includesVouchers', type: 'boolean', default: false },
                { name: 'includesCustomBranding', type: 'boolean', default: false },
                { name: 'includesApiAccess', type: 'boolean', default: false },
                { name: 'includesPrioritySupport', type: 'boolean', default: false },
                { name: 'includesWhiteLabel', type: 'boolean', default: false },
                { name: 'commissionRate', type: 'decimal', precision: 5, scale: 2, default: 0 },
                { name: 'isActive', type: 'boolean', default: true },
                { name: 'sortOrder', type: 'int', default: 0 },
                { name: 'createdAt', type: 'timestamptz', default: 'now()' },
            ],
        }), true);
        await queryRunner.createIndex('subscription_plans', new typeorm_1.TableIndex({ name: 'IDX_sp_slug', columnNames: ['slug'], isUnique: true }));
        await queryRunner.createTable(new typeorm_1.Table({
            name: 'subscriptions',
            columns: [
                { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' },
                { name: 'businessId', type: 'uuid' },
                { name: 'planId', type: 'uuid' },
                { name: 'status', type: 'enum', enum: ['ACTIVE', 'PAST_DUE', 'CANCELLED', 'EXPIRED', 'TRIAL'], default: `'TRIAL'` },
                { name: 'startDate', type: 'timestamptz' },
                { name: 'endDate', type: 'timestamptz', isNullable: true },
                { name: 'trialEndDate', type: 'timestamptz', isNullable: true },
                { name: 'nextBillingDate', type: 'timestamptz', isNullable: true },
                { name: 'priceKes', type: 'decimal', precision: 12, scale: 2 },
                { name: 'autoRenew', type: 'boolean', default: true },
                { name: 'cancelledAt', type: 'timestamptz', isNullable: true },
                { name: 'cancelledReason', type: 'text', isNullable: true },
                { name: 'createdAt', type: 'timestamptz', default: 'now()' },
                { name: 'updatedAt', type: 'timestamptz', default: 'now()' },
            ],
        }), true);
        await queryRunner.createForeignKey('subscriptions', new typeorm_1.TableForeignKey({
            name: 'FK_subscriptions_business', columnNames: ['businessId'],
            referencedTableName: 'businesses', referencedColumnNames: ['id'], onDelete: 'CASCADE',
        }));
        await queryRunner.createForeignKey('subscriptions', new typeorm_1.TableForeignKey({
            name: 'FK_subscriptions_plan', columnNames: ['planId'],
            referencedTableName: 'subscription_plans', referencedColumnNames: ['id'], onDelete: 'RESTRICT',
        }));
        await queryRunner.createIndex('subscriptions', new typeorm_1.TableIndex({ name: 'IDX_subscriptions_businessId', columnNames: ['businessId'] }));
        await queryRunner.createTable(new typeorm_1.Table({
            name: 'roles', columns: [
                { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' },
                { name: 'name', type: 'varchar', length: '100', isUnique: true },
                { name: 'description', type: 'text', isNullable: true },
                { name: 'type', type: 'enum', enum: ['SUPER_ADMIN', 'BUSINESS_OWNER', 'MANAGER', 'ACCOUNTANT', 'SUPPORT_AGENT', 'TECHNICIAN', 'SALES_AGENT', 'CASHIER', 'CUSTOMER'] },
                { name: 'isSystem', type: 'boolean', default: false },
                { name: 'businessId', type: 'uuid', isNullable: true },
                { name: 'createdAt', type: 'timestamptz', default: 'now()' },
            ],
        }), true);
        await queryRunner.createIndex('roles', new typeorm_1.TableIndex({ name: 'IDX_roles_name', columnNames: ['name'], isUnique: true }));
        await queryRunner.createTable(new typeorm_1.Table({
            name: 'permissions', columns: [
                { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' },
                { name: 'name', type: 'varchar', length: '150', isUnique: true },
                { name: 'resource', type: 'varchar', length: '100' },
                { name: 'action', type: 'varchar', length: '50' },
                { name: 'description', type: 'text', isNullable: true },
            ],
        }), true);
        await queryRunner.createIndex('permissions', new typeorm_1.TableIndex({ name: 'IDX_permissions_name', columnNames: ['name'], isUnique: true }));
        await queryRunner.createTable(new typeorm_1.Table({
            name: 'role_permissions', columns: [
                { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' },
                { name: 'roleId', type: 'uuid' }, { name: 'permissionId', type: 'uuid' },
            ],
        }), true);
        await queryRunner.createForeignKey('role_permissions', new typeorm_1.TableForeignKey({ name: 'FK_rp_role', columnNames: ['roleId'], referencedTableName: 'roles', referencedColumnNames: ['id'], onDelete: 'CASCADE' }));
        await queryRunner.createForeignKey('role_permissions', new typeorm_1.TableForeignKey({ name: 'FK_rp_permission', columnNames: ['permissionId'], referencedTableName: 'permissions', referencedColumnNames: ['id'], onDelete: 'CASCADE' }));
        await queryRunner.createTable(new typeorm_1.Table({
            name: 'users', columns: [
                { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' },
                { name: 'email', type: 'varchar', length: '255', isUnique: true },
                { name: 'phoneNumber', type: 'varchar', length: '20', isNullable: true },
                { name: 'passwordHash', type: 'varchar', length: '255' },
                { name: 'firstName', type: 'varchar', length: '100' },
                { name: 'lastName', type: 'varchar', length: '100' },
                { name: 'roleId', type: 'uuid' },
                { name: 'businessId', type: 'uuid', isNullable: true },
                { name: 'isActive', type: 'boolean', default: true },
                { name: 'isVerified', type: 'boolean', default: false },
                { name: 'twoFactorEnabled', type: 'boolean', default: false },
                { name: 'twoFactorSecret', type: 'varchar', length: '255', isNullable: true },
                { name: 'lastLoginAt', type: 'timestamptz', isNullable: true },
                { name: 'lastLoginIp', type: 'varchar', length: '45', isNullable: true },
                { name: 'loginAttempts', type: 'int', default: 0 },
                { name: 'lockedUntil', type: 'timestamptz', isNullable: true },
                { name: 'passwordChangedAt', type: 'timestamptz', isNullable: true },
                { name: 'avatar', type: 'varchar', length: '500', isNullable: true },
                { name: 'createdAt', type: 'timestamptz', default: 'now()' },
                { name: 'updatedAt', type: 'timestamptz', default: 'now()' },
                { name: 'deletedAt', type: 'timestamptz', isNullable: true },
            ],
        }), true);
        await queryRunner.createIndex('users', new typeorm_1.TableIndex({ name: 'IDX_users_email', columnNames: ['email'], isUnique: true }));
        await queryRunner.createForeignKey('users', new typeorm_1.TableForeignKey({ name: 'FK_users_role', columnNames: ['roleId'], referencedTableName: 'roles', referencedColumnNames: ['id'], onDelete: 'RESTRICT' }));
        await queryRunner.createForeignKey('users', new typeorm_1.TableForeignKey({ name: 'FK_users_business', columnNames: ['businessId'], referencedTableName: 'businesses', referencedColumnNames: ['id'], onDelete: 'SET NULL' }));
        await queryRunner.createTable(new typeorm_1.Table({
            name: 'locations', columns: [
                { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' },
                { name: 'businessId', type: 'uuid' },
                { name: 'name', type: 'varchar', length: '255' },
                { name: 'address', type: 'text', isNullable: true },
                { name: 'city', type: 'varchar', length: '100', isNullable: true },
                { name: 'state', type: 'varchar', length: '100', isNullable: true },
                { name: 'country', type: 'varchar', length: '100', isNullable: true },
                { name: 'latitude', type: 'decimal', precision: 10, scale: 7, isNullable: true },
                { name: 'longitude', type: 'decimal', precision: 10, scale: 7, isNullable: true },
                { name: 'isActive', type: 'boolean', default: true },
                { name: 'settings', type: 'jsonb', isNullable: true },
                { name: 'createdAt', type: 'timestamptz', default: 'now()' },
                { name: 'updatedAt', type: 'timestamptz', default: 'now()' },
            ],
        }), true);
        await queryRunner.createForeignKey('locations', new typeorm_1.TableForeignKey({ name: 'FK_locations_business', columnNames: ['businessId'], referencedTableName: 'businesses', referencedColumnNames: ['id'], onDelete: 'CASCADE' }));
        await queryRunner.createIndex('locations', new typeorm_1.TableIndex({ name: 'IDX_locations_businessId', columnNames: ['businessId'] }));
        await queryRunner.createTable(new typeorm_1.Table({
            name: 'routers', columns: [
                { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' },
                { name: 'businessId', type: 'uuid' },
                { name: 'locationId', type: 'uuid', isNullable: true },
                { name: 'name', type: 'varchar', length: '255' },
                { name: 'platform', type: 'enum', enum: ['MIKROTIK', 'UNIFI', 'TP_LINK', 'CISCO', 'PFSENSE', 'GENERIC', 'RADIUS', 'FREERADIUS', 'OPENWRT'], default: `'MIKROTIK'` },
                { name: 'host', type: 'varchar', length: '255' },
                { name: 'apiPort', type: 'int', default: 8728 },
                { name: 'apiUsername', type: 'varchar', length: '255' },
                { name: 'apiPassword', type: 'varchar', length: '500' },
                { name: 'useSsl', type: 'boolean', default: false },
                { name: 'isActive', type: 'boolean', default: true },
                { name: 'isOnline', type: 'boolean', default: false },
                { name: 'lastSeenAt', type: 'timestamptz', isNullable: true },
                { name: 'cpuUsage', type: 'decimal', precision: 5, scale: 2, isNullable: true },
                { name: 'memoryUsage', type: 'decimal', precision: 5, scale: 2, isNullable: true },
                { name: 'uptime', type: 'bigint', isNullable: true },
                { name: 'activeSessions', type: 'int', default: 0 },
                { name: 'metadata', type: 'jsonb', isNullable: true },
                { name: 'createdAt', type: 'timestamptz', default: 'now()' },
                { name: 'updatedAt', type: 'timestamptz', default: 'now()' },
            ],
        }), true);
        await queryRunner.createForeignKey('routers', new typeorm_1.TableForeignKey({ name: 'FK_routers_business', columnNames: ['businessId'], referencedTableName: 'businesses', referencedColumnNames: ['id'], onDelete: 'CASCADE' }));
        await queryRunner.createForeignKey('routers', new typeorm_1.TableForeignKey({ name: 'FK_routers_location', columnNames: ['locationId'], referencedTableName: 'locations', referencedColumnNames: ['id'], onDelete: 'SET NULL' }));
        await queryRunner.createIndex('routers', new typeorm_1.TableIndex({ name: 'IDX_routers_businessId', columnNames: ['businessId'] }));
        await queryRunner.createTable(new typeorm_1.Table({
            name: 'packages', columns: [
                { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' },
                { name: 'businessId', type: 'uuid' },
                { name: 'name', type: 'varchar', length: '255' },
                { name: 'description', type: 'text', isNullable: true },
                { name: 'type', type: 'enum', enum: ['TIME', 'DATA', 'COMBINED', 'DAILY', 'WEEKLY', 'MONTHLY', 'UNLIMITED', 'FREE_TRIAL', 'PROMOTIONAL', 'VOUCHER', 'CUSTOM'] },
                { name: 'priceKes', type: 'decimal', precision: 12, scale: 2, default: 0 },
                { name: 'durationMinutes', type: 'int', isNullable: true },
                { name: 'dataAllowanceMb', type: 'bigint', isNullable: true },
                { name: 'uploadSpeedKbps', type: 'int', isNullable: true },
                { name: 'downloadSpeedKbps', type: 'int', isNullable: true },
                { name: 'maxDevices', type: 'int', default: 1 },
                { name: 'simultaneousConnections', type: 'int', default: 1 },
                { name: 'validityPeriodDays', type: 'int', isNullable: true },
                { name: 'isActive', type: 'boolean', default: true },
                { name: 'isFeatured', type: 'boolean', default: false },
                { name: 'gracePeriodMinutes', type: 'int', default: 0 },
                { name: 'fairUsagePolicyText', type: 'text', isNullable: true },
                { name: 'autoRenew', type: 'boolean', default: false },
                { name: 'taxRate', type: 'decimal', precision: 5, scale: 2, default: 0 },
                { name: 'taxInclusive', type: 'boolean', default: true },
                { name: 'sortOrder', type: 'int', default: 0 },
                { name: 'routerProfile', type: 'varchar', length: '255', isNullable: true },
                { name: 'createdAt', type: 'timestamptz', default: 'now()' },
                { name: 'updatedAt', type: 'timestamptz', default: 'now()' },
            ],
        }), true);
        await queryRunner.createForeignKey('packages', new typeorm_1.TableForeignKey({ name: 'FK_packages_business', columnNames: ['businessId'], referencedTableName: 'businesses', referencedColumnNames: ['id'], onDelete: 'CASCADE' }));
        await queryRunner.createIndex('packages', new typeorm_1.TableIndex({ name: 'IDX_packages_businessId', columnNames: ['businessId'] }));
        await queryRunner.createTable(new typeorm_1.Table({
            name: 'package_router_assignments', columns: [
                { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' },
                { name: 'packageId', type: 'uuid' }, { name: 'routerId', type: 'uuid' },
            ],
        }), true);
        await queryRunner.createForeignKey('package_router_assignments', new typeorm_1.TableForeignKey({ name: 'FK_pra_package', columnNames: ['packageId'], referencedTableName: 'packages', referencedColumnNames: ['id'], onDelete: 'CASCADE' }));
        await queryRunner.createForeignKey('package_router_assignments', new typeorm_1.TableForeignKey({ name: 'FK_pra_router', columnNames: ['routerId'], referencedTableName: 'routers', referencedColumnNames: ['id'], onDelete: 'CASCADE' }));
        await queryRunner.createTable(new typeorm_1.Table({
            name: 'customers', columns: [
                { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' },
                { name: 'businessId', type: 'uuid' },
                { name: 'phoneNumber', type: 'varchar', length: '20' },
                { name: 'email', type: 'varchar', length: '255', isNullable: true },
                { name: 'firstName', type: 'varchar', length: '100', isNullable: true },
                { name: 'lastName', type: 'varchar', length: '100', isNullable: true },
                { name: 'totalPayments', type: 'decimal', precision: 12, scale: 2, default: 0 },
                { name: 'totalSessions', type: 'int', default: 0 },
                { name: 'isBlocked', type: 'boolean', default: false },
                { name: 'blockedReason', type: 'text', isNullable: true },
                { name: 'lastConnectionAt', type: 'timestamptz', isNullable: true },
                { name: 'createdAt', type: 'timestamptz', default: 'now()' },
                { name: 'updatedAt', type: 'timestamptz', default: 'now()' },
            ],
        }), true);
        await queryRunner.createForeignKey('customers', new typeorm_1.TableForeignKey({ name: 'FK_customers_business', columnNames: ['businessId'], referencedTableName: 'businesses', referencedColumnNames: ['id'], onDelete: 'CASCADE' }));
        await queryRunner.createIndex('customers', new typeorm_1.TableIndex({ name: 'IDX_customers_businessId', columnNames: ['businessId'] }));
        await queryRunner.createIndex('customers', new typeorm_1.TableIndex({ name: 'IDX_customers_business_phone', columnNames: ['businessId', 'phoneNumber'], isUnique: true }));
        await queryRunner.createIndex('customers', new typeorm_1.TableIndex({ name: 'IDX_customers_phone', columnNames: ['phoneNumber'] }));
        await queryRunner.createTable(new typeorm_1.Table({
            name: 'customer_devices', columns: [
                { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' },
                { name: 'customerId', type: 'uuid' },
                { name: 'macAddress', type: 'varchar', length: '17' },
                { name: 'ipAddress', type: 'varchar', length: '45', isNullable: true },
                { name: 'deviceName', type: 'varchar', length: '255', isNullable: true },
                { name: 'deviceType', type: 'varchar', length: '100', isNullable: true },
                { name: 'browserInfo', type: 'text', isNullable: true },
                { name: 'firstSeenAt', type: 'timestamptz', default: 'now()' },
                { name: 'lastSeenAt', type: 'timestamptz', isNullable: true },
                { name: 'isBlocked', type: 'boolean', default: false },
                { name: 'createdAt', type: 'timestamptz', default: 'now()' },
            ],
        }), true);
        await queryRunner.createForeignKey('customer_devices', new typeorm_1.TableForeignKey({ name: 'FK_cd_customer', columnNames: ['customerId'], referencedTableName: 'customers', referencedColumnNames: ['id'], onDelete: 'CASCADE' }));
        await queryRunner.createIndex('customer_devices', new typeorm_1.TableIndex({ name: 'IDX_cd_customerId', columnNames: ['customerId'] }));
        await queryRunner.createIndex('customer_devices', new typeorm_1.TableIndex({ name: 'IDX_cd_macAddress', columnNames: ['macAddress'] }));
        await queryRunner.createTable(new typeorm_1.Table({
            name: 'payments', columns: [
                { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' },
                { name: 'businessId', type: 'uuid' },
                { name: 'customerId', type: 'uuid', isNullable: true },
                { name: 'packageId', type: 'uuid' },
                { name: 'routerId', type: 'uuid', isNullable: true },
                { name: 'internalReference', type: 'varchar', length: '100', isUnique: true },
                { name: 'mpesaReceipt', type: 'varchar', length: '50', isUnique: true, isNullable: true },
                { name: 'phoneNumber', type: 'varchar', length: '20' },
                { name: 'amount', type: 'decimal', precision: 12, scale: 2 },
                { name: 'status', type: 'enum', enum: ['CREATED', 'PENDING', 'STK_SENT', 'PROCESSING', 'SUCCESSFUL', 'FAILED', 'CANCELLED', 'TIMED_OUT', 'REVERSED', 'RECONCILIATION_REQUIRED'], default: `'CREATED'` },
                { name: 'merchantRequestId', type: 'varchar', length: '100', isNullable: true },
                { name: 'checkoutRequestId', type: 'varchar', length: '100', isNullable: true },
                { name: 'resultCode', type: 'int', isNullable: true },
                { name: 'resultDescription', type: 'text', isNullable: true },
                { name: 'mpesaCallbackReceived', type: 'boolean', default: false },
                { name: 'callbackPayload', type: 'jsonb', isNullable: true },
                { name: 'attempts', type: 'int', default: 0 },
                { name: 'lastAttemptAt', type: 'timestamptz', isNullable: true },
                { name: 'reconciled', type: 'boolean', default: false },
                { name: 'reconciledAt', type: 'timestamptz', isNullable: true },
                { name: 'notes', type: 'text', isNullable: true },
                { name: 'createdAt', type: 'timestamptz', default: 'now()' },
                { name: 'updatedAt', type: 'timestamptz', default: 'now()' },
            ],
        }), true);
        await queryRunner.createForeignKey('payments', new typeorm_1.TableForeignKey({ name: 'FK_payments_business', columnNames: ['businessId'], referencedTableName: 'businesses', referencedColumnNames: ['id'], onDelete: 'CASCADE' }));
        await queryRunner.createForeignKey('payments', new typeorm_1.TableForeignKey({ name: 'FK_payments_customer', columnNames: ['customerId'], referencedTableName: 'customers', referencedColumnNames: ['id'], onDelete: 'SET NULL' }));
        await queryRunner.createForeignKey('payments', new typeorm_1.TableForeignKey({ name: 'FK_payments_package', columnNames: ['packageId'], referencedTableName: 'packages', referencedColumnNames: ['id'], onDelete: 'RESTRICT' }));
        await queryRunner.createIndex('payments', new typeorm_1.TableIndex({ name: 'IDX_payments_businessId', columnNames: ['businessId'] }));
        await queryRunner.createIndex('payments', new typeorm_1.TableIndex({ name: 'IDX_payments_status', columnNames: ['status'] }));
        await queryRunner.createIndex('payments', new typeorm_1.TableIndex({ name: 'IDX_payments_internalRef', columnNames: ['internalReference'], isUnique: true }));
        await queryRunner.createIndex('payments', new typeorm_1.TableIndex({ name: 'IDX_payments_mpesaReceipt', columnNames: ['mpesaReceipt'], isUnique: true }));
        await queryRunner.createTable(new typeorm_1.Table({
            name: 'payment_attempts', columns: [
                { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' },
                { name: 'paymentId', type: 'uuid' },
                { name: 'attemptNumber', type: 'int' },
                { name: 'status', type: 'varchar', length: '50' },
                { name: 'requestPayload', type: 'jsonb', isNullable: true },
                { name: 'responsePayload', type: 'jsonb', isNullable: true },
                { name: 'errorMessage', type: 'text', isNullable: true },
                { name: 'createdAt', type: 'timestamptz', default: 'now()' },
            ],
        }), true);
        await queryRunner.createForeignKey('payment_attempts', new typeorm_1.TableForeignKey({ name: 'FK_pa_payment', columnNames: ['paymentId'], referencedTableName: 'payments', referencedColumnNames: ['id'], onDelete: 'CASCADE' }));
        await queryRunner.createIndex('payment_attempts', new typeorm_1.TableIndex({ name: 'IDX_pa_paymentId', columnNames: ['paymentId'] }));
        await queryRunner.createTable(new typeorm_1.Table({
            name: 'mpesa_callbacks', columns: [
                { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' },
                { name: 'checkoutRequestId', type: 'varchar', length: '100' },
                { name: 'merchantRequestId', type: 'varchar', length: '100', isNullable: true },
                { name: 'resultCode', type: 'int', isNullable: true },
                { name: 'resultDescription', type: 'text', isNullable: true },
                { name: 'mpesaReceipt', type: 'varchar', length: '50', isNullable: true },
                { name: 'phoneNumber', type: 'varchar', length: '20', isNullable: true },
                { name: 'amount', type: 'decimal', precision: 12, scale: 2, isNullable: true },
                { name: 'rawPayload', type: 'jsonb' },
                { name: 'processed', type: 'boolean', default: false },
                { name: 'duplicate', type: 'boolean', default: false },
                { name: 'receivedAt', type: 'timestamptz' },
                { name: 'processedAt', type: 'timestamptz', isNullable: true },
                { name: 'createdAt', type: 'timestamptz', default: 'now()' },
            ],
        }), true);
        await queryRunner.createIndex('mpesa_callbacks', new typeorm_1.TableIndex({ name: 'IDX_mc_checkoutReqId', columnNames: ['checkoutRequestId'] }));
        await queryRunner.createIndex('mpesa_callbacks', new typeorm_1.TableIndex({ name: 'IDX_mc_mpesaReceipt', columnNames: ['mpesaReceipt'] }));
        await queryRunner.createTable(new typeorm_1.Table({
            name: 'mpesa_reconciliations', columns: [
                { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' },
                { name: 'paymentId', type: 'uuid' },
                { name: 'checkoutRequestId', type: 'varchar', length: '100' },
                { name: 'reconciliationStatus', type: 'varchar', length: '50' },
                { name: 'responsePayload', type: 'jsonb', isNullable: true },
                { name: 'errorMessage', type: 'text', isNullable: true },
                { name: 'reconciledAt', type: 'timestamptz', isNullable: true },
                { name: 'createdAt', type: 'timestamptz', default: 'now()' },
            ],
        }), true);
        await queryRunner.createForeignKey('mpesa_reconciliations', new typeorm_1.TableForeignKey({ name: 'FK_mr_payment', columnNames: ['paymentId'], referencedTableName: 'payments', referencedColumnNames: ['id'], onDelete: 'CASCADE' }));
        await queryRunner.createIndex('mpesa_reconciliations', new typeorm_1.TableIndex({ name: 'IDX_mr_paymentId', columnNames: ['paymentId'] }));
        await queryRunner.createTable(new typeorm_1.Table({
            name: 'wifi_sessions', columns: [
                { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' },
                { name: 'customerId', type: 'uuid' },
                { name: 'packageId', type: 'uuid' },
                { name: 'routerId', type: 'uuid' },
                { name: 'businessId', type: 'uuid' },
                { name: 'deviceId', type: 'uuid', isNullable: true },
                { name: 'status', type: 'enum', enum: ['PENDING_ACTIVATION', 'ACTIVE', 'PAUSED', 'EXPIRED', 'DATA_EXHAUSTED', 'DISCONNECTED', 'CANCELLED', 'ACTIVATION_FAILED'], default: `'PENDING_ACTIVATION'` },
                { name: 'startTime', type: 'timestamptz', isNullable: true },
                { name: 'endTime', type: 'timestamptz', isNullable: true },
                { name: 'expiryTime', type: 'timestamptz', isNullable: true },
                { name: 'remainingDataMb', type: 'bigint', isNullable: true },
                { name: 'dataUsedMb', type: 'decimal', precision: 12, scale: 2, default: 0 },
                { name: 'ipAddress', type: 'varchar', length: '45', isNullable: true },
                { name: 'macAddress', type: 'varchar', length: '17', isNullable: true },
                { name: 'sessionKey', type: 'varchar', length: '255', isNullable: true },
                { name: 'routerSessionId', type: 'varchar', length: '255', isNullable: true },
                { name: 'activationAttempts', type: 'int', default: 0 },
                { name: 'lastActivationError', type: 'text', isNullable: true },
                { name: 'disconnectedAt', type: 'timestamptz', isNullable: true },
                { name: 'createdAt', type: 'timestamptz', default: 'now()' },
                { name: 'updatedAt', type: 'timestamptz', default: 'now()' },
            ],
        }), true);
        await queryRunner.createForeignKey('wifi_sessions', new typeorm_1.TableForeignKey({ name: 'FK_ws_customer', columnNames: ['customerId'], referencedTableName: 'customers', referencedColumnNames: ['id'], onDelete: 'CASCADE' }));
        await queryRunner.createForeignKey('wifi_sessions', new typeorm_1.TableForeignKey({ name: 'FK_ws_package', columnNames: ['packageId'], referencedTableName: 'packages', referencedColumnNames: ['id'], onDelete: 'RESTRICT' }));
        await queryRunner.createForeignKey('wifi_sessions', new typeorm_1.TableForeignKey({ name: 'FK_ws_router', columnNames: ['routerId'], referencedTableName: 'routers', referencedColumnNames: ['id'], onDelete: 'CASCADE' }));
        await queryRunner.createForeignKey('wifi_sessions', new typeorm_1.TableForeignKey({ name: 'FK_ws_business', columnNames: ['businessId'], referencedTableName: 'businesses', referencedColumnNames: ['id'], onDelete: 'CASCADE' }));
        await queryRunner.createForeignKey('wifi_sessions', new typeorm_1.TableForeignKey({ name: 'FK_ws_device', columnNames: ['deviceId'], referencedTableName: 'customer_devices', referencedColumnNames: ['id'], onDelete: 'SET NULL' }));
        await queryRunner.createIndex('wifi_sessions', new typeorm_1.TableIndex({ name: 'IDX_ws_customerId', columnNames: ['customerId'] }));
        await queryRunner.createIndex('wifi_sessions', new typeorm_1.TableIndex({ name: 'IDX_ws_routerId', columnNames: ['routerId'] }));
        await queryRunner.createIndex('wifi_sessions', new typeorm_1.TableIndex({ name: 'IDX_ws_businessId', columnNames: ['businessId'] }));
        await queryRunner.createIndex('wifi_sessions', new typeorm_1.TableIndex({ name: 'IDX_ws_status', columnNames: ['status'] }));
        await queryRunner.createTable(new typeorm_1.Table({
            name: 'radius_accounts', columns: [
                { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' },
                { name: 'businessId', type: 'uuid' },
                { name: 'customerId', type: 'uuid' },
                { name: 'username', type: 'varchar', length: '100', isUnique: true },
                { name: 'password', type: 'varchar', length: '500' },
                { name: 'callingStationId', type: 'varchar', length: '255', isNullable: true },
                { name: 'framedIpAddress', type: 'varchar', length: '45', isNullable: true },
                { name: 'nasIpAddress', type: 'varchar', length: '45', isNullable: true },
                { name: 'simultaneousUse', type: 'int', default: 1 },
                { name: 'sessionTimeout', type: 'int', isNullable: true },
                { name: 'idleTimeout', type: 'int', isNullable: true },
                { name: 'isActive', type: 'boolean', default: true },
                { name: 'createdAt', type: 'timestamptz', default: 'now()' },
                { name: 'updatedAt', type: 'timestamptz', default: 'now()' },
            ],
        }), true);
        await queryRunner.createForeignKey('radius_accounts', new typeorm_1.TableForeignKey({ name: 'FK_ra_business', columnNames: ['businessId'], referencedTableName: 'businesses', referencedColumnNames: ['id'], onDelete: 'CASCADE' }));
        await queryRunner.createForeignKey('radius_accounts', new typeorm_1.TableForeignKey({ name: 'FK_ra_customer', columnNames: ['customerId'], referencedTableName: 'customers', referencedColumnNames: ['id'], onDelete: 'CASCADE' }));
        await queryRunner.createIndex('radius_accounts', new typeorm_1.TableIndex({ name: 'IDX_ra_username', columnNames: ['username'], isUnique: true }));
        await queryRunner.createIndex('radius_accounts', new typeorm_1.TableIndex({ name: 'IDX_ra_businessId', columnNames: ['businessId'] }));
        await queryRunner.createTable(new typeorm_1.Table({
            name: 'vouchers', columns: [
                { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' },
                { name: 'businessId', type: 'uuid' },
                { name: 'batchId', type: 'uuid', isNullable: true },
                { name: 'code', type: 'varchar', length: '50', isUnique: true },
                { name: 'packageId', type: 'uuid' },
                { name: 'status', type: 'enum', enum: ['UNUSED', 'USED', 'DISABLED', 'EXPIRED'], default: `'UNUSED'` },
                { name: 'usedByCustomerId', type: 'uuid', isNullable: true },
                { name: 'usedAt', type: 'timestamptz', isNullable: true },
                { name: 'expiryDate', type: 'timestamptz', isNullable: true },
                { name: 'createdAt', type: 'timestamptz', default: 'now()' },
            ],
        }), true);
        await queryRunner.createForeignKey('vouchers', new typeorm_1.TableForeignKey({ name: 'FK_vouchers_business', columnNames: ['businessId'], referencedTableName: 'businesses', referencedColumnNames: ['id'], onDelete: 'CASCADE' }));
        await queryRunner.createForeignKey('vouchers', new typeorm_1.TableForeignKey({ name: 'FK_vouchers_package', columnNames: ['packageId'], referencedTableName: 'packages', referencedColumnNames: ['id'], onDelete: 'RESTRICT' }));
        await queryRunner.createIndex('vouchers', new typeorm_1.TableIndex({ name: 'IDX_vouchers_code', columnNames: ['code'], isUnique: true }));
        await queryRunner.createIndex('vouchers', new typeorm_1.TableIndex({ name: 'IDX_vouchers_businessId', columnNames: ['businessId'] }));
        await queryRunner.createTable(new typeorm_1.Table({
            name: 'voucher_batches', columns: [
                { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' },
                { name: 'businessId', type: 'uuid' },
                { name: 'prefix', type: 'varchar', length: '50' },
                { name: 'count', type: 'int' },
                { name: 'generatedBy', type: 'uuid' },
                { name: 'packageId', type: 'uuid' },
                { name: 'expiryDate', type: 'timestamptz', isNullable: true },
                { name: 'notes', type: 'text', isNullable: true },
                { name: 'createdAt', type: 'timestamptz', default: 'now()' },
            ],
        }), true);
        await queryRunner.createForeignKey('voucher_batches', new typeorm_1.TableForeignKey({ name: 'FK_vb_business', columnNames: ['businessId'], referencedTableName: 'businesses', referencedColumnNames: ['id'], onDelete: 'CASCADE' }));
        await queryRunner.createForeignKey('voucher_batches', new typeorm_1.TableForeignKey({ name: 'FK_vb_package', columnNames: ['packageId'], referencedTableName: 'packages', referencedColumnNames: ['id'], onDelete: 'RESTRICT' }));
        await queryRunner.createIndex('voucher_batches', new typeorm_1.TableIndex({ name: 'IDX_vb_businessId', columnNames: ['businessId'] }));
        await queryRunner.createTable(new typeorm_1.Table({
            name: 'invoices', columns: [
                { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' },
                { name: 'businessId', type: 'uuid' },
                { name: 'paymentId', type: 'uuid' },
                { name: 'invoiceNumber', type: 'varchar', length: '100', isUnique: true },
                { name: 'customerId', type: 'uuid' },
                { name: 'amount', type: 'decimal', precision: 12, scale: 2 },
                { name: 'taxAmount', type: 'decimal', precision: 12, scale: 2, default: 0 },
                { name: 'totalAmount', type: 'decimal', precision: 12, scale: 2 },
                { name: 'status', type: 'varchar', length: '50', default: `'PENDING'` },
                { name: 'items', type: 'jsonb', isNullable: true },
                { name: 'dueDate', type: 'timestamptz', isNullable: true },
                { name: 'paidAt', type: 'timestamptz', isNullable: true },
                { name: 'pdfUrl', type: 'varchar', length: '500', isNullable: true },
                { name: 'createdAt', type: 'timestamptz', default: 'now()' },
                { name: 'updatedAt', type: 'timestamptz', default: 'now()' },
            ],
        }), true);
        await queryRunner.createForeignKey('invoices', new typeorm_1.TableForeignKey({ name: 'FK_invoices_business', columnNames: ['businessId'], referencedTableName: 'businesses', referencedColumnNames: ['id'], onDelete: 'CASCADE' }));
        await queryRunner.createForeignKey('invoices', new typeorm_1.TableForeignKey({ name: 'FK_invoices_payment', columnNames: ['paymentId'], referencedTableName: 'payments', referencedColumnNames: ['id'], onDelete: 'CASCADE' }));
        await queryRunner.createForeignKey('invoices', new typeorm_1.TableForeignKey({ name: 'FK_invoices_customer', columnNames: ['customerId'], referencedTableName: 'customers', referencedColumnNames: ['id'], onDelete: 'CASCADE' }));
        await queryRunner.createIndex('invoices', new typeorm_1.TableIndex({ name: 'IDX_invoices_invoiceNumber', columnNames: ['invoiceNumber'], isUnique: true }));
        await queryRunner.createIndex('invoices', new typeorm_1.TableIndex({ name: 'IDX_invoices_businessId', columnNames: ['businessId'] }));
        await queryRunner.createTable(new typeorm_1.Table({
            name: 'receipts', columns: [
                { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' },
                { name: 'businessId', type: 'uuid' },
                { name: 'paymentId', type: 'uuid', isUnique: true },
                { name: 'receiptNumber', type: 'varchar', length: '100', isUnique: true },
                { name: 'customerId', type: 'uuid' },
                { name: 'amount', type: 'decimal', precision: 12, scale: 2 },
                { name: 'taxDetails', type: 'jsonb', isNullable: true },
                { name: 'paymentMethod', type: 'varchar', length: '50', default: `'MPESA'` },
                { name: 'mpesaReceipt', type: 'varchar', length: '50', isNullable: true },
                { name: 'createdAt', type: 'timestamptz', default: 'now()' },
            ],
        }), true);
        await queryRunner.createForeignKey('receipts', new typeorm_1.TableForeignKey({ name: 'FK_receipts_business', columnNames: ['businessId'], referencedTableName: 'businesses', referencedColumnNames: ['id'], onDelete: 'CASCADE' }));
        await queryRunner.createForeignKey('receipts', new typeorm_1.TableForeignKey({ name: 'FK_receipts_payment', columnNames: ['paymentId'], referencedTableName: 'payments', referencedColumnNames: ['id'], onDelete: 'CASCADE' }));
        await queryRunner.createForeignKey('receipts', new typeorm_1.TableForeignKey({ name: 'FK_receipts_customer', columnNames: ['customerId'], referencedTableName: 'customers', referencedColumnNames: ['id'], onDelete: 'CASCADE' }));
        await queryRunner.createIndex('receipts', new typeorm_1.TableIndex({ name: 'IDX_receipts_receiptNumber', columnNames: ['receiptNumber'], isUnique: true }));
        await queryRunner.createIndex('receipts', new typeorm_1.TableIndex({ name: 'IDX_receipts_businessId', columnNames: ['businessId'] }));
        await queryRunner.createTable(new typeorm_1.Table({
            name: 'transactions', columns: [
                { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' },
                { name: 'businessId', type: 'uuid' },
                { name: 'customerId', type: 'uuid', isNullable: true },
                { name: 'paymentId', type: 'uuid', isNullable: true },
                { name: 'type', type: 'enum', enum: ['PAYMENT', 'REFUND', 'COMMISSION', 'SUBSCRIPTION', 'ADJUSTMENT'] },
                { name: 'amount', type: 'decimal', precision: 12, scale: 2 },
                { name: 'balanceBefore', type: 'decimal', precision: 12, scale: 2, default: 0 },
                { name: 'balanceAfter', type: 'decimal', precision: 12, scale: 2, default: 0 },
                { name: 'description', type: 'text', isNullable: true },
                { name: 'referenceId', type: 'varchar', length: '255', isNullable: true },
                { name: 'createdAt', type: 'timestamptz', default: 'now()' },
            ],
        }), true);
        await queryRunner.createForeignKey('transactions', new typeorm_1.TableForeignKey({ name: 'FK_tx_business', columnNames: ['businessId'], referencedTableName: 'businesses', referencedColumnNames: ['id'], onDelete: 'CASCADE' }));
        await queryRunner.createForeignKey('transactions', new typeorm_1.TableForeignKey({ name: 'FK_tx_customer', columnNames: ['customerId'], referencedTableName: 'customers', referencedColumnNames: ['id'], onDelete: 'SET NULL' }));
        await queryRunner.createForeignKey('transactions', new typeorm_1.TableForeignKey({ name: 'FK_tx_payment', columnNames: ['paymentId'], referencedTableName: 'payments', referencedColumnNames: ['id'], onDelete: 'SET NULL' }));
        await queryRunner.createIndex('transactions', new typeorm_1.TableIndex({ name: 'IDX_tx_businessId', columnNames: ['businessId'] }));
        await queryRunner.createIndex('transactions', new typeorm_1.TableIndex({ name: 'IDX_tx_type', columnNames: ['type'] }));
        await queryRunner.createTable(new typeorm_1.Table({
            name: 'commissions', columns: [
                { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' },
                { name: 'businessId', type: 'uuid' },
                { name: 'paymentId', type: 'uuid' },
                { name: 'amount', type: 'decimal', precision: 12, scale: 2 },
                { name: 'rate', type: 'decimal', precision: 5, scale: 2 },
                { name: 'status', type: 'enum', enum: ['PENDING', 'PAID'], default: `'PENDING'` },
                { name: 'paidAt', type: 'timestamptz', isNullable: true },
                { name: 'createdAt', type: 'timestamptz', default: 'now()' },
            ],
        }), true);
        await queryRunner.createForeignKey('commissions', new typeorm_1.TableForeignKey({ name: 'FK_comm_business', columnNames: ['businessId'], referencedTableName: 'businesses', referencedColumnNames: ['id'], onDelete: 'CASCADE' }));
        await queryRunner.createForeignKey('commissions', new typeorm_1.TableForeignKey({ name: 'FK_comm_payment', columnNames: ['paymentId'], referencedTableName: 'payments', referencedColumnNames: ['id'], onDelete: 'CASCADE' }));
        await queryRunner.createIndex('commissions', new typeorm_1.TableIndex({ name: 'IDX_comm_businessId', columnNames: ['businessId'] }));
        await queryRunner.createTable(new typeorm_1.Table({
            name: 'notifications', columns: [
                { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' },
                { name: 'businessId', type: 'uuid' },
                { name: 'userId', type: 'uuid', isNullable: true },
                { name: 'customerId', type: 'uuid', isNullable: true },
                { name: 'type', type: 'enum', enum: ['SMS', 'EMAIL', 'WHATSAPP', 'IN_APP'] },
                { name: 'templateKey', type: 'varchar', length: '100', isNullable: true },
                { name: 'recipient', type: 'varchar', length: '255' },
                { name: 'subject', type: 'varchar', length: '500', isNullable: true },
                { name: 'body', type: 'text' },
                { name: 'status', type: 'enum', enum: ['PENDING', 'SENT', 'FAILED', 'DELIVERED'], default: `'PENDING'` },
                { name: 'sentAt', type: 'timestamptz', isNullable: true },
                { name: 'deliveredAt', type: 'timestamptz', isNullable: true },
                { name: 'errorMessage', type: 'text', isNullable: true },
                { name: 'createdAt', type: 'timestamptz', default: 'now()' },
            ],
        }), true);
        await queryRunner.createIndex('notifications', new typeorm_1.TableIndex({ name: 'IDX_notif_businessId', columnNames: ['businessId'] }));
        await queryRunner.createTable(new typeorm_1.Table({
            name: 'notification_templates', columns: [
                { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' },
                { name: 'businessId', type: 'uuid' },
                { name: 'key', type: 'varchar', length: '100' },
                { name: 'name', type: 'varchar', length: '255' },
                { name: 'type', type: 'varchar', length: '50' },
                { name: 'subject', type: 'varchar', length: '500', isNullable: true },
                { name: 'bodyTemplate', type: 'text' },
                { name: 'variables', type: 'jsonb', isNullable: true },
                { name: 'isDefault', type: 'boolean', default: false },
                { name: 'createdAt', type: 'timestamptz', default: 'now()' },
                { name: 'updatedAt', type: 'timestamptz', default: 'now()' },
            ],
        }), true);
        await queryRunner.createForeignKey('notification_templates', new typeorm_1.TableForeignKey({ name: 'FK_nt_business', columnNames: ['businessId'], referencedTableName: 'businesses', referencedColumnNames: ['id'], onDelete: 'CASCADE' }));
        await queryRunner.createIndex('notification_templates', new typeorm_1.TableIndex({ name: 'IDX_nt_business_key', columnNames: ['businessId', 'key'], isUnique: true }));
        await queryRunner.createTable(new typeorm_1.Table({
            name: 'support_tickets', columns: [
                { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' },
                { name: 'businessId', type: 'uuid' },
                { name: 'customerId', type: 'uuid', isNullable: true },
                { name: 'userId', type: 'uuid', isNullable: true },
                { name: 'subject', type: 'varchar', length: '500' },
                { name: 'description', type: 'text' },
                { name: 'status', type: 'enum', enum: ['OPEN', 'IN_PROGRESS', 'RESOLVED', 'CLOSED'], default: `'OPEN'` },
                { name: 'priority', type: 'enum', enum: ['LOW', 'MEDIUM', 'HIGH', 'URGENT'], default: `'MEDIUM'` },
                { name: 'createdAt', type: 'timestamptz', default: 'now()' },
                { name: 'updatedAt', type: 'timestamptz', default: 'now()' },
            ],
        }), true);
        await queryRunner.createForeignKey('support_tickets', new typeorm_1.TableForeignKey({ name: 'FK_st_business', columnNames: ['businessId'], referencedTableName: 'businesses', referencedColumnNames: ['id'], onDelete: 'CASCADE' }));
        await queryRunner.createForeignKey('support_tickets', new typeorm_1.TableForeignKey({ name: 'FK_st_customer', columnNames: ['customerId'], referencedTableName: 'customers', referencedColumnNames: ['id'], onDelete: 'SET NULL' }));
        await queryRunner.createForeignKey('support_tickets', new typeorm_1.TableForeignKey({ name: 'FK_st_user', columnNames: ['userId'], referencedTableName: 'users', referencedColumnNames: ['id'], onDelete: 'SET NULL' }));
        await queryRunner.createIndex('support_tickets', new typeorm_1.TableIndex({ name: 'IDX_st_businessId', columnNames: ['businessId'] }));
        await queryRunner.createIndex('support_tickets', new typeorm_1.TableIndex({ name: 'IDX_st_status', columnNames: ['status'] }));
        await queryRunner.createTable(new typeorm_1.Table({
            name: 'audit_logs', columns: [
                { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' },
                { name: 'businessId', type: 'uuid', isNullable: true },
                { name: 'userId', type: 'uuid', isNullable: true },
                { name: 'action', type: 'varchar', length: '100' },
                { name: 'entityType', type: 'varchar', length: '100' },
                { name: 'entityId', type: 'varchar', length: '100' },
                { name: 'previousValue', type: 'jsonb', isNullable: true },
                { name: 'newValue', type: 'jsonb', isNullable: true },
                { name: 'ipAddress', type: 'varchar', length: '45', isNullable: true },
                { name: 'userAgent', type: 'text', isNullable: true },
                { name: 'createdAt', type: 'timestamptz', default: 'now()' },
            ],
        }), true);
        await queryRunner.createForeignKey('audit_logs', new typeorm_1.TableForeignKey({ name: 'FK_al_business', columnNames: ['businessId'], referencedTableName: 'businesses', referencedColumnNames: ['id'], onDelete: 'SET NULL' }));
        await queryRunner.createForeignKey('audit_logs', new typeorm_1.TableForeignKey({ name: 'FK_al_user', columnNames: ['userId'], referencedTableName: 'users', referencedColumnNames: ['id'], onDelete: 'SET NULL' }));
        await queryRunner.createIndex('audit_logs', new typeorm_1.TableIndex({ name: 'IDX_al_businessId', columnNames: ['businessId'] }));
        await queryRunner.createIndex('audit_logs', new typeorm_1.TableIndex({ name: 'IDX_al_entity', columnNames: ['entityType', 'entityId'] }));
        await queryRunner.createIndex('audit_logs', new typeorm_1.TableIndex({ name: 'IDX_al_action', columnNames: ['action'] }));
        await queryRunner.createTable(new typeorm_1.Table({
            name: 'api_logs', columns: [
                { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' },
                { name: 'businessId', type: 'uuid', isNullable: true },
                { name: 'method', type: 'varchar', length: '10' },
                { name: 'url', type: 'varchar', length: '500' },
                { name: 'requestBody', type: 'text', isNullable: true },
                { name: 'responseBody', type: 'text', isNullable: true },
                { name: 'statusCode', type: 'int' },
                { name: 'ipAddress', type: 'varchar', length: '45', isNullable: true },
                { name: 'userAgent', type: 'text', isNullable: true },
                { name: 'durationMs', type: 'int', default: 0 },
                { name: 'createdAt', type: 'timestamptz', default: 'now()' },
            ],
        }), true);
        await queryRunner.createIndex('api_logs', new typeorm_1.TableIndex({ name: 'IDX_apilog_businessId', columnNames: ['businessId'] }));
        await queryRunner.createIndex('api_logs', new typeorm_1.TableIndex({ name: 'IDX_apilog_method_url', columnNames: ['method', 'url'] }));
        await queryRunner.createIndex('api_logs', new typeorm_1.TableIndex({ name: 'IDX_apilog_statusCode', columnNames: ['statusCode'] }));
        await queryRunner.createTable(new typeorm_1.Table({
            name: 'system_settings', columns: [
                { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' },
                { name: 'key', type: 'varchar', length: '200', isUnique: true },
                { name: 'value', type: 'text' },
                { name: 'description', type: 'text', isNullable: true },
                { name: 'isEncrypted', type: 'boolean', default: false },
                { name: 'isPublic', type: 'boolean', default: false },
                { name: 'updatedAt', type: 'timestamptz', default: 'now()' },
            ],
        }), true);
        await queryRunner.createIndex('system_settings', new typeorm_1.TableIndex({ name: 'IDX_ss_key', columnNames: ['key'], isUnique: true }));
        await queryRunner.createTable(new typeorm_1.Table({
            name: 'business_settings', columns: [
                { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' },
                { name: 'businessId', type: 'uuid' },
                { name: 'key', type: 'varchar', length: '200' },
                { name: 'value', type: 'text' },
                { name: 'description', type: 'text', isNullable: true },
                { name: 'isEncrypted', type: 'boolean', default: false },
                { name: 'updatedAt', type: 'timestamptz', default: 'now()' },
            ],
        }), true);
        await queryRunner.createForeignKey('business_settings', new typeorm_1.TableForeignKey({ name: 'FK_bs_business', columnNames: ['businessId'], referencedTableName: 'businesses', referencedColumnNames: ['id'], onDelete: 'CASCADE' }));
        await queryRunner.createIndex('business_settings', new typeorm_1.TableIndex({ name: 'IDX_bs_business_key', columnNames: ['businessId', 'key'], isUnique: true }));
        await queryRunner.createTable(new typeorm_1.Table({
            name: 'background_jobs', columns: [
                { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' },
                { name: 'jobId', type: 'varchar', length: '255', isUnique: true },
                { name: 'queue', type: 'varchar', length: '100' },
                { name: 'name', type: 'varchar', length: '255' },
                { name: 'data', type: 'jsonb', isNullable: true },
                { name: 'status', type: 'enum', enum: ['PENDING', 'ACTIVE', 'COMPLETED', 'FAILED', 'RETRYING'], default: `'PENDING'` },
                { name: 'attempts', type: 'int', default: 0 },
                { name: 'maxAttempts', type: 'int', default: 3 },
                { name: 'errorMessage', type: 'text', isNullable: true },
                { name: 'scheduledAt', type: 'timestamptz', isNullable: true },
                { name: 'startedAt', type: 'timestamptz', isNullable: true },
                { name: 'completedAt', type: 'timestamptz', isNullable: true },
                { name: 'createdAt', type: 'timestamptz', default: 'now()' },
                { name: 'updatedAt', type: 'timestamptz', default: 'now()' },
            ],
        }), true);
        await queryRunner.createIndex('background_jobs', new typeorm_1.TableIndex({ name: 'IDX_bj_jobId', columnNames: ['jobId'], isUnique: true }));
        await queryRunner.createIndex('background_jobs', new typeorm_1.TableIndex({ name: 'IDX_bj_queue', columnNames: ['queue'] }));
        await queryRunner.createIndex('background_jobs', new typeorm_1.TableIndex({ name: 'IDX_bj_status', columnNames: ['status'] }));
        await queryRunner.createTable(new typeorm_1.Table({
            name: 'failed_jobs', columns: [
                { name: 'id', type: 'uuid', isPrimary: true, default: 'uuid_generate_v4()' },
                { name: 'jobId', type: 'varchar', length: '255' },
                { name: 'queue', type: 'varchar', length: '100' },
                { name: 'name', type: 'varchar', length: '255' },
                { name: 'data', type: 'jsonb', isNullable: true },
                { name: 'errorMessage', type: 'text', isNullable: true },
                { name: 'errorStack', type: 'text', isNullable: true },
                { name: 'failedAt', type: 'timestamptz', default: 'now()' },
            ],
        }), true);
        await queryRunner.createIndex('failed_jobs', new typeorm_1.TableIndex({ name: 'IDX_fj_jobId', columnNames: ['jobId'] }));
        await queryRunner.createIndex('failed_jobs', new typeorm_1.TableIndex({ name: 'IDX_fj_queue', columnNames: ['queue'] }));
    }
    async down(queryRunner) {
        await queryRunner.dropTable('failed_jobs', true);
        await queryRunner.dropTable('background_jobs', true);
        await queryRunner.dropTable('business_settings', true);
        await queryRunner.dropTable('system_settings', true);
        await queryRunner.dropTable('api_logs', true);
        await queryRunner.dropTable('audit_logs', true);
        await queryRunner.dropTable('support_tickets', true);
        await queryRunner.dropTable('notification_templates', true);
        await queryRunner.dropTable('notifications', true);
        await queryRunner.dropTable('commissions', true);
        await queryRunner.dropTable('transactions', true);
        await queryRunner.dropTable('receipts', true);
        await queryRunner.dropTable('invoices', true);
        await queryRunner.dropTable('voucher_batches', true);
        await queryRunner.dropTable('vouchers', true);
        await queryRunner.dropTable('radius_accounts', true);
        await queryRunner.dropTable('wifi_sessions', true);
        await queryRunner.dropTable('mpesa_reconciliations', true);
        await queryRunner.dropTable('mpesa_callbacks', true);
        await queryRunner.dropTable('payment_attempts', true);
        await queryRunner.dropTable('payments', true);
        await queryRunner.dropTable('customer_devices', true);
        await queryRunner.dropTable('customers', true);
        await queryRunner.dropTable('package_router_assignments', true);
        await queryRunner.dropTable('packages', true);
        await queryRunner.dropTable('routers', true);
        await queryRunner.dropTable('locations', true);
        await queryRunner.dropTable('users', true);
        await queryRunner.dropTable('role_permissions', true);
        await queryRunner.dropTable('permissions', true);
        await queryRunner.dropTable('roles', true);
        await queryRunner.dropTable('subscriptions', true);
        await queryRunner.dropTable('subscription_plans', true);
        await queryRunner.dropTable('businesses', true);
    }
}
exports.InitialSchema1700000000000 = InitialSchema1700000000000;
