Pārlūkot izejas kodu

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 8 mēneši atpakaļ
vecāks
revīzija
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');
-  }
-};