courseworx/backend/test-migration.js
mmabdalla 5477297914 v2.0.2 - Complete Plugin Architecture System and Multi-Currency Implementation
Major Features Added:
- Complete Plugin Architecture System with financial plugin
- Multi-currency support with exchange rates
- Course type system (online, classroom, hybrid)
- Attendance tracking and QR code scanning
- Classroom sessions management
- Course sections and content management
- Professional video player with authentication
- Secure media serving system
- Shopping cart and checkout system
- Financial dashboard and earnings tracking
- Trainee progress tracking
- User notes and assignments system

Backend Infrastructure:
- Plugin loader and registry system
- Multi-currency database models
- Secure media middleware
- Course access middleware
- Financial plugin with payment processing
- Database migrations for new features
- API endpoints for all new functionality

Frontend Components:
- Course management interface
- Content creation and editing
- Section management with drag-and-drop
- Professional video player
- QR scanner for attendance
- Shopping cart and checkout flow
- Financial dashboard
- Plugin management interface
- Trainee details and progress views

This represents a major evolution of CourseWorx from a basic LMS to a comprehensive educational platform with plugin architecture.
2025-09-14 04:20:37 +03:00

116 lines
4.5 KiB
JavaScript

/**
* Manual Migration Runner for Currency Tables
* Run this to create the currency tables
*/
const { sequelize } = require('./config/database');
const { DataTypes } = require('sequelize');
async function runMigration() {
try {
console.log('🚀 Starting currency tables migration...');
// Create currencies table
await sequelize.query(`
CREATE TABLE IF NOT EXISTS currencies (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
code VARCHAR(3) UNIQUE NOT NULL,
name VARCHAR NOT NULL,
symbol VARCHAR(10) NOT NULL,
"decimalPlaces" INTEGER NOT NULL DEFAULT 2,
"isActive" BOOLEAN DEFAULT true,
"isBaseCurrency" BOOLEAN DEFAULT false,
"bankAccountDetails" JSONB,
metadata JSONB DEFAULT '{}',
"createdAt" TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
"updatedAt" TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
`);
// Create exchange_rates table
await sequelize.query(`
CREATE TABLE IF NOT EXISTS exchange_rates (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
"fromCurrencyId" UUID NOT NULL REFERENCES currencies(id),
"toCurrencyId" UUID NOT NULL REFERENCES currencies(id),
rate DECIMAL(15,8) NOT NULL,
"effectiveDate" TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
"expiryDate" TIMESTAMP WITH TIME ZONE,
"isActive" BOOLEAN DEFAULT true,
source VARCHAR DEFAULT 'manual',
notes TEXT,
"createdBy" UUID REFERENCES users(id),
"createdAt" TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
"updatedAt" TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
`);
// Create exchange_rate_history table
await sequelize.query(`
CREATE TABLE IF NOT EXISTS exchange_rate_history (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
"exchangeRateId" UUID NOT NULL REFERENCES exchange_rates(id),
"fromCurrencyId" UUID NOT NULL REFERENCES currencies(id),
"toCurrencyId" UUID NOT NULL REFERENCES currencies(id),
"previousRate" DECIMAL(15,8),
"newRate" DECIMAL(15,8) NOT NULL,
"changePercentage" DECIMAL(8,4),
"changeDate" TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
"changeReason" VARCHAR DEFAULT 'manual_update',
"changedBy" UUID REFERENCES users(id),
notes TEXT,
"createdAt" TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
"updatedAt" TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
`);
// Create course_currencies table
await sequelize.query(`
CREATE TABLE IF NOT EXISTS course_currencies (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
"courseId" UUID NOT NULL REFERENCES courses(id),
"baseCurrencyId" UUID NOT NULL REFERENCES currencies(id),
"basePrice" DECIMAL(10,2) NOT NULL,
"allowedPaymentCurrencies" UUID[] DEFAULT '{}',
"customExchangeRates" JSONB DEFAULT '{}',
"isActive" BOOLEAN DEFAULT true,
metadata JSONB DEFAULT '{}',
"createdAt" TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
"updatedAt" TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
`);
// Create indexes
await sequelize.query(`CREATE INDEX IF NOT EXISTS idx_currencies_code ON currencies(code);`);
await sequelize.query(`CREATE INDEX IF NOT EXISTS idx_currencies_active ON currencies("isActive");`);
await sequelize.query(`CREATE INDEX IF NOT EXISTS idx_currencies_base ON currencies("isBaseCurrency");`);
await sequelize.query(`CREATE INDEX IF NOT EXISTS idx_exchange_rates_pair ON exchange_rates("fromCurrencyId", "toCurrencyId");`);
await sequelize.query(`CREATE INDEX IF NOT EXISTS idx_exchange_rates_date ON exchange_rates("effectiveDate");`);
await sequelize.query(`CREATE INDEX IF NOT EXISTS idx_exchange_rates_active ON exchange_rates("isActive");`);
await sequelize.query(`CREATE INDEX IF NOT EXISTS idx_course_currencies_course ON course_currencies("courseId");`);
await sequelize.query(`CREATE INDEX IF NOT EXISTS idx_course_currencies_base ON course_currencies("baseCurrencyId");`);
console.log('✅ Currency tables migration completed successfully!');
} catch (error) {
console.error('❌ Migration failed:', error.message);
throw error;
}
}
// Run migration if this script is executed directly
if (require.main === module) {
runMigration()
.then(() => {
console.log('🎉 Migration completed!');
process.exit(0);
})
.catch((error) => {
console.error('💥 Migration failed:', error);
process.exit(1);
});
}
module.exports = { runMigration };