whitelabel-db 1.1.95 → 1.1.97

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -75,8 +75,9 @@ const connect = (connectionDetails) => __awaiter(void 0, void 0, void 0, functio
75
75
  try {
76
76
  yield connection.authenticate();
77
77
  console.log('Database connection has been established successfully.');
78
- // Ensure sync completes and creates necessary tables including SequelizeMeta
79
- yield connection.sync({ alter: false });
78
+ // Only create tables that don't exist, don't alter existing schema
79
+ // This prevents conflicts with migrations
80
+ yield connection.sync({ force: false, alter: false });
80
81
  console.log('Database sync completed successfully.');
81
82
  return connection;
82
83
  }
@@ -0,0 +1,16 @@
1
+ import { QueryInterface } from 'sequelize';
2
+ /**
3
+ * Safely adds a column to a table, checking if it already exists first
4
+ */
5
+ export declare function safeAddColumn(queryInterface: QueryInterface, tableName: string, columnName: string, columnDefinition: any): Promise<void>;
6
+ /**
7
+ * Safely adds multiple columns to a table
8
+ */
9
+ export declare function safeAddColumns(queryInterface: QueryInterface, tableName: string, columns: Array<{
10
+ name: string;
11
+ definition: any;
12
+ }>): Promise<void>;
13
+ /**
14
+ * Safely adds an index to a table, handling if it already exists
15
+ */
16
+ export declare function safeAddIndex(queryInterface: QueryInterface, tableName: string, indexName: string, columns: string[], options?: any): Promise<void>;
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.safeAddIndex = exports.safeAddColumns = exports.safeAddColumn = void 0;
13
+ /**
14
+ * Safely adds a column to a table, checking if it already exists first
15
+ */
16
+ function safeAddColumn(queryInterface, tableName, columnName, columnDefinition) {
17
+ return __awaiter(this, void 0, void 0, function* () {
18
+ try {
19
+ const tableDescription = yield queryInterface.describeTable(tableName);
20
+ const existingColumns = Object.keys(tableDescription);
21
+ if (existingColumns.includes(columnName)) {
22
+ console.log(`${columnName} column already exists in ${tableName}, skipping.`);
23
+ return;
24
+ }
25
+ yield queryInterface.addColumn(tableName, columnName, columnDefinition);
26
+ console.log(`${columnName} column added to ${tableName} successfully.`);
27
+ }
28
+ catch (error) {
29
+ console.error(`Error adding ${columnName} column to ${tableName}:`, error.message);
30
+ throw error;
31
+ }
32
+ });
33
+ }
34
+ exports.safeAddColumn = safeAddColumn;
35
+ /**
36
+ * Safely adds multiple columns to a table
37
+ */
38
+ function safeAddColumns(queryInterface, tableName, columns) {
39
+ return __awaiter(this, void 0, void 0, function* () {
40
+ try {
41
+ const tableDescription = yield queryInterface.describeTable(tableName);
42
+ const existingColumns = Object.keys(tableDescription);
43
+ const columnsToAdd = columns.filter((column) => !existingColumns.includes(column.name));
44
+ if (columnsToAdd.length === 0) {
45
+ console.log(`All columns already exist in ${tableName}, skipping migration.`);
46
+ return;
47
+ }
48
+ yield Promise.all(columnsToAdd.map((column) => queryInterface.addColumn(tableName, column.name, column.definition)));
49
+ console.log(`Added ${columnsToAdd.length} columns to ${tableName} successfully.`);
50
+ }
51
+ catch (error) {
52
+ console.error(`Error adding columns to ${tableName}:`, error.message);
53
+ throw error;
54
+ }
55
+ });
56
+ }
57
+ exports.safeAddColumns = safeAddColumns;
58
+ /**
59
+ * Safely adds an index to a table, handling if it already exists
60
+ */
61
+ function safeAddIndex(queryInterface, tableName, indexName, columns, options = {}) {
62
+ return __awaiter(this, void 0, void 0, function* () {
63
+ try {
64
+ yield queryInterface.addIndex(tableName, columns, Object.assign({ name: indexName }, options));
65
+ console.log(`Index ${indexName} added to ${tableName} successfully.`);
66
+ }
67
+ catch (error) {
68
+ if (error.message.includes('already exists')) {
69
+ console.log(`Index ${indexName} already exists on ${tableName}, skipping.`);
70
+ }
71
+ else {
72
+ console.error(`Error adding index ${indexName} to ${tableName}:`, error.message);
73
+ throw error;
74
+ }
75
+ }
76
+ });
77
+ }
78
+ exports.safeAddIndex = safeAddIndex;
@@ -14,19 +14,36 @@ exports.down = exports.up = void 0;
14
14
  const sequelize_1 = require("sequelize");
15
15
  const up = (queryInterface) => __awaiter(void 0, void 0, void 0, function* () {
16
16
  try {
17
- // Add all columns in parallel
18
- yield queryInterface.addColumn('users', 'passwordResetToken', {
19
- type: sequelize_1.DataTypes.STRING,
20
- allowNull: true,
21
- });
22
- yield queryInterface.addColumn('users', 'passwordResetTokenExpiresAt', {
23
- type: sequelize_1.DataTypes.DATE,
24
- allowNull: true,
25
- });
26
- console.log('All columns added successfully.');
17
+ // Check which columns already exist
18
+ const tableDescription = yield queryInterface.describeTable('users');
19
+ const existingColumns = Object.keys(tableDescription);
20
+ // Add passwordResetToken if it doesn't exist
21
+ if (!existingColumns.includes('passwordResetToken')) {
22
+ yield queryInterface.addColumn('users', 'passwordResetToken', {
23
+ type: sequelize_1.DataTypes.STRING,
24
+ allowNull: true,
25
+ });
26
+ console.log('passwordResetToken column added successfully.');
27
+ }
28
+ else {
29
+ console.log('passwordResetToken column already exists, skipping.');
30
+ }
31
+ // Add passwordResetTokenExpiresAt if it doesn't exist
32
+ if (!existingColumns.includes('passwordResetTokenExpiresAt')) {
33
+ yield queryInterface.addColumn('users', 'passwordResetTokenExpiresAt', {
34
+ type: sequelize_1.DataTypes.DATE,
35
+ allowNull: true,
36
+ });
37
+ console.log('passwordResetTokenExpiresAt column added successfully.');
38
+ }
39
+ else {
40
+ console.log('passwordResetTokenExpiresAt column already exists, skipping.');
41
+ }
42
+ console.log('Migration completed successfully.');
27
43
  }
28
44
  catch (error) {
29
45
  console.error('Error while adding columns:', error.message);
46
+ throw error;
30
47
  }
31
48
  });
32
49
  exports.up = up;
@@ -0,0 +1,6 @@
1
+ import { QueryInterface } from 'sequelize';
2
+ declare const _default: {
3
+ up: (queryInterface: QueryInterface) => Promise<void>;
4
+ down: (queryInterface: QueryInterface) => Promise<void>;
5
+ };
6
+ export = _default;
@@ -0,0 +1,188 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ const sequelize_1 = require("sequelize");
12
+ module.exports = {
13
+ up: (queryInterface) => __awaiter(void 0, void 0, void 0, function* () {
14
+ // Create guest_profiles table
15
+ yield queryInterface.createTable('guest_profiles', {
16
+ guest_id: {
17
+ type: sequelize_1.DataTypes.UUID,
18
+ allowNull: false,
19
+ primaryKey: true,
20
+ defaultValue: sequelize_1.DataTypes.UUIDV4,
21
+ },
22
+ frequent_destinations: {
23
+ type: sequelize_1.DataTypes.JSONB,
24
+ allowNull: true,
25
+ },
26
+ avg_budget_range: {
27
+ type: sequelize_1.DataTypes.JSONB,
28
+ allowNull: true,
29
+ },
30
+ preferred_filters: {
31
+ type: sequelize_1.DataTypes.JSONB,
32
+ allowNull: true,
33
+ },
34
+ family_traveler: {
35
+ type: sequelize_1.DataTypes.BOOLEAN,
36
+ allowNull: true,
37
+ },
38
+ avg_stay_duration: {
39
+ type: sequelize_1.DataTypes.INTEGER,
40
+ allowNull: true,
41
+ },
42
+ created_at: {
43
+ type: sequelize_1.DataTypes.DATE,
44
+ allowNull: false,
45
+ defaultValue: sequelize_1.DataTypes.NOW,
46
+ },
47
+ updated_at: {
48
+ type: sequelize_1.DataTypes.DATE,
49
+ allowNull: false,
50
+ defaultValue: sequelize_1.DataTypes.NOW,
51
+ },
52
+ });
53
+ // Create guest_search_history table
54
+ yield queryInterface.createTable('guest_search_history', {
55
+ search_id: {
56
+ type: sequelize_1.DataTypes.UUID,
57
+ allowNull: false,
58
+ primaryKey: true,
59
+ defaultValue: sequelize_1.DataTypes.UUIDV4,
60
+ },
61
+ guest_id: {
62
+ type: sequelize_1.DataTypes.UUID,
63
+ allowNull: true,
64
+ references: {
65
+ model: 'guests',
66
+ key: 'id',
67
+ },
68
+ onUpdate: 'CASCADE',
69
+ onDelete: 'SET NULL',
70
+ },
71
+ destination: {
72
+ type: sequelize_1.DataTypes.STRING,
73
+ allowNull: false,
74
+ },
75
+ checkin_date: {
76
+ type: sequelize_1.DataTypes.DATEONLY,
77
+ allowNull: false,
78
+ },
79
+ checkout_date: {
80
+ type: sequelize_1.DataTypes.DATEONLY,
81
+ allowNull: false,
82
+ },
83
+ guests: {
84
+ type: sequelize_1.DataTypes.SMALLINT,
85
+ allowNull: false,
86
+ defaultValue: 1,
87
+ },
88
+ rooms: {
89
+ type: sequelize_1.DataTypes.SMALLINT,
90
+ allowNull: false,
91
+ defaultValue: 1,
92
+ },
93
+ budget_range: {
94
+ type: sequelize_1.DataTypes.JSONB,
95
+ allowNull: true,
96
+ },
97
+ filters: {
98
+ type: sequelize_1.DataTypes.JSONB,
99
+ allowNull: true,
100
+ },
101
+ search_timestamp: {
102
+ type: sequelize_1.DataTypes.DATE,
103
+ allowNull: false,
104
+ defaultValue: sequelize_1.DataTypes.NOW,
105
+ },
106
+ search_context: {
107
+ type: sequelize_1.DataTypes.STRING,
108
+ allowNull: false,
109
+ defaultValue: 'exploration',
110
+ },
111
+ device_type: {
112
+ type: sequelize_1.DataTypes.STRING,
113
+ allowNull: false,
114
+ defaultValue: 'unknown',
115
+ },
116
+ travel_purpose: {
117
+ type: sequelize_1.DataTypes.STRING,
118
+ allowNull: false,
119
+ defaultValue: 'unspecified',
120
+ },
121
+ selected_hotel_ids: {
122
+ type: sequelize_1.DataTypes.ARRAY(sequelize_1.DataTypes.STRING),
123
+ allowNull: true,
124
+ },
125
+ place_id: {
126
+ type: sequelize_1.DataTypes.STRING,
127
+ allowNull: true,
128
+ },
129
+ });
130
+ // Create recommendations_cache table
131
+ yield queryInterface.createTable('recommendations_cache', {
132
+ cache_id: {
133
+ type: sequelize_1.DataTypes.UUID,
134
+ allowNull: false,
135
+ primaryKey: true,
136
+ defaultValue: sequelize_1.DataTypes.UUIDV4,
137
+ },
138
+ guest_id: {
139
+ type: sequelize_1.DataTypes.UUID,
140
+ allowNull: true,
141
+ references: {
142
+ model: 'guests',
143
+ key: 'id',
144
+ },
145
+ onUpdate: 'CASCADE',
146
+ onDelete: 'SET NULL',
147
+ },
148
+ hotels: {
149
+ type: sequelize_1.DataTypes.ARRAY(sequelize_1.DataTypes.STRING),
150
+ allowNull: false,
151
+ },
152
+ check_in: {
153
+ type: sequelize_1.DataTypes.DATEONLY,
154
+ allowNull: false,
155
+ },
156
+ check_out: {
157
+ type: sequelize_1.DataTypes.DATEONLY,
158
+ allowNull: false,
159
+ },
160
+ cached_at: {
161
+ type: sequelize_1.DataTypes.DATE,
162
+ allowNull: false,
163
+ defaultValue: sequelize_1.DataTypes.NOW,
164
+ },
165
+ expiry: {
166
+ type: sequelize_1.DataTypes.DATE,
167
+ allowNull: false,
168
+ },
169
+ search_params: {
170
+ type: sequelize_1.DataTypes.JSONB,
171
+ allowNull: true,
172
+ },
173
+ created_at: {
174
+ type: sequelize_1.DataTypes.DATE,
175
+ allowNull: false,
176
+ defaultValue: sequelize_1.DataTypes.NOW,
177
+ },
178
+ });
179
+ // We won't add separate indexes since the foreign keys and primary keys are already indexed
180
+ // Also, Sequelize automatically creates indexes for foreign key references
181
+ }),
182
+ down: (queryInterface) => __awaiter(void 0, void 0, void 0, function* () {
183
+ // Drop tables in reverse order to avoid foreign key constraints
184
+ yield queryInterface.dropTable('recommendations_cache');
185
+ yield queryInterface.dropTable('guest_search_history');
186
+ yield queryInterface.dropTable('guest_profiles');
187
+ }),
188
+ };
@@ -14,16 +14,23 @@ exports.down = exports.up = void 0;
14
14
  const sequelize_1 = require("sequelize");
15
15
  const up = (queryInterface) => __awaiter(void 0, void 0, void 0, function* () {
16
16
  try {
17
- // Add all columns in parallel
17
+ // Check if seo column already exists
18
+ const tableDescription = yield queryInterface.describeTable('projects');
19
+ const existingColumns = Object.keys(tableDescription);
20
+ if (existingColumns.includes('seo')) {
21
+ console.log('seo column already exists, skipping migration.');
22
+ return;
23
+ }
18
24
  yield queryInterface.addColumn('projects', 'seo', {
19
25
  type: sequelize_1.DataTypes.JSONB,
20
26
  allowNull: false,
21
27
  defaultValue: {},
22
28
  });
23
- console.log('column added successfully.');
29
+ console.log('seo column added successfully.');
24
30
  }
25
31
  catch (error) {
26
- console.error('Error while adding columns:', error.message);
32
+ console.error('Error while adding seo column:', error.message);
33
+ throw error;
27
34
  }
28
35
  });
29
36
  exports.up = up;
@@ -0,0 +1,6 @@
1
+ import { QueryInterface } from 'sequelize';
2
+ declare const _default: {
3
+ up: (queryInterface: QueryInterface) => Promise<void>;
4
+ down: (queryInterface: QueryInterface) => Promise<void>;
5
+ };
6
+ export default _default;
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const sequelize_1 = require("sequelize");
13
+ exports.default = {
14
+ up: (queryInterface) => __awaiter(void 0, void 0, void 0, function* () {
15
+ yield queryInterface.createTable('guest_favorite_hotels', {
16
+ guest_id: {
17
+ type: sequelize_1.DataTypes.UUID,
18
+ allowNull: false,
19
+ primaryKey: true,
20
+ references: {
21
+ model: 'guests',
22
+ key: 'id',
23
+ },
24
+ onDelete: 'CASCADE',
25
+ onUpdate: 'CASCADE',
26
+ },
27
+ hotel_id: {
28
+ type: sequelize_1.DataTypes.STRING,
29
+ allowNull: false,
30
+ primaryKey: true,
31
+ },
32
+ created_at: {
33
+ type: sequelize_1.DataTypes.DATE,
34
+ allowNull: false,
35
+ defaultValue: sequelize_1.DataTypes.NOW,
36
+ },
37
+ updated_at: {
38
+ type: sequelize_1.DataTypes.DATE,
39
+ allowNull: false,
40
+ defaultValue: sequelize_1.DataTypes.NOW,
41
+ },
42
+ });
43
+ // Add indexes
44
+ yield queryInterface.addIndex('guest_favorite_hotels', ['guest_id']);
45
+ yield queryInterface.addIndex('guest_favorite_hotels', ['hotel_id']);
46
+ }),
47
+ down: (queryInterface) => __awaiter(void 0, void 0, void 0, function* () {
48
+ yield queryInterface.dropTable('guest_favorite_hotels');
49
+ }),
50
+ };
@@ -14,19 +14,38 @@ exports.down = exports.up = void 0;
14
14
  const sequelize_1 = require("sequelize");
15
15
  const up = (queryInterface) => __awaiter(void 0, void 0, void 0, function* () {
16
16
  try {
17
- // Add all columns in parallel
18
- yield queryInterface.addColumn('users', 'otpExpiresAt', {
19
- type: sequelize_1.DataTypes.DATE,
20
- allowNull: true,
21
- });
22
- yield queryInterface.addColumn('bookings', 'otpExpiresAt', {
23
- type: sequelize_1.DataTypes.DATE,
24
- allowNull: true,
25
- });
26
- console.log('column added successfully.');
17
+ // Check which columns already exist
18
+ const usersTableDescription = yield queryInterface.describeTable('users');
19
+ const bookingsTableDescription = yield queryInterface.describeTable('bookings');
20
+ const existingUsersColumns = Object.keys(usersTableDescription);
21
+ const existingBookingsColumns = Object.keys(bookingsTableDescription);
22
+ // Add otpExpiresAt to users if it doesn't exist
23
+ if (!existingUsersColumns.includes('otpExpiresAt')) {
24
+ yield queryInterface.addColumn('users', 'otpExpiresAt', {
25
+ type: sequelize_1.DataTypes.DATE,
26
+ allowNull: true,
27
+ });
28
+ console.log('otpExpiresAt column added to users table.');
29
+ }
30
+ else {
31
+ console.log('otpExpiresAt column already exists in users table, skipping.');
32
+ }
33
+ // Add otpExpiresAt to bookings if it doesn't exist
34
+ if (!existingBookingsColumns.includes('otpExpiresAt')) {
35
+ yield queryInterface.addColumn('bookings', 'otpExpiresAt', {
36
+ type: sequelize_1.DataTypes.DATE,
37
+ allowNull: true,
38
+ });
39
+ console.log('otpExpiresAt column added to bookings table.');
40
+ }
41
+ else {
42
+ console.log('otpExpiresAt column already exists in bookings table, skipping.');
43
+ }
44
+ console.log('Migration completed successfully.');
27
45
  }
28
46
  catch (error) {
29
47
  console.error('Error while adding columns:', error.message);
48
+ throw error;
30
49
  }
31
50
  });
32
51
  exports.up = up;
@@ -19,16 +19,25 @@ const columns = [
19
19
  ];
20
20
  const up = (queryInterface) => __awaiter(void 0, void 0, void 0, function* () {
21
21
  try {
22
- // Add all columns in parallel
23
- yield Promise.all(columns.map((column) => queryInterface.addColumn('bookings', column.name, {
22
+ // Check which columns already exist
23
+ const tableDescription = yield queryInterface.describeTable('bookings');
24
+ const existingColumns = Object.keys(tableDescription);
25
+ // Filter out columns that already exist
26
+ const columnsToAdd = columns.filter((column) => !existingColumns.includes(column.name));
27
+ if (columnsToAdd.length === 0) {
28
+ console.log('All columns already exist, skipping migration.');
29
+ return;
30
+ }
31
+ // Add only the columns that don't exist
32
+ yield Promise.all(columnsToAdd.map((column) => queryInterface.addColumn('bookings', column.name, {
24
33
  type: column.type,
25
34
  allowNull: column.allowNull,
26
35
  })));
27
- console.log('All columns added successfully.');
28
- console.log('All columns added successfully.');
36
+ console.log(`Added ${columnsToAdd.length} columns successfully.`);
29
37
  }
30
38
  catch (error) {
31
39
  console.error('Error while adding columns:', error.message);
40
+ throw error; // Re-throw to ensure migration fails properly
32
41
  }
33
42
  });
34
43
  exports.up = up;
@@ -13,11 +13,25 @@ exports.down = exports.up = void 0;
13
13
  const sequelize_1 = require("sequelize");
14
14
  function up(queryInterface) {
15
15
  return __awaiter(this, void 0, void 0, function* () {
16
- yield queryInterface.addColumn('static_hotels', 'placeId', {
17
- type: sequelize_1.DataTypes.STRING,
18
- allowNull: true,
19
- comment: 'Google Place ID for the hotel',
20
- });
16
+ try {
17
+ // Check if column already exists
18
+ const tableDescription = yield queryInterface.describeTable('static_hotels');
19
+ const existingColumns = Object.keys(tableDescription);
20
+ if (existingColumns.includes('placeId')) {
21
+ console.log('placeId column already exists, skipping migration.');
22
+ return;
23
+ }
24
+ yield queryInterface.addColumn('static_hotels', 'placeId', {
25
+ type: sequelize_1.DataTypes.STRING,
26
+ allowNull: true,
27
+ comment: 'Google Place ID for the hotel',
28
+ });
29
+ console.log('placeId column added successfully.');
30
+ }
31
+ catch (error) {
32
+ console.error('Error while adding placeId column:', error.message);
33
+ throw error;
34
+ }
21
35
  });
22
36
  }
23
37
  exports.up = up;
@@ -13,25 +13,61 @@ exports.down = exports.up = void 0;
13
13
  const sequelize_1 = require("sequelize");
14
14
  function up(queryInterface) {
15
15
  return __awaiter(this, void 0, void 0, function* () {
16
- // Add hotelId column to room_amenities table
17
- yield queryInterface.addColumn('room_amenities', 'hotelId', {
18
- type: sequelize_1.DataTypes.STRING,
19
- allowNull: true,
20
- references: {
21
- model: 'static_hotels',
22
- key: 'id',
23
- },
24
- onUpdate: 'CASCADE',
25
- onDelete: 'CASCADE',
26
- });
27
- // Add index for better performance
28
- yield queryInterface.addIndex('room_amenities', ['hotelId'], {
29
- name: 'idx_room_amenities_hotel_id',
30
- });
31
- // Add composite index for filtering
32
- yield queryInterface.addIndex('room_amenities', ['hotelId', 'amenityId'], {
33
- name: 'idx_room_amenities_hotel_amenity',
34
- });
16
+ try {
17
+ // Check if hotelId column already exists
18
+ const tableDescription = yield queryInterface.describeTable('room_amenities');
19
+ const existingColumns = Object.keys(tableDescription);
20
+ if (!existingColumns.includes('hotelId')) {
21
+ // Add hotelId column to room_amenities table
22
+ yield queryInterface.addColumn('room_amenities', 'hotelId', {
23
+ type: sequelize_1.DataTypes.STRING,
24
+ allowNull: true,
25
+ references: {
26
+ model: 'static_hotels',
27
+ key: 'id',
28
+ },
29
+ onUpdate: 'CASCADE',
30
+ onDelete: 'CASCADE',
31
+ });
32
+ console.log('hotelId column added successfully.');
33
+ }
34
+ else {
35
+ console.log('hotelId column already exists, skipping column creation.');
36
+ }
37
+ // Try to add indexes - they will fail gracefully if they already exist
38
+ try {
39
+ yield queryInterface.addIndex('room_amenities', ['hotelId'], {
40
+ name: 'idx_room_amenities_hotel_id',
41
+ });
42
+ console.log('hotelId index added successfully.');
43
+ }
44
+ catch (error) {
45
+ if (error.message.includes('already exists')) {
46
+ console.log('hotelId index already exists, skipping.');
47
+ }
48
+ else {
49
+ throw error;
50
+ }
51
+ }
52
+ try {
53
+ yield queryInterface.addIndex('room_amenities', ['hotelId', 'amenityId'], {
54
+ name: 'idx_room_amenities_hotel_amenity',
55
+ });
56
+ console.log('Composite index added successfully.');
57
+ }
58
+ catch (error) {
59
+ if (error.message.includes('already exists')) {
60
+ console.log('Composite index already exists, skipping.');
61
+ }
62
+ else {
63
+ throw error;
64
+ }
65
+ }
66
+ }
67
+ catch (error) {
68
+ console.error('Error in migration 018:', error.message);
69
+ throw error;
70
+ }
35
71
  });
36
72
  }
37
73
  exports.up = up;