Эх сурвалжийг харах

refactor: Remove unnecessary migrations for fresh deployment

Remove old migration files entirely as they are not needed for first-time
deployment. The migrations were designed to upgrade an old database schema
(candles_1h -> candles, adding timeframe, etc.), but since this is a fresh
deployment, the Sequelize models already define the correct schema.

The models are the single source of truth:
- Candle model: includes timeframe, proper constraints and indexes
- Symbol model: includes all instrument types including 'index', proper indexes
- LivePrice model: properly defined

Database schema is created entirely by model sync on first deployment.
Future schema changes should be handled through new migrations if needed.
Hussain Afzal 11 сар өмнө
parent
commit
ba0b4a0aa3

+ 1 - 1
docker-compose.yml

@@ -59,7 +59,7 @@ services:
     restart: unless-stopped
     # Override entrypoint for development to use nodemon with live reload
     entrypoint: /bin/sh
-    command: -c "/usr/local/bin/wait-for-db.sh && node docker/sync-models.js && npx sequelize-cli db:migrate && npm install -g nodemon && nodemon src/server.js"
+    command: -c "/usr/local/bin/wait-for-db.sh && node docker/sync-models.js && (npx sequelize-cli db:migrate || echo 'No migrations to run or migration skipped') && npm install -g nodemon && nodemon src/server.js"
 
   # Nginx Reverse Proxy
   nginx:

+ 10 - 8
docker/entrypoint.sh

@@ -47,14 +47,16 @@ sequelize.sync({ alter: true, force: false })
     echo "WARNING: Model sync failed, continuing with migrations..."
 }
 
-# Run database migrations
-echo "Running database migrations..."
-npx sequelize-cli db:migrate || {
-    echo "ERROR: Database migration failed"
-    exit 1
-}
-
-echo "Migrations completed successfully"
+# Run database migrations (if any exist, excluding archive folder)
+echo "Running database migrations (if any)..."
+if [ -d "migrations" ] && [ "$(find migrations -maxdepth 1 -name '*.js' -not -path '*/archive/*' 2>/dev/null | wc -l)" -gt 0 ]; then
+    npx sequelize-cli db:migrate || {
+        echo "WARNING: Database migration failed, but continuing..."
+    }
+    echo "Migrations completed"
+else
+    echo "No migrations found, skipping migration step. Database schema created by model sync."
+fi
 
 # Start the application
 echo "Starting Node.js application..."

+ 0 - 41
migrations/20251016210526-add_unique_constraint_candles.js

@@ -1,41 +0,0 @@
-'use strict';
-
-/** @type {import('sequelize-cli').Migration} */
-module.exports = {
-  async up (queryInterface, Sequelize) {
-    // Check if table exists before adding constraint
-    const tableExists = await queryInterface.sequelize.query(
-      "SELECT EXISTS (SELECT FROM information_schema.tables WHERE table_name = 'candles_1h');",
-      { type: Sequelize.QueryTypes.SELECT }
-    );
-    
-    if (tableExists && tableExists[0] && tableExists[0].exists) {
-      // Check if constraint already exists
-      const constraintExists = await queryInterface.sequelize.query(
-        "SELECT EXISTS (SELECT FROM pg_constraint WHERE conname = 'unique_symbol_open_time');",
-        { type: Sequelize.QueryTypes.SELECT }
-      );
-      
-      if (!constraintExists || !constraintExists[0] || !constraintExists[0].exists) {
-        await queryInterface.addConstraint('candles_1h', {
-          fields: ['symbol_id', 'open_time'],
-          type: 'unique',
-          name: 'unique_symbol_open_time'
-        });
-      }
-    } else {
-      console.log('Table candles_1h does not exist, skipping constraint addition. Tables will be created by model sync.');
-    }
-  },
-
-  async down (queryInterface, Sequelize) {
-    const tableExists = await queryInterface.sequelize.query(
-      "SELECT EXISTS (SELECT FROM information_schema.tables WHERE table_name = 'candles_1h');",
-      { type: Sequelize.QueryTypes.SELECT }
-    );
-    
-    if (tableExists && tableExists[0] && tableExists[0].exists) {
-      await queryInterface.removeConstraint('candles_1h', 'unique_symbol_open_time');
-    }
-  }
-};

+ 0 - 33
migrations/20251027075914-add-index-to-instrument-type.js

@@ -1,33 +0,0 @@
-'use strict';
-
-/** @type {import('sequelize-cli').Migration} */
-module.exports = {
-  async up (queryInterface, Sequelize) {
-    // Check if table exists
-    const tableExists = await queryInterface.sequelize.query(
-      "SELECT EXISTS (SELECT FROM information_schema.tables WHERE table_name = 'symbols');",
-      { type: Sequelize.QueryTypes.SELECT }
-    );
-    
-    if (tableExists && tableExists[0] && tableExists[0].exists) {
-      // Drop the existing CHECK constraint if it exists and add a new one with 'index'
-      await queryInterface.sequelize.query("ALTER TABLE symbols DROP CONSTRAINT IF EXISTS symbols_instrument_type_check;");
-      await queryInterface.sequelize.query("ALTER TABLE symbols ADD CONSTRAINT symbols_instrument_type_check CHECK (instrument_type IN ('crypto', 'stock', 'forex', 'commodity', 'index'));");
-    } else {
-      console.log('Table symbols does not exist, skipping constraint update. Tables will be created by model sync.');
-    }
-  },
-
-  async down (queryInterface, Sequelize) {
-    const tableExists = await queryInterface.sequelize.query(
-      "SELECT EXISTS (SELECT FROM information_schema.tables WHERE table_name = 'symbols');",
-      { type: Sequelize.QueryTypes.SELECT }
-    );
-    
-    if (tableExists && tableExists[0] && tableExists[0].exists) {
-      // Revert the CHECK constraint without 'index'
-      await queryInterface.sequelize.query("ALTER TABLE symbols DROP CONSTRAINT IF EXISTS symbols_instrument_type_check;");
-      await queryInterface.sequelize.query("ALTER TABLE symbols ADD CONSTRAINT symbols_instrument_type_check CHECK (instrument_type IN ('crypto', 'stock', 'forex', 'commodity'));");
-    }
-  }
-};

+ 0 - 80
migrations/20251112102032-add-timeframe-to-candles.js

@@ -1,80 +0,0 @@
-'use strict';
-
-/** @type {import('sequelize-cli').Migration} */
-module.exports = {
-  async up (queryInterface, Sequelize) {
-    // Check if candles_1h table exists
-    const tableExists = await queryInterface.sequelize.query(
-      "SELECT EXISTS (SELECT FROM information_schema.tables WHERE table_name = 'candles_1h');",
-      { type: Sequelize.QueryTypes.SELECT }
-    );
-    
-    if (!tableExists || !tableExists[0] || !tableExists[0].exists) {
-      console.log('Table candles_1h does not exist, skipping migration. Tables will be created by model sync with timeframe support.');
-      return;
-    }
-    
-    // Rename table from candles_1h to candles
-    await queryInterface.renameTable('candles_1h', 'candles');
-
-    // Add timeframe column with enum
-    await queryInterface.addColumn('candles', 'timeframe', {
-      type: Sequelize.ENUM('15m', '30m', '1h', '1D', '1W', '1M'),
-      allowNull: false,
-      defaultValue: '1h'
-    });
-
-    // Update existing records to have '1h' timeframe
-    await queryInterface.sequelize.query('UPDATE candles SET timeframe = \'1h\' WHERE timeframe IS NULL');
-
-    // Remove the default value after setting existing records
-    await queryInterface.changeColumn('candles', 'timeframe', {
-      type: Sequelize.ENUM('15m', '30m', '1h', '1D', '1W', '1M'),
-      allowNull: false
-    });
-
-    // Drop the old unique constraint
-    await queryInterface.removeConstraint('candles', 'unique_symbol_open_time');
-
-    // Add new unique constraint including timeframe
-    await queryInterface.addConstraint('candles', {
-      fields: ['symbol_id', 'open_time', 'timeframe'],
-      type: 'unique',
-      name: 'unique_symbol_open_time_timeframe'
-    });
-
-    // Update indexes to include timeframe
-    await queryInterface.removeIndex('candles', 'idx_candles_open_time');
-    await queryInterface.addIndex('candles', ['open_time', 'timeframe'], {
-      name: 'idx_candles_open_time_timeframe'
-    });
-  },
-
-  async down (queryInterface, Sequelize) {
-    // Reverse the changes
-
-    // Remove new indexes
-    await queryInterface.removeIndex('candles', 'idx_candles_open_time_timeframe');
-
-    // Add back old index
-    await queryInterface.addIndex('candles', ['open_time'], {
-      name: 'idx_candles_open_time'
-    });
-
-    // Remove new constraint
-    await queryInterface.removeConstraint('candles', 'unique_symbol_open_time_timeframe');
-
-    // Add back old constraint
-    await queryInterface.addConstraint('candles', {
-      fields: ['symbol_id', 'open_time'],
-      type: 'unique',
-      name: 'unique_symbol_open_time'
-    });
-
-    // Remove timeframe column
-    await queryInterface.removeColumn('candles', 'timeframe');
-
-    // Rename table back to candles_1h
-    await queryInterface.renameTable('candles', 'candles_1h');
-  }
-};