@bikdotai/bik-shared-backend 20.3.2-beta.3 → 20.4.0
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.
- package/lib/alertsV2/alertInstances.repo.js +2 -26
- package/lib/alertsV2/alertsV2.helper.d.ts +4 -3
- package/lib/alertsV2/alertsV2.helper.js +3 -49
- package/lib/alertsV2/alertsV2.service.js +5 -14
- package/lib/auth/authMiddlewares.js +3 -68
- package/lib/auth/firebase-auth.service.js +3 -3
- package/lib/auth/implementations/bik-admin-auth-service.d.ts +1 -1
- package/lib/auth/implementations/bik-admin-auth-service.js +1 -2
- package/lib/auth/index.d.ts +0 -3
- package/lib/auth/index.js +0 -3
- package/lib/auth/secret-manager/env-variables/variables.list.d.ts +0 -3
- package/lib/auth/secret-manager/env-variables/variables.list.js +0 -3
- package/lib/chat-handover-protocol/chat-handover-protocol.js +41 -26
- package/lib/core/setup.d.ts +0 -3
- package/lib/core/setup.js +2 -24
- package/lib/elastic/counter/ingestion.js +0 -1
- package/lib/elastic/queries/campaign/getBroadcastDetailedStats.d.ts +0 -117
- package/lib/elastic/queries/campaign/getBroadcastDetailedStats.js +1 -94
- package/lib/elastic/queries/campaign/getUniqueCustomerCnt.d.ts +0 -1
- package/lib/elastic/queries/campaign/getUniqueCustomerCnt.js +0 -1
- package/lib/elastic/queries/chatbot/getAiOperations.d.ts +5 -5
- package/lib/elastic/queries/chatbot/getAiOperations.js +3 -3
- package/lib/elastic/queries/chatbot/index.d.ts +0 -1
- package/lib/elastic/queries/chatbot/index.js +0 -1
- package/lib/elastic/queries/crm/getActivityTimelineByAgent.js +1 -1
- package/lib/elastic/queries/crm/getBreachedSLACount.d.ts +0 -1
- package/lib/elastic/queries/crm/getBreachedSLACount.js +5 -8
- package/lib/elastic/queries/crm/getFirstResponseTime.d.ts +0 -1
- package/lib/elastic/queries/crm/getFirstResponseTime.js +5 -8
- package/lib/elastic/queries/integrations/index.d.ts +0 -1
- package/lib/elastic/queries/integrations/index.js +0 -1
- package/lib/elastic/queries/openAi/addToCartSession.d.ts +0 -1
- package/lib/elastic/queries/openAi/addToCartSession.js +3 -11
- package/lib/elastic/queries/openAi/checkoutCompletedSession.d.ts +0 -1
- package/lib/elastic/queries/openAi/checkoutCompletedSession.js +3 -11
- package/lib/elastic/reports/crm/index.d.ts +0 -1
- package/lib/elastic/reports/crm/index.js +0 -1
- package/lib/elastic/reports/reports.service.js +8 -17
- package/lib/events/events.d.ts +0 -8
- package/lib/events/events.js +1 -25
- package/lib/events/schema/events.helper.d.ts +0 -1
- package/lib/events/schema/events.helper.js +6 -12
- package/lib/index.d.ts +0 -1
- package/lib/index.js +0 -1
- package/lib/merchant-events/elastic.search.d.ts +0 -5
- package/lib/merchant-events/elastic.search.js +2 -23
- package/lib/merchant-events/merchant.service.d.ts +1 -1
- package/lib/merchant-events/merchant.service.js +11 -12
- package/lib/recordAnalytics/recordAnalytics.service.js +4 -5
- package/lib/redis/redisPubSubService.d.ts +6 -4
- package/lib/redis/redisPubSubService.js +123 -211
- package/lib/redis/redisService.js +8 -14
- package/lib/swagger/SwaggerSchemaHelper.js +17 -21
- package/lib/user-properties/userProperties.service.js +0 -1
- package/package.json +2 -2
- package/lib/alerts/templates/campaign/campaignMovedToDraftSegmentSyncDelay.d.ts +0 -1
- package/lib/alerts/templates/campaign/campaignMovedToDraftSegmentSyncDelay.js +0 -4
- package/lib/alerts/templates/campaign/campaignMovedToDraftSegmentSyncFailed.d.ts +0 -1
- package/lib/alerts/templates/campaign/campaignMovedToDraftSegmentSyncFailed.js +0 -4
- package/lib/alerts/templates/campaign/campaignScheduledTimeExceededDueToSyncDelay.d.ts +0 -1
- package/lib/alerts/templates/campaign/campaignScheduledTimeExceededDueToSyncDelay.js +0 -4
- package/lib/auth/secret-manager/configManager.firestore.d.ts +0 -22
- package/lib/auth/secret-manager/configManager.firestore.js +0 -166
- package/lib/auth/secret-manager/configManager.helper.d.ts +0 -13
- package/lib/auth/secret-manager/configManager.helper.js +0 -32
- package/lib/auth/secret-manager/configManager.model.d.ts +0 -38
- package/lib/auth/secret-manager/configManager.model.js +0 -2
- package/lib/auth/secret-manager/configManager.service.d.ts +0 -17
- package/lib/auth/secret-manager/configManager.service.js +0 -138
- package/lib/core/local_runner.d.ts +0 -1
- package/lib/core/local_runner.js +0 -60
- package/lib/database/database.model.d.ts +0 -95
- package/lib/database/database.model.js +0 -5
- package/lib/database/database.service.d.ts +0 -90
- package/lib/database/database.service.js +0 -382
- package/lib/database/index.d.ts +0 -7
- package/lib/database/index.js +0 -23
- package/lib/elastic/queries/chatbot/getAgentCostForBroadcast.d.ts +0 -117
- package/lib/elastic/queries/chatbot/getAgentCostForBroadcast.js +0 -98
- package/lib/elastic/queries/integrations/getOrdersShadowServices.d.ts +0 -76
- package/lib/elastic/queries/integrations/getOrdersShadowServices.js +0 -61
|
@@ -1,382 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Database Service
|
|
4
|
-
*
|
|
5
|
-
* Provides generic database connection management for PostgreSQL using Sequelize and node-postgres.
|
|
6
|
-
* Supports connection pooling, read replicas, auto-retry logic, and Secret Manager integration.
|
|
7
|
-
*/
|
|
8
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
9
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
10
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
11
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
12
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
13
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
14
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
15
|
-
});
|
|
16
|
-
};
|
|
17
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
exports.readerPool = exports.pool = exports.BikSequelize = exports.resetDefaultConnections = exports.getDefaultReaderPool = exports.getDefaultPool = exports.getDefaultSequelize = exports.DatabaseService = exports.ENABLE_SEQUELIZE_LOGGING = exports.databaseSchema = void 0;
|
|
19
|
-
const sequelize_1 = require("sequelize");
|
|
20
|
-
const pg_1 = require("pg");
|
|
21
|
-
const auth_1 = require("../auth");
|
|
22
|
-
const config_1 = require("../core/config");
|
|
23
|
-
const logger_1 = require("../logger");
|
|
24
|
-
exports.databaseSchema = config_1.isProd ? 'bik' : 'public';
|
|
25
|
-
// Enable sequelize logging based on environment variable
|
|
26
|
-
exports.ENABLE_SEQUELIZE_LOGGING = auth_1.EnvVariableHelper.accessRaw('ENABLE_SEQUELIZE_LOGGING') === 'true';
|
|
27
|
-
/**
|
|
28
|
-
* Service class for managing database connections
|
|
29
|
-
* Provides generic functions to create Sequelize and pg Pool connections
|
|
30
|
-
*/
|
|
31
|
-
class DatabaseService {
|
|
32
|
-
/**
|
|
33
|
-
* Get PostgreSQL configuration from secrets
|
|
34
|
-
* @param secretKeyName - Optional custom secret key name (defaults to 'aurora-common')
|
|
35
|
-
* @returns Promise<PgConfig>
|
|
36
|
-
*/
|
|
37
|
-
static getPgConfig(secretKeyName) {
|
|
38
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
39
|
-
// Cache the config to avoid multiple secret manager calls
|
|
40
|
-
if (!this.pgConfigCache) {
|
|
41
|
-
this.pgConfigCache = (() => __awaiter(this, void 0, void 0, function* () {
|
|
42
|
-
const secretName = secretKeyName ||
|
|
43
|
-
auth_1.EnvVariableHelper.access(auth_1.ServiceName.PGSQL, auth_1.PgSQLKeys.SECRET_NAME, 'pg_secret_name') ||
|
|
44
|
-
'aurora-common';
|
|
45
|
-
const secretManagerService = auth_1.SecretManagerService.getInstance();
|
|
46
|
-
const secrets = yield secretManagerService.getSecret(secretName);
|
|
47
|
-
return {
|
|
48
|
-
username: secrets.user,
|
|
49
|
-
password: secrets.password,
|
|
50
|
-
host: secrets.host,
|
|
51
|
-
read: secrets.read,
|
|
52
|
-
database: secrets.database,
|
|
53
|
-
dialect: secrets.dialect,
|
|
54
|
-
schema: secrets.schema,
|
|
55
|
-
port: secrets.port,
|
|
56
|
-
};
|
|
57
|
-
}))();
|
|
58
|
-
}
|
|
59
|
-
return this.pgConfigCache;
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Reset the cached config (useful for testing or when secrets change)
|
|
64
|
-
*/
|
|
65
|
-
static resetConfigCache() {
|
|
66
|
-
this.pgConfigCache = null;
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Create a Sequelize instance with optimal configuration
|
|
70
|
-
* @param options - Optional configuration for connection pooling and retry logic
|
|
71
|
-
* @param secretKeyName - Optional custom secret key name
|
|
72
|
-
* @returns Promise<Sequelize>
|
|
73
|
-
*/
|
|
74
|
-
static createSequelizeConnection(options = {}, secretKeyName) {
|
|
75
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
76
|
-
const pgConfig = yield this.getPgConfig(secretKeyName);
|
|
77
|
-
const { maxConnections = 15, minConnections = 1, acquireTimeout = 60000, idleTimeout = 1000, maxRetries = 20, backoffBase = 500, backoffExponent = 1.2, enableLogging = exports.ENABLE_SEQUELIZE_LOGGING, customSchema, enableQueryMetadata = true, } = options;
|
|
78
|
-
const sequelize = new sequelize_1.Sequelize(pgConfig.database, pgConfig.username, pgConfig.password, {
|
|
79
|
-
dialect: 'postgres',
|
|
80
|
-
replication: {
|
|
81
|
-
read: pgConfig.read || [],
|
|
82
|
-
write: { host: pgConfig.host },
|
|
83
|
-
},
|
|
84
|
-
pool: {
|
|
85
|
-
max: maxConnections,
|
|
86
|
-
min: minConnections,
|
|
87
|
-
acquire: acquireTimeout,
|
|
88
|
-
idle: idleTimeout,
|
|
89
|
-
},
|
|
90
|
-
retry: {
|
|
91
|
-
match: [
|
|
92
|
-
sequelize_1.ConnectionError,
|
|
93
|
-
sequelize_1.DatabaseError,
|
|
94
|
-
sequelize_1.ConnectionRefusedError,
|
|
95
|
-
/Deadlock/i,
|
|
96
|
-
/SequelizeDatabaseError/,
|
|
97
|
-
/SequelizeConnectionError/,
|
|
98
|
-
/SequelizeHostNotFoundError/,
|
|
99
|
-
/SequelizeHostNotReachableError/,
|
|
100
|
-
/SequelizeInvalidConnectionError/,
|
|
101
|
-
/SequelizeConnectionTimedOutError/,
|
|
102
|
-
],
|
|
103
|
-
max: maxRetries,
|
|
104
|
-
backoffBase,
|
|
105
|
-
backoffExponent,
|
|
106
|
-
},
|
|
107
|
-
port: 5432,
|
|
108
|
-
logging: enableLogging,
|
|
109
|
-
schema: customSchema || pgConfig.schema,
|
|
110
|
-
dialectOptions: {
|
|
111
|
-
application_name: 'bik-backend', // Default application name
|
|
112
|
-
},
|
|
113
|
-
});
|
|
114
|
-
// Set application_name at the connection level for ALL queries (including Model operations)
|
|
115
|
-
// This approach works because it wraps the actual query execution on each connection
|
|
116
|
-
if (enableQueryMetadata) {
|
|
117
|
-
// Hook into connection acquisition to wrap the query method
|
|
118
|
-
const originalGetConnection = sequelize.connectionManager.getConnection.bind(sequelize.connectionManager);
|
|
119
|
-
sequelize.connectionManager.getConnection = function (options) {
|
|
120
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
121
|
-
const connection = yield originalGetConnection(options);
|
|
122
|
-
// Wrap the query method if not already wrapped
|
|
123
|
-
if (!connection._queryWrapped) {
|
|
124
|
-
const originalQuery = connection.query.bind(connection);
|
|
125
|
-
connection.query = function (sql, ...args) {
|
|
126
|
-
try {
|
|
127
|
-
// Get CURRENT context at query execution time
|
|
128
|
-
const context = logger_1.LogExecutionContextHelper.getContext();
|
|
129
|
-
const apiName = (context === null || context === void 0 ? void 0 : context.apiName) || 'unknown_api';
|
|
130
|
-
if (apiName === 'unknown_api') {
|
|
131
|
-
console.warn('⚠️ [DB] NO API NAME IN CONTEXT!');
|
|
132
|
-
}
|
|
133
|
-
// Inject SET application_name before the actual query
|
|
134
|
-
const appNameQuery = `SET application_name = 'bik:${apiName}'`;
|
|
135
|
-
if (typeof sql === 'string') {
|
|
136
|
-
console.log('🔍 [DB] Executing raw SQL query');
|
|
137
|
-
sql = `${appNameQuery}; ${sql}`;
|
|
138
|
-
}
|
|
139
|
-
else if (sql && typeof sql === 'object' && 'text' in sql) {
|
|
140
|
-
console.log('🔍 [DB] Executing parameterized SQL query');
|
|
141
|
-
sql.text = `${appNameQuery}; ${sql.text}`;
|
|
142
|
-
}
|
|
143
|
-
else {
|
|
144
|
-
console.log('⚠️ [DB] Unable to set application_name - unrecognized query format', sql);
|
|
145
|
-
}
|
|
146
|
-
if (exports.ENABLE_SEQUELIZE_LOGGING) {
|
|
147
|
-
console.log(`🔍 [DB] Query executing with application_name: bik:${apiName}`);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
catch (error) {
|
|
151
|
-
if (exports.ENABLE_SEQUELIZE_LOGGING) {
|
|
152
|
-
console.error('Error setting application_name:', error);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
return originalQuery(sql, ...args);
|
|
156
|
-
};
|
|
157
|
-
connection._queryWrapped = true;
|
|
158
|
-
}
|
|
159
|
-
else {
|
|
160
|
-
console.warn('⚠️ [DB] Query method already wrapped');
|
|
161
|
-
}
|
|
162
|
-
return connection;
|
|
163
|
-
});
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
return sequelize;
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* Create a PostgreSQL Pool for raw queries (write operations)
|
|
171
|
-
* @param options - Optional configuration for connection pooling
|
|
172
|
-
* @param secretKeyName - Optional custom secret key name
|
|
173
|
-
* @returns Promise<Pool>
|
|
174
|
-
*/
|
|
175
|
-
static createPool(options = {}, secretKeyName) {
|
|
176
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
177
|
-
const pgConfig = yield this.getPgConfig(secretKeyName);
|
|
178
|
-
const { maxConnections = 15, minConnections = 0, idleTimeout = 1000 } = options;
|
|
179
|
-
const config = {
|
|
180
|
-
user: pgConfig.username,
|
|
181
|
-
database: pgConfig.database,
|
|
182
|
-
password: pgConfig.password,
|
|
183
|
-
port: pgConfig.port,
|
|
184
|
-
host: pgConfig.host,
|
|
185
|
-
max: maxConnections,
|
|
186
|
-
min: minConnections,
|
|
187
|
-
idleTimeoutMillis: idleTimeout,
|
|
188
|
-
application_name: 'bik-backend', // Default application name for Aurora tracking
|
|
189
|
-
};
|
|
190
|
-
const pool = new pg_1.Pool(config);
|
|
191
|
-
// Wrap the query method to set application_name dynamically
|
|
192
|
-
const originalQuery = pool.query.bind(pool);
|
|
193
|
-
pool.query = function (queryTextOrConfig, values, callback) {
|
|
194
|
-
try {
|
|
195
|
-
const context = logger_1.LogExecutionContextHelper.getContext();
|
|
196
|
-
const apiName = (context === null || context === void 0 ? void 0 : context.apiName) || 'unknown_api';
|
|
197
|
-
// Inject SET application_name before the actual query
|
|
198
|
-
// This makes it visible in Aurora Performance Insights and pg_stat_activity
|
|
199
|
-
const appNameQuery = `SET application_name = 'bik:${apiName}'`;
|
|
200
|
-
if (typeof queryTextOrConfig === 'string') {
|
|
201
|
-
// Simple query: query(text, values, callback)
|
|
202
|
-
queryTextOrConfig = `${appNameQuery}; ${queryTextOrConfig}`;
|
|
203
|
-
}
|
|
204
|
-
else if (queryTextOrConfig &&
|
|
205
|
-
typeof queryTextOrConfig === 'object' &&
|
|
206
|
-
'text' in queryTextOrConfig) {
|
|
207
|
-
// Query config object: query({ text, values }, callback)
|
|
208
|
-
queryTextOrConfig.text = `${appNameQuery}; ${queryTextOrConfig.text}`;
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
catch (error) {
|
|
212
|
-
if (exports.ENABLE_SEQUELIZE_LOGGING) {
|
|
213
|
-
console.error('Error setting application_name for Pool query:', error);
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
return originalQuery(queryTextOrConfig, values, callback);
|
|
217
|
-
};
|
|
218
|
-
return pool;
|
|
219
|
-
});
|
|
220
|
-
}
|
|
221
|
-
/**
|
|
222
|
-
* Create a PostgreSQL Pool for read operations (using read replicas)
|
|
223
|
-
* @param options - Optional configuration for connection pooling
|
|
224
|
-
* @param secretKeyName - Optional custom secret key name
|
|
225
|
-
* @returns Promise<Pool>
|
|
226
|
-
*/
|
|
227
|
-
static createReaderPool(options = {}, secretKeyName) {
|
|
228
|
-
var _a, _b;
|
|
229
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
230
|
-
const pgConfig = yield this.getPgConfig(secretKeyName);
|
|
231
|
-
const { maxConnections = 15, minConnections = 0, idleTimeout = 1000 } = options;
|
|
232
|
-
const config = {
|
|
233
|
-
user: pgConfig.username,
|
|
234
|
-
database: pgConfig.database,
|
|
235
|
-
password: pgConfig.password,
|
|
236
|
-
port: pgConfig.port,
|
|
237
|
-
host: ((_b = (_a = pgConfig.read) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.host) || pgConfig.host,
|
|
238
|
-
max: maxConnections,
|
|
239
|
-
min: minConnections,
|
|
240
|
-
idleTimeoutMillis: idleTimeout,
|
|
241
|
-
application_name: 'bik-backend-reader', // Default application name for Aurora tracking
|
|
242
|
-
};
|
|
243
|
-
const pool = new pg_1.Pool(config);
|
|
244
|
-
// Wrap the query method to set application_name dynamically
|
|
245
|
-
const originalQuery = pool.query.bind(pool);
|
|
246
|
-
pool.query = function (queryTextOrConfig, values, callback) {
|
|
247
|
-
try {
|
|
248
|
-
const context = logger_1.LogExecutionContextHelper.getContext();
|
|
249
|
-
const apiName = (context === null || context === void 0 ? void 0 : context.apiName) || 'unknown_api';
|
|
250
|
-
// Inject SET application_name before the actual query
|
|
251
|
-
// This makes it visible in Aurora Performance Insights and pg_stat_activity
|
|
252
|
-
const appNameQuery = `SET application_name = 'bik:${apiName}:read'`;
|
|
253
|
-
if (typeof queryTextOrConfig === 'string') {
|
|
254
|
-
// Simple query: query(text, values, callback)
|
|
255
|
-
queryTextOrConfig = `${appNameQuery}; ${queryTextOrConfig}`;
|
|
256
|
-
}
|
|
257
|
-
else if (queryTextOrConfig &&
|
|
258
|
-
typeof queryTextOrConfig === 'object' &&
|
|
259
|
-
'text' in queryTextOrConfig) {
|
|
260
|
-
// Query config object: query({ text, values }, callback)
|
|
261
|
-
queryTextOrConfig.text = `${appNameQuery}; ${queryTextOrConfig.text}`;
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
catch (error) {
|
|
265
|
-
if (exports.ENABLE_SEQUELIZE_LOGGING) {
|
|
266
|
-
console.error('Error setting application_name for ReaderPool query:', error);
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
return originalQuery(queryTextOrConfig, values, callback);
|
|
270
|
-
};
|
|
271
|
-
return pool;
|
|
272
|
-
});
|
|
273
|
-
}
|
|
274
|
-
/**
|
|
275
|
-
* Create all database connections at once
|
|
276
|
-
* Useful for initializing all required connections at application startup
|
|
277
|
-
* @param options - Optional configuration for connection pooling
|
|
278
|
-
* @param secretKeyName - Optional custom secret key name
|
|
279
|
-
* @returns Promise with all connection types
|
|
280
|
-
*/
|
|
281
|
-
static createAllConnections(options = {}, secretKeyName) {
|
|
282
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
283
|
-
const [sequelize, pool, readerPool] = yield Promise.all([
|
|
284
|
-
this.createSequelizeConnection(options, secretKeyName),
|
|
285
|
-
this.createPool(options, secretKeyName),
|
|
286
|
-
this.createReaderPool(options, secretKeyName),
|
|
287
|
-
]);
|
|
288
|
-
return { sequelize, pool, readerPool };
|
|
289
|
-
});
|
|
290
|
-
}
|
|
291
|
-
/**
|
|
292
|
-
* Test database connection
|
|
293
|
-
* @param sequelize - Sequelize instance to test
|
|
294
|
-
* @returns Promise<boolean>
|
|
295
|
-
*/
|
|
296
|
-
static testConnection(sequelize) {
|
|
297
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
298
|
-
try {
|
|
299
|
-
yield sequelize.authenticate();
|
|
300
|
-
console.log('Database connection has been established successfully.');
|
|
301
|
-
return true;
|
|
302
|
-
}
|
|
303
|
-
catch (error) {
|
|
304
|
-
console.error('Unable to connect to the database:', error);
|
|
305
|
-
return false;
|
|
306
|
-
}
|
|
307
|
-
});
|
|
308
|
-
}
|
|
309
|
-
/**
|
|
310
|
-
* Gracefully close all connections
|
|
311
|
-
* @param connections - Object containing all connection instances
|
|
312
|
-
*/
|
|
313
|
-
static closeConnections(connections) {
|
|
314
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
315
|
-
const closePromises = [];
|
|
316
|
-
if (connections.sequelize) {
|
|
317
|
-
closePromises.push(connections.sequelize.close());
|
|
318
|
-
}
|
|
319
|
-
if (connections.pool) {
|
|
320
|
-
closePromises.push(connections.pool.end());
|
|
321
|
-
}
|
|
322
|
-
if (connections.readerPool) {
|
|
323
|
-
closePromises.push(connections.readerPool.end());
|
|
324
|
-
}
|
|
325
|
-
yield Promise.all(closePromises);
|
|
326
|
-
console.log('All database connections closed successfully.');
|
|
327
|
-
});
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
exports.DatabaseService = DatabaseService;
|
|
331
|
-
DatabaseService.pgConfigCache = null;
|
|
332
|
-
// Singleton instances for backward compatibility and easy access
|
|
333
|
-
let defaultSequelizeInstance = null;
|
|
334
|
-
let defaultPoolInstance = null;
|
|
335
|
-
let defaultReaderPoolInstance = null;
|
|
336
|
-
/**
|
|
337
|
-
* Get or create the default Sequelize instance (Singleton)
|
|
338
|
-
* @returns Promise<Sequelize>
|
|
339
|
-
*/
|
|
340
|
-
const getDefaultSequelize = () => {
|
|
341
|
-
if (!defaultSequelizeInstance) {
|
|
342
|
-
defaultSequelizeInstance = DatabaseService.createSequelizeConnection();
|
|
343
|
-
}
|
|
344
|
-
return defaultSequelizeInstance;
|
|
345
|
-
};
|
|
346
|
-
exports.getDefaultSequelize = getDefaultSequelize;
|
|
347
|
-
/**
|
|
348
|
-
* Get or create the default Pool instance (Singleton)
|
|
349
|
-
* @returns Promise<Pool>
|
|
350
|
-
*/
|
|
351
|
-
const getDefaultPool = () => {
|
|
352
|
-
if (!defaultPoolInstance) {
|
|
353
|
-
defaultPoolInstance = DatabaseService.createPool();
|
|
354
|
-
}
|
|
355
|
-
return defaultPoolInstance;
|
|
356
|
-
};
|
|
357
|
-
exports.getDefaultPool = getDefaultPool;
|
|
358
|
-
/**
|
|
359
|
-
* Get or create the default Reader Pool instance (Singleton)
|
|
360
|
-
* @returns Promise<Pool>
|
|
361
|
-
*/
|
|
362
|
-
const getDefaultReaderPool = () => {
|
|
363
|
-
if (!defaultReaderPoolInstance) {
|
|
364
|
-
defaultReaderPoolInstance = DatabaseService.createReaderPool();
|
|
365
|
-
}
|
|
366
|
-
return defaultReaderPoolInstance;
|
|
367
|
-
};
|
|
368
|
-
exports.getDefaultReaderPool = getDefaultReaderPool;
|
|
369
|
-
/**
|
|
370
|
-
* Reset all singleton instances (useful for testing)
|
|
371
|
-
*/
|
|
372
|
-
const resetDefaultConnections = () => {
|
|
373
|
-
defaultSequelizeInstance = null;
|
|
374
|
-
defaultPoolInstance = null;
|
|
375
|
-
defaultReaderPoolInstance = null;
|
|
376
|
-
DatabaseService.resetConfigCache();
|
|
377
|
-
};
|
|
378
|
-
exports.resetDefaultConnections = resetDefaultConnections;
|
|
379
|
-
// Export legacy variable names for backward compatibility
|
|
380
|
-
exports.BikSequelize = (0, exports.getDefaultSequelize)();
|
|
381
|
-
exports.pool = (0, exports.getDefaultPool)();
|
|
382
|
-
exports.readerPool = (0, exports.getDefaultReaderPool)();
|
package/lib/database/index.d.ts
DELETED
package/lib/database/index.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Database Service
|
|
4
|
-
*
|
|
5
|
-
* Generic database connection management for PostgreSQL
|
|
6
|
-
*/
|
|
7
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
-
if (k2 === undefined) k2 = k;
|
|
9
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
-
}
|
|
13
|
-
Object.defineProperty(o, k2, desc);
|
|
14
|
-
}) : (function(o, m, k, k2) {
|
|
15
|
-
if (k2 === undefined) k2 = k;
|
|
16
|
-
o[k2] = m[k];
|
|
17
|
-
}));
|
|
18
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
19
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
20
|
-
};
|
|
21
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
-
__exportStar(require("./database.service"), exports);
|
|
23
|
-
__exportStar(require("./database.model"), exports);
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import { Events } from '@bikdotai/bik-models/events';
|
|
2
|
-
import { QueryHelper } from '../query.helper';
|
|
3
|
-
export interface GetAgentCostForBroadcastParams {
|
|
4
|
-
indexName: string;
|
|
5
|
-
storeId: string;
|
|
6
|
-
broadcastId: string;
|
|
7
|
-
startDate: string;
|
|
8
|
-
endDate: string;
|
|
9
|
-
}
|
|
10
|
-
export interface AgentCostUsageBucket {
|
|
11
|
-
usedTier: string | null;
|
|
12
|
-
usageType: string | null;
|
|
13
|
-
isFreeAgent: boolean | null;
|
|
14
|
-
/** For non-audio usage: number of operations */
|
|
15
|
-
count: number;
|
|
16
|
-
/** For audio (AUDIO usageType): total seconds */
|
|
17
|
-
usageUnits: number;
|
|
18
|
-
}
|
|
19
|
-
export interface GetAgentCostForBroadcastResponse {
|
|
20
|
-
buckets: AgentCostUsageBucket[];
|
|
21
|
-
}
|
|
22
|
-
export declare class GetAgentCostForBroadcastQuery implements QueryHelper<GetAgentCostForBroadcastParams, GetAgentCostForBroadcastResponse> {
|
|
23
|
-
getQuery(params: GetAgentCostForBroadcastParams): {
|
|
24
|
-
index: string;
|
|
25
|
-
size: number;
|
|
26
|
-
query: {
|
|
27
|
-
bool: {
|
|
28
|
-
filter: {
|
|
29
|
-
range: {
|
|
30
|
-
timestamp: {
|
|
31
|
-
gte: string;
|
|
32
|
-
lte: string;
|
|
33
|
-
};
|
|
34
|
-
};
|
|
35
|
-
}[];
|
|
36
|
-
must: ({
|
|
37
|
-
term: {
|
|
38
|
-
'storeId.keyword': {
|
|
39
|
-
value: string;
|
|
40
|
-
};
|
|
41
|
-
"eventName.keyword"?: undefined;
|
|
42
|
-
'eventProperties.useCaseId.keyword'?: undefined;
|
|
43
|
-
};
|
|
44
|
-
} | {
|
|
45
|
-
term: {
|
|
46
|
-
'eventName.keyword': {
|
|
47
|
-
value: Events;
|
|
48
|
-
};
|
|
49
|
-
"storeId.keyword"?: undefined;
|
|
50
|
-
'eventProperties.useCaseId.keyword'?: undefined;
|
|
51
|
-
};
|
|
52
|
-
} | {
|
|
53
|
-
term: {
|
|
54
|
-
'eventProperties.useCaseId.keyword': {
|
|
55
|
-
value: string;
|
|
56
|
-
};
|
|
57
|
-
"storeId.keyword"?: undefined;
|
|
58
|
-
"eventName.keyword"?: undefined;
|
|
59
|
-
};
|
|
60
|
-
})[];
|
|
61
|
-
};
|
|
62
|
-
};
|
|
63
|
-
aggs: {
|
|
64
|
-
usage_by_tier_type_agent: {
|
|
65
|
-
composite: {
|
|
66
|
-
size: number;
|
|
67
|
-
sources: ({
|
|
68
|
-
usedTier: {
|
|
69
|
-
terms: {
|
|
70
|
-
field: string;
|
|
71
|
-
missing_bucket: boolean;
|
|
72
|
-
};
|
|
73
|
-
};
|
|
74
|
-
usageType?: undefined;
|
|
75
|
-
isFreeAgent?: undefined;
|
|
76
|
-
} | {
|
|
77
|
-
usageType: {
|
|
78
|
-
terms: {
|
|
79
|
-
field: string;
|
|
80
|
-
missing_bucket: boolean;
|
|
81
|
-
};
|
|
82
|
-
};
|
|
83
|
-
usedTier?: undefined;
|
|
84
|
-
isFreeAgent?: undefined;
|
|
85
|
-
} | {
|
|
86
|
-
isFreeAgent: {
|
|
87
|
-
terms: {
|
|
88
|
-
field: string;
|
|
89
|
-
missing_bucket: boolean;
|
|
90
|
-
};
|
|
91
|
-
};
|
|
92
|
-
usedTier?: undefined;
|
|
93
|
-
usageType?: undefined;
|
|
94
|
-
})[];
|
|
95
|
-
};
|
|
96
|
-
aggs: {
|
|
97
|
-
audio_usage: {
|
|
98
|
-
filter: {
|
|
99
|
-
term: {
|
|
100
|
-
'eventProperties.usageType.keyword': string;
|
|
101
|
-
};
|
|
102
|
-
};
|
|
103
|
-
aggs: {
|
|
104
|
-
total_usage_units: {
|
|
105
|
-
sum: {
|
|
106
|
-
field: string;
|
|
107
|
-
missing: number;
|
|
108
|
-
};
|
|
109
|
-
};
|
|
110
|
-
};
|
|
111
|
-
};
|
|
112
|
-
};
|
|
113
|
-
};
|
|
114
|
-
};
|
|
115
|
-
};
|
|
116
|
-
transform(elasticOutput: any): GetAgentCostForBroadcastResponse;
|
|
117
|
-
}
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.GetAgentCostForBroadcastQuery = void 0;
|
|
4
|
-
const events_1 = require("@bikdotai/bik-models/events");
|
|
5
|
-
class GetAgentCostForBroadcastQuery {
|
|
6
|
-
getQuery(params) {
|
|
7
|
-
return {
|
|
8
|
-
index: params.indexName,
|
|
9
|
-
size: 0,
|
|
10
|
-
query: {
|
|
11
|
-
bool: {
|
|
12
|
-
filter: [
|
|
13
|
-
{
|
|
14
|
-
range: {
|
|
15
|
-
timestamp: { gte: params.startDate, lte: params.endDate },
|
|
16
|
-
},
|
|
17
|
-
},
|
|
18
|
-
],
|
|
19
|
-
must: [
|
|
20
|
-
{ term: { 'storeId.keyword': { value: params.storeId } } },
|
|
21
|
-
{ term: { 'eventName.keyword': { value: events_1.Events.SERVICE_USED } } },
|
|
22
|
-
{
|
|
23
|
-
term: {
|
|
24
|
-
'eventProperties.useCaseId.keyword': { value: params.broadcastId },
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
],
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
aggs: {
|
|
31
|
-
usage_by_tier_type_agent: {
|
|
32
|
-
composite: {
|
|
33
|
-
size: 10000,
|
|
34
|
-
sources: [
|
|
35
|
-
{
|
|
36
|
-
usedTier: {
|
|
37
|
-
terms: {
|
|
38
|
-
field: 'eventProperties.usedTier.keyword',
|
|
39
|
-
missing_bucket: true,
|
|
40
|
-
},
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
usageType: {
|
|
45
|
-
terms: {
|
|
46
|
-
field: 'eventProperties.usageType.keyword',
|
|
47
|
-
missing_bucket: true,
|
|
48
|
-
},
|
|
49
|
-
},
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
isFreeAgent: {
|
|
53
|
-
terms: {
|
|
54
|
-
field: 'eventProperties.isFreeAgent',
|
|
55
|
-
missing_bucket: true,
|
|
56
|
-
},
|
|
57
|
-
},
|
|
58
|
-
},
|
|
59
|
-
],
|
|
60
|
-
},
|
|
61
|
-
aggs: {
|
|
62
|
-
audio_usage: {
|
|
63
|
-
filter: {
|
|
64
|
-
term: { 'eventProperties.usageType.keyword': 'AUDIO' },
|
|
65
|
-
},
|
|
66
|
-
aggs: {
|
|
67
|
-
total_usage_units: {
|
|
68
|
-
sum: { field: 'eventProperties.usageUnits', missing: 0 },
|
|
69
|
-
},
|
|
70
|
-
},
|
|
71
|
-
},
|
|
72
|
-
},
|
|
73
|
-
},
|
|
74
|
-
},
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
transform(elasticOutput) {
|
|
78
|
-
var _a, _b, _c;
|
|
79
|
-
const buckets = (_c = (_b = (_a = elasticOutput === null || elasticOutput === void 0 ? void 0 : elasticOutput.aggregations) === null || _a === void 0 ? void 0 : _a.usage_by_tier_type_agent) === null || _b === void 0 ? void 0 : _b.buckets) !== null && _c !== void 0 ? _c : [];
|
|
80
|
-
return {
|
|
81
|
-
buckets: buckets
|
|
82
|
-
.filter((b) => b.key.usedTier !== null &&
|
|
83
|
-
b.key.usageType !== null &&
|
|
84
|
-
b.key.isFreeAgent !== null)
|
|
85
|
-
.map((b) => {
|
|
86
|
-
var _a, _b, _c, _d;
|
|
87
|
-
return ({
|
|
88
|
-
usedTier: b.key.usedTier,
|
|
89
|
-
usageType: b.key.usageType,
|
|
90
|
-
isFreeAgent: b.key.isFreeAgent,
|
|
91
|
-
count: (_a = b.doc_count) !== null && _a !== void 0 ? _a : 0,
|
|
92
|
-
usageUnits: (_d = (_c = (_b = b.audio_usage) === null || _b === void 0 ? void 0 : _b.total_usage_units) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : 0,
|
|
93
|
-
});
|
|
94
|
-
}),
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
exports.GetAgentCostForBroadcastQuery = GetAgentCostForBroadcastQuery;
|