adaptic-backend 1.0.340 → 1.0.342
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/Account.cjs +2670 -2264
- package/Account.d.ts +19 -2
- package/Action.cjs +1195 -839
- package/Action.d.ts +19 -2
- package/Alert.cjs +2651 -2347
- package/Alert.d.ts +19 -2
- package/Allocation.cjs +2631 -2304
- package/Allocation.d.ts +19 -2
- package/AlpacaAccount.cjs +2654 -2104
- package/AlpacaAccount.d.ts +19 -2
- package/Asset.cjs +2611 -1544
- package/Asset.d.ts +19 -2
- package/Authenticator.cjs +2603 -2290
- package/Authenticator.d.ts +19 -2
- package/Customer.cjs +2506 -2220
- package/Customer.d.ts +19 -2
- package/EconomicEvent.cjs +708 -367
- package/EconomicEvent.d.ts +19 -2
- package/MarketSentiment.cjs +691 -340
- package/MarketSentiment.d.ts +19 -2
- package/NewsArticle.cjs +2114 -1655
- package/NewsArticle.d.ts +19 -2
- package/NewsArticleAssetSentiment.cjs +1873 -1564
- package/NewsArticleAssetSentiment.d.ts +19 -2
- package/ScheduledOptionOrder.cjs +607 -316
- package/ScheduledOptionOrder.d.ts +19 -2
- package/Session.cjs +2592 -2294
- package/Session.d.ts +19 -2
- package/Trade.cjs +1261 -795
- package/Trade.d.ts +19 -2
- package/User.cjs +2432 -2013
- package/User.d.ts +19 -2
- package/VerificationToken.cjs +637 -328
- package/VerificationToken.d.ts +19 -2
- package/esm/Account.d.ts +19 -2
- package/esm/Account.d.ts.map +1 -1
- package/esm/Account.js.map +1 -1
- package/esm/Account.mjs +2661 -2262
- package/esm/Action.d.ts +19 -2
- package/esm/Action.d.ts.map +1 -1
- package/esm/Action.js.map +1 -1
- package/esm/Action.mjs +1186 -837
- package/esm/Alert.d.ts +19 -2
- package/esm/Alert.d.ts.map +1 -1
- package/esm/Alert.js.map +1 -1
- package/esm/Alert.mjs +2642 -2345
- package/esm/Allocation.d.ts +19 -2
- package/esm/Allocation.d.ts.map +1 -1
- package/esm/Allocation.js.map +1 -1
- package/esm/Allocation.mjs +2622 -2302
- package/esm/AlpacaAccount.d.ts +19 -2
- package/esm/AlpacaAccount.d.ts.map +1 -1
- package/esm/AlpacaAccount.js.map +1 -1
- package/esm/AlpacaAccount.mjs +2645 -2102
- package/esm/Asset.d.ts +19 -2
- package/esm/Asset.d.ts.map +1 -1
- package/esm/Asset.js.map +1 -1
- package/esm/Asset.mjs +2602 -1542
- package/esm/Authenticator.d.ts +19 -2
- package/esm/Authenticator.d.ts.map +1 -1
- package/esm/Authenticator.js.map +1 -1
- package/esm/Authenticator.mjs +2594 -2288
- package/esm/Customer.d.ts +19 -2
- package/esm/Customer.d.ts.map +1 -1
- package/esm/Customer.js.map +1 -1
- package/esm/Customer.mjs +2497 -2218
- package/esm/EconomicEvent.d.ts +19 -2
- package/esm/EconomicEvent.d.ts.map +1 -1
- package/esm/EconomicEvent.js.map +1 -1
- package/esm/EconomicEvent.mjs +699 -365
- package/esm/MarketSentiment.d.ts +19 -2
- package/esm/MarketSentiment.d.ts.map +1 -1
- package/esm/MarketSentiment.js.map +1 -1
- package/esm/MarketSentiment.mjs +682 -338
- package/esm/NewsArticle.d.ts +19 -2
- package/esm/NewsArticle.d.ts.map +1 -1
- package/esm/NewsArticle.js.map +1 -1
- package/esm/NewsArticle.mjs +2105 -1653
- package/esm/NewsArticleAssetSentiment.d.ts +19 -2
- package/esm/NewsArticleAssetSentiment.d.ts.map +1 -1
- package/esm/NewsArticleAssetSentiment.js.map +1 -1
- package/esm/NewsArticleAssetSentiment.mjs +1864 -1562
- package/esm/ScheduledOptionOrder.d.ts +19 -2
- package/esm/ScheduledOptionOrder.d.ts.map +1 -1
- package/esm/ScheduledOptionOrder.js.map +1 -1
- package/esm/ScheduledOptionOrder.mjs +598 -314
- package/esm/Session.d.ts +19 -2
- package/esm/Session.d.ts.map +1 -1
- package/esm/Session.js.map +1 -1
- package/esm/Session.mjs +2583 -2292
- package/esm/Trade.d.ts +19 -2
- package/esm/Trade.d.ts.map +1 -1
- package/esm/Trade.js.map +1 -1
- package/esm/Trade.mjs +1252 -793
- package/esm/User.d.ts +19 -2
- package/esm/User.d.ts.map +1 -1
- package/esm/User.js.map +1 -1
- package/esm/User.mjs +2423 -2011
- package/esm/VerificationToken.d.ts +19 -2
- package/esm/VerificationToken.d.ts.map +1 -1
- package/esm/VerificationToken.js.map +1 -1
- package/esm/VerificationToken.mjs +628 -326
- package/esm/generated/typegraphql-prisma/enhance.js.map +1 -1
- package/esm/generated/typegraphql-prisma/enhance.mjs +1 -1
- package/esm/generated/typegraphql-prisma/resolvers/inputs/AccountWhereUniqueInput.d.ts +1 -1
- package/esm/generated/typegraphql-prisma/resolvers/inputs/AccountWhereUniqueInput.d.ts.map +1 -1
- package/esm/generated/typegraphql-prisma/resolvers/inputs/AccountWhereUniqueInput.js.map +1 -1
- package/esm/generated/typegraphql-prisma/resolvers/inputs/AccountWhereUniqueInput.mjs +7 -7
- package/esm/prismaClient.d.ts +4 -5
- package/esm/prismaClient.d.ts.map +1 -1
- package/esm/prismaClient.js.map +1 -1
- package/esm/prismaClient.mjs +13 -11
- package/generated/typegraphql-prisma/enhance.cjs +1 -1
- package/generated/typegraphql-prisma/enhance.js.map +1 -1
- package/generated/typegraphql-prisma/resolvers/inputs/AccountWhereUniqueInput.cjs +6 -6
- package/generated/typegraphql-prisma/resolvers/inputs/AccountWhereUniqueInput.d.ts +1 -1
- package/generated/typegraphql-prisma/resolvers/inputs/AccountWhereUniqueInput.d.ts.map +1 -1
- package/generated/typegraphql-prisma/resolvers/inputs/AccountWhereUniqueInput.js.map +1 -1
- package/package.json +1 -1
- package/prismaClient.cjs +13 -11
- package/prismaClient.d.ts +4 -5
- package/server.cjs +37 -5
package/Trade.cjs
CHANGED
@@ -55,896 +55,1362 @@ exports.Trade = {
|
|
55
55
|
* @param client - Apollo Client instance.
|
56
56
|
* @returns The created Trade or null.
|
57
57
|
*/
|
58
|
+
/**
|
59
|
+
* Create a new Trade record.
|
60
|
+
* Enhanced with connection resilience against Prisma connection errors.
|
61
|
+
* @param props - Properties for the new record.
|
62
|
+
* @param globalClient - Apollo Client instance.
|
63
|
+
* @returns The created Trade or null.
|
64
|
+
*/
|
58
65
|
async create(props, globalClient) {
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
:
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
66
|
+
var _a, _b, _c, _d, _e;
|
67
|
+
// Maximum number of retries for database connection issues
|
68
|
+
const MAX_RETRIES = 3;
|
69
|
+
let retryCount = 0;
|
70
|
+
let lastError = null;
|
71
|
+
// Retry loop to handle potential database connection issues
|
72
|
+
while (retryCount < MAX_RETRIES) {
|
73
|
+
try {
|
74
|
+
const [modules, client] = await Promise.all([
|
75
|
+
(0, client_1.getApolloModules)(),
|
76
|
+
globalClient
|
77
|
+
? Promise.resolve(globalClient)
|
78
|
+
: client_1.client
|
79
|
+
]);
|
80
|
+
const { gql, ApolloError } = modules;
|
81
|
+
const CREATE_ONE_TRADE = gql `
|
82
|
+
mutation createOneTrade($data: TradeCreateInput!) {
|
83
|
+
createOneTrade(data: $data) {
|
84
|
+
${selectionSet}
|
85
|
+
}
|
86
|
+
}
|
87
|
+
`;
|
88
|
+
const variables = {
|
89
|
+
data: {
|
90
|
+
alpacaAccountId: props.alpacaAccountId !== undefined ? props.alpacaAccountId : undefined,
|
91
|
+
signal: props.signal !== undefined ? props.signal : undefined,
|
92
|
+
strategy: props.strategy !== undefined ? props.strategy : undefined,
|
93
|
+
analysis: props.analysis !== undefined ? props.analysis : undefined,
|
94
|
+
summary: props.summary !== undefined ? props.summary : undefined,
|
95
|
+
confidence: props.confidence !== undefined ? props.confidence : undefined,
|
96
|
+
timestamp: props.timestamp !== undefined ? props.timestamp : undefined,
|
97
|
+
status: props.status !== undefined ? props.status : undefined,
|
98
|
+
symbol: props.symbol !== undefined ? props.symbol : undefined,
|
99
|
+
entryPrice: props.entryPrice !== undefined ? props.entryPrice : undefined,
|
100
|
+
exitPrice: props.exitPrice !== undefined ? props.exitPrice : undefined,
|
101
|
+
entryQty: props.entryQty !== undefined ? props.entryQty : undefined,
|
102
|
+
exitQty: props.exitQty !== undefined ? props.exitQty : undefined,
|
103
|
+
entryValue: props.entryValue !== undefined ? props.entryValue : undefined,
|
104
|
+
exitValue: props.exitValue !== undefined ? props.exitValue : undefined,
|
105
|
+
entryTime: props.entryTime !== undefined ? props.entryTime : undefined,
|
106
|
+
exitTime: props.exitTime !== undefined ? props.exitTime : undefined,
|
107
|
+
pnlAmount: props.pnlAmount !== undefined ? props.pnlAmount : undefined,
|
108
|
+
pnlPercent: props.pnlPercent !== undefined ? props.pnlPercent : undefined,
|
109
|
+
durationMinutes: props.durationMinutes !== undefined ? props.durationMinutes : undefined,
|
110
|
+
marketPhase: props.marketPhase !== undefined ? props.marketPhase : undefined,
|
111
|
+
marketVolatility: props.marketVolatility !== undefined ? props.marketVolatility : undefined,
|
112
|
+
thresholdsJson: props.thresholdsJson !== undefined ? props.thresholdsJson : undefined,
|
113
|
+
actions: props.actions ?
|
114
|
+
Array.isArray(props.actions) && props.actions.length > 0 && props.actions.every((item) => typeof item === 'object' && 'id' in item && Object.keys(item).length === 1) ? {
|
115
|
+
connect: props.actions.map((item) => ({
|
116
|
+
id: item.id
|
117
|
+
}))
|
118
|
+
}
|
119
|
+
: { connectOrCreate: props.actions.map((item) => ({
|
120
|
+
where: {
|
121
|
+
id: item.id !== undefined ? item.id : undefined,
|
122
|
+
alpacaOrderId: item.alpacaOrderId !== undefined ? item.alpacaOrderId : undefined,
|
123
|
+
tradeId: item.tradeId !== undefined ? {
|
124
|
+
equals: item.tradeId
|
125
|
+
} : undefined,
|
126
|
+
},
|
127
|
+
create: {
|
128
|
+
sequence: item.sequence !== undefined ? item.sequence : undefined,
|
129
|
+
type: item.type !== undefined ? item.type : undefined,
|
130
|
+
primary: item.primary !== undefined ? item.primary : undefined,
|
131
|
+
note: item.note !== undefined ? item.note : undefined,
|
132
|
+
status: item.status !== undefined ? item.status : undefined,
|
133
|
+
alpacaOrderId: item.alpacaOrderId !== undefined ? item.alpacaOrderId : undefined,
|
134
|
+
},
|
135
|
+
}))
|
136
|
+
} : undefined,
|
137
|
+
},
|
138
|
+
};
|
139
|
+
const filteredVariables = (0, utils_1.removeUndefinedProps)(variables);
|
140
|
+
const response = await client.mutate({
|
141
|
+
mutation: CREATE_ONE_TRADE,
|
142
|
+
variables: filteredVariables,
|
143
|
+
// Don't cache mutations, but ensure we're using the freshest context
|
144
|
+
fetchPolicy: 'no-cache'
|
145
|
+
});
|
146
|
+
if (response.errors && response.errors.length > 0)
|
147
|
+
throw new Error(response.errors[0].message);
|
148
|
+
if (response && response.data && response.data.createOneTrade) {
|
149
|
+
return response.data.createOneTrade;
|
150
|
+
}
|
151
|
+
else {
|
152
|
+
return null;
|
153
|
+
}
|
131
154
|
}
|
132
|
-
|
133
|
-
|
155
|
+
catch (error) {
|
156
|
+
lastError = error;
|
157
|
+
// Check if this is a database connection error that we should retry
|
158
|
+
const isConnectionError = ((_a = error.message) === null || _a === void 0 ? void 0 : _a.includes('Server has closed the connection')) ||
|
159
|
+
((_b = error.message) === null || _b === void 0 ? void 0 : _b.includes('Cannot reach database server')) ||
|
160
|
+
((_c = error.message) === null || _c === void 0 ? void 0 : _c.includes('Connection timed out')) ||
|
161
|
+
((_d = error.message) === null || _d === void 0 ? void 0 : _d.includes('Accelerate')) || // Prisma Accelerate proxy errors
|
162
|
+
(error.networkError && ((_e = error.networkError.message) === null || _e === void 0 ? void 0 : _e.includes('Failed to fetch')));
|
163
|
+
if (isConnectionError && retryCount < MAX_RETRIES - 1) {
|
164
|
+
retryCount++;
|
165
|
+
const delay = Math.pow(2, retryCount) * 100; // Exponential backoff: 200ms, 400ms, 800ms
|
166
|
+
console.warn("Database connection error, retrying...");
|
167
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
168
|
+
continue;
|
169
|
+
}
|
170
|
+
// Log the error and rethrow
|
171
|
+
console.error("Database error occurred:", error);
|
172
|
+
throw error;
|
134
173
|
}
|
135
174
|
}
|
136
|
-
|
137
|
-
|
138
|
-
throw error;
|
139
|
-
}
|
175
|
+
// If we exhausted retries, throw the last error
|
176
|
+
throw lastError;
|
140
177
|
},
|
141
178
|
/**
|
142
179
|
* Create multiple Trade records.
|
180
|
+
* Enhanced with connection resilience against Prisma connection errors.
|
143
181
|
* @param props - Array of Trade objects for the new records.
|
144
182
|
* @param globalClient - Apollo Client instance.
|
145
183
|
* @returns The count of created records or null.
|
146
184
|
*/
|
147
185
|
async createMany(props, globalClient) {
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
summary: prop.summary !== undefined ? prop.summary : undefined,
|
168
|
-
confidence: prop.confidence !== undefined ? prop.confidence : undefined,
|
169
|
-
timestamp: prop.timestamp !== undefined ? prop.timestamp : undefined,
|
170
|
-
status: prop.status !== undefined ? prop.status : undefined,
|
171
|
-
symbol: prop.symbol !== undefined ? prop.symbol : undefined,
|
172
|
-
entryPrice: prop.entryPrice !== undefined ? prop.entryPrice : undefined,
|
173
|
-
exitPrice: prop.exitPrice !== undefined ? prop.exitPrice : undefined,
|
174
|
-
entryQty: prop.entryQty !== undefined ? prop.entryQty : undefined,
|
175
|
-
exitQty: prop.exitQty !== undefined ? prop.exitQty : undefined,
|
176
|
-
entryValue: prop.entryValue !== undefined ? prop.entryValue : undefined,
|
177
|
-
exitValue: prop.exitValue !== undefined ? prop.exitValue : undefined,
|
178
|
-
entryTime: prop.entryTime !== undefined ? prop.entryTime : undefined,
|
179
|
-
exitTime: prop.exitTime !== undefined ? prop.exitTime : undefined,
|
180
|
-
pnlAmount: prop.pnlAmount !== undefined ? prop.pnlAmount : undefined,
|
181
|
-
pnlPercent: prop.pnlPercent !== undefined ? prop.pnlPercent : undefined,
|
182
|
-
durationMinutes: prop.durationMinutes !== undefined ? prop.durationMinutes : undefined,
|
183
|
-
marketPhase: prop.marketPhase !== undefined ? prop.marketPhase : undefined,
|
184
|
-
marketVolatility: prop.marketVolatility !== undefined ? prop.marketVolatility : undefined,
|
185
|
-
thresholdsJson: prop.thresholdsJson !== undefined ? prop.thresholdsJson : undefined,
|
186
|
-
})),
|
187
|
-
};
|
188
|
-
const filteredVariables = (0, utils_1.removeUndefinedProps)(variables);
|
189
|
-
try {
|
190
|
-
const response = await client.mutate({ mutation: CREATE_MANY_TRADE, variables: filteredVariables });
|
191
|
-
if (response.errors && response.errors.length > 0)
|
192
|
-
throw new Error(response.errors[0].message);
|
193
|
-
if (response && response.data && response.data.createManyTrade) {
|
194
|
-
return response.data.createManyTrade;
|
186
|
+
var _a, _b, _c, _d, _e;
|
187
|
+
// Maximum number of retries for database connection issues
|
188
|
+
const MAX_RETRIES = 3;
|
189
|
+
let retryCount = 0;
|
190
|
+
let lastError = null;
|
191
|
+
// Retry loop to handle potential database connection issues
|
192
|
+
while (retryCount < MAX_RETRIES) {
|
193
|
+
try {
|
194
|
+
const [modules, client] = await Promise.all([
|
195
|
+
(0, client_1.getApolloModules)(),
|
196
|
+
globalClient
|
197
|
+
? Promise.resolve(globalClient)
|
198
|
+
: client_1.client
|
199
|
+
]);
|
200
|
+
const { gql, ApolloError } = modules;
|
201
|
+
const CREATE_MANY_TRADE = gql `
|
202
|
+
mutation createManyTrade($data: [TradeCreateManyInput!]!) {
|
203
|
+
createManyTrade(data: $data) {
|
204
|
+
count
|
195
205
|
}
|
196
|
-
|
197
|
-
|
206
|
+
}`;
|
207
|
+
const variables = {
|
208
|
+
data: props.map(prop => ({
|
209
|
+
alpacaAccountId: prop.alpacaAccountId !== undefined ? prop.alpacaAccountId : undefined,
|
210
|
+
signal: prop.signal !== undefined ? prop.signal : undefined,
|
211
|
+
strategy: prop.strategy !== undefined ? prop.strategy : undefined,
|
212
|
+
analysis: prop.analysis !== undefined ? prop.analysis : undefined,
|
213
|
+
summary: prop.summary !== undefined ? prop.summary : undefined,
|
214
|
+
confidence: prop.confidence !== undefined ? prop.confidence : undefined,
|
215
|
+
timestamp: prop.timestamp !== undefined ? prop.timestamp : undefined,
|
216
|
+
status: prop.status !== undefined ? prop.status : undefined,
|
217
|
+
symbol: prop.symbol !== undefined ? prop.symbol : undefined,
|
218
|
+
entryPrice: prop.entryPrice !== undefined ? prop.entryPrice : undefined,
|
219
|
+
exitPrice: prop.exitPrice !== undefined ? prop.exitPrice : undefined,
|
220
|
+
entryQty: prop.entryQty !== undefined ? prop.entryQty : undefined,
|
221
|
+
exitQty: prop.exitQty !== undefined ? prop.exitQty : undefined,
|
222
|
+
entryValue: prop.entryValue !== undefined ? prop.entryValue : undefined,
|
223
|
+
exitValue: prop.exitValue !== undefined ? prop.exitValue : undefined,
|
224
|
+
entryTime: prop.entryTime !== undefined ? prop.entryTime : undefined,
|
225
|
+
exitTime: prop.exitTime !== undefined ? prop.exitTime : undefined,
|
226
|
+
pnlAmount: prop.pnlAmount !== undefined ? prop.pnlAmount : undefined,
|
227
|
+
pnlPercent: prop.pnlPercent !== undefined ? prop.pnlPercent : undefined,
|
228
|
+
durationMinutes: prop.durationMinutes !== undefined ? prop.durationMinutes : undefined,
|
229
|
+
marketPhase: prop.marketPhase !== undefined ? prop.marketPhase : undefined,
|
230
|
+
marketVolatility: prop.marketVolatility !== undefined ? prop.marketVolatility : undefined,
|
231
|
+
thresholdsJson: prop.thresholdsJson !== undefined ? prop.thresholdsJson : undefined,
|
232
|
+
})),
|
233
|
+
};
|
234
|
+
const filteredVariables = (0, utils_1.removeUndefinedProps)(variables);
|
235
|
+
const response = await client.mutate({
|
236
|
+
mutation: CREATE_MANY_TRADE,
|
237
|
+
variables: filteredVariables,
|
238
|
+
// Don't cache mutations, but ensure we're using the freshest context
|
239
|
+
fetchPolicy: 'no-cache'
|
240
|
+
});
|
241
|
+
if (response.errors && response.errors.length > 0)
|
242
|
+
throw new Error(response.errors[0].message);
|
243
|
+
if (response && response.data && response.data.createManyTrade) {
|
244
|
+
return response.data.createManyTrade;
|
245
|
+
}
|
246
|
+
else {
|
247
|
+
return null;
|
248
|
+
}
|
249
|
+
}
|
250
|
+
catch (error) {
|
251
|
+
lastError = error;
|
252
|
+
// Check if this is a database connection error that we should retry
|
253
|
+
const isConnectionError = ((_a = error.message) === null || _a === void 0 ? void 0 : _a.includes('Server has closed the connection')) ||
|
254
|
+
((_b = error.message) === null || _b === void 0 ? void 0 : _b.includes('Cannot reach database server')) ||
|
255
|
+
((_c = error.message) === null || _c === void 0 ? void 0 : _c.includes('Connection timed out')) ||
|
256
|
+
((_d = error.message) === null || _d === void 0 ? void 0 : _d.includes('Accelerate')) || // Prisma Accelerate proxy errors
|
257
|
+
(error.networkError && ((_e = error.networkError.message) === null || _e === void 0 ? void 0 : _e.includes('Failed to fetch')));
|
258
|
+
if (isConnectionError && retryCount < MAX_RETRIES - 1) {
|
259
|
+
retryCount++;
|
260
|
+
const delay = Math.pow(2, retryCount) * 100; // Exponential backoff: 200ms, 400ms, 800ms
|
261
|
+
console.warn("Database connection error, retrying...");
|
262
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
263
|
+
continue;
|
264
|
+
}
|
265
|
+
// Log the error and rethrow
|
266
|
+
console.error("Database error occurred:", error);
|
267
|
+
throw error;
|
198
268
|
}
|
199
269
|
}
|
200
|
-
|
201
|
-
|
202
|
-
throw error;
|
203
|
-
}
|
270
|
+
// If we exhausted retries, throw the last error
|
271
|
+
throw lastError;
|
204
272
|
},
|
205
273
|
/**
|
206
274
|
* Update a single Trade record.
|
275
|
+
* Enhanced with connection resilience against Prisma connection errors.
|
207
276
|
* @param props - Properties to update.
|
208
277
|
* @param globalClient - Apollo Client instance.
|
209
278
|
* @returns The updated Trade or null.
|
210
279
|
*/
|
211
280
|
async update(props, globalClient) {
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
281
|
+
var _a, _b, _c, _d, _e;
|
282
|
+
// Maximum number of retries for database connection issues
|
283
|
+
const MAX_RETRIES = 3;
|
284
|
+
let retryCount = 0;
|
285
|
+
let lastError = null;
|
286
|
+
// Retry loop to handle potential database connection issues
|
287
|
+
while (retryCount < MAX_RETRIES) {
|
288
|
+
try {
|
289
|
+
const [modules, client] = await Promise.all([
|
290
|
+
(0, client_1.getApolloModules)(),
|
291
|
+
globalClient
|
292
|
+
? Promise.resolve(globalClient)
|
293
|
+
: client_1.client
|
294
|
+
]);
|
295
|
+
const { gql, ApolloError } = modules;
|
296
|
+
const UPDATE_ONE_TRADE = gql `
|
297
|
+
mutation updateOneTrade($data: TradeUpdateInput!, $where: TradeWhereUniqueInput!) {
|
298
|
+
updateOneTrade(data: $data, where: $where) {
|
299
|
+
${selectionSet}
|
300
|
+
}
|
301
|
+
}`;
|
302
|
+
const variables = {
|
303
|
+
where: {
|
304
|
+
id: props.id !== undefined ? props.id : undefined,
|
305
|
+
alpacaAccountId: props.alpacaAccountId !== undefined ? props.alpacaAccountId : undefined,
|
306
|
+
signal: props.signal !== undefined ? {
|
307
|
+
equals: props.signal
|
308
|
+
} : undefined,
|
309
|
+
strategy: props.strategy !== undefined ? {
|
310
|
+
equals: props.strategy
|
311
|
+
} : undefined,
|
312
|
+
analysis: props.analysis !== undefined ? {
|
313
|
+
equals: props.analysis
|
314
|
+
} : undefined,
|
315
|
+
summary: props.summary !== undefined ? {
|
316
|
+
equals: props.summary
|
317
|
+
} : undefined,
|
318
|
+
confidence: props.confidence !== undefined ? {
|
319
|
+
equals: props.confidence
|
320
|
+
} : undefined,
|
321
|
+
timestamp: props.timestamp !== undefined ? {
|
322
|
+
equals: props.timestamp
|
323
|
+
} : undefined,
|
324
|
+
createdAt: props.createdAt !== undefined ? {
|
325
|
+
equals: props.createdAt
|
326
|
+
} : undefined,
|
327
|
+
updatedAt: props.updatedAt !== undefined ? {
|
328
|
+
equals: props.updatedAt
|
329
|
+
} : undefined,
|
330
|
+
status: props.status !== undefined ? {
|
331
|
+
equals: props.status
|
332
|
+
} : undefined,
|
333
|
+
symbol: props.symbol !== undefined ? props.symbol : undefined,
|
334
|
+
entryTime: props.entryTime !== undefined ? {
|
335
|
+
equals: props.entryTime
|
336
|
+
} : undefined,
|
337
|
+
exitTime: props.exitTime !== undefined ? {
|
338
|
+
equals: props.exitTime
|
339
|
+
} : undefined,
|
340
|
+
marketPhase: props.marketPhase !== undefined ? {
|
341
|
+
equals: props.marketPhase
|
342
|
+
} : undefined,
|
343
|
+
marketVolatility: props.marketVolatility !== undefined ? {
|
344
|
+
equals: props.marketVolatility
|
345
|
+
} : undefined,
|
346
|
+
thresholdsJson: props.thresholdsJson !== undefined ? {
|
347
|
+
equals: props.thresholdsJson
|
348
|
+
} : undefined,
|
349
|
+
},
|
350
|
+
data: {
|
351
|
+
id: props.id !== undefined ? {
|
352
|
+
set: props.id
|
353
|
+
} : undefined,
|
354
|
+
alpacaAccountId: props.alpacaAccountId !== undefined ? {
|
355
|
+
set: props.alpacaAccountId
|
356
|
+
} : undefined,
|
357
|
+
signal: props.signal !== undefined ? {
|
358
|
+
set: props.signal
|
359
|
+
} : undefined,
|
360
|
+
strategy: props.strategy !== undefined ? {
|
361
|
+
set: props.strategy
|
362
|
+
} : undefined,
|
363
|
+
analysis: props.analysis !== undefined ? {
|
364
|
+
set: props.analysis
|
365
|
+
} : undefined,
|
366
|
+
summary: props.summary !== undefined ? {
|
367
|
+
set: props.summary
|
368
|
+
} : undefined,
|
369
|
+
confidence: props.confidence !== undefined ? {
|
370
|
+
set: props.confidence
|
371
|
+
} : undefined,
|
372
|
+
timestamp: props.timestamp !== undefined ? {
|
373
|
+
set: props.timestamp
|
374
|
+
} : undefined,
|
375
|
+
createdAt: props.createdAt !== undefined ? {
|
376
|
+
set: props.createdAt
|
377
|
+
} : undefined,
|
378
|
+
updatedAt: props.updatedAt !== undefined ? {
|
379
|
+
set: props.updatedAt
|
380
|
+
} : undefined,
|
381
|
+
status: props.status !== undefined ? {
|
382
|
+
set: props.status
|
383
|
+
} : undefined,
|
384
|
+
symbol: props.symbol !== undefined ? {
|
385
|
+
set: props.symbol
|
386
|
+
} : undefined,
|
387
|
+
entryPrice: props.entryPrice !== undefined ? {
|
388
|
+
set: props.entryPrice
|
389
|
+
} : undefined,
|
390
|
+
exitPrice: props.exitPrice !== undefined ? {
|
391
|
+
set: props.exitPrice
|
392
|
+
} : undefined,
|
393
|
+
entryQty: props.entryQty !== undefined ? {
|
394
|
+
set: props.entryQty
|
395
|
+
} : undefined,
|
396
|
+
exitQty: props.exitQty !== undefined ? {
|
397
|
+
set: props.exitQty
|
398
|
+
} : undefined,
|
399
|
+
entryValue: props.entryValue !== undefined ? {
|
400
|
+
set: props.entryValue
|
401
|
+
} : undefined,
|
402
|
+
exitValue: props.exitValue !== undefined ? {
|
403
|
+
set: props.exitValue
|
404
|
+
} : undefined,
|
405
|
+
entryTime: props.entryTime !== undefined ? {
|
406
|
+
set: props.entryTime
|
407
|
+
} : undefined,
|
408
|
+
exitTime: props.exitTime !== undefined ? {
|
409
|
+
set: props.exitTime
|
410
|
+
} : undefined,
|
411
|
+
pnlAmount: props.pnlAmount !== undefined ? {
|
412
|
+
set: props.pnlAmount
|
413
|
+
} : undefined,
|
414
|
+
pnlPercent: props.pnlPercent !== undefined ? {
|
415
|
+
set: props.pnlPercent
|
416
|
+
} : undefined,
|
417
|
+
durationMinutes: props.durationMinutes !== undefined ? {
|
418
|
+
set: props.durationMinutes
|
419
|
+
} : undefined,
|
420
|
+
marketPhase: props.marketPhase !== undefined ? {
|
421
|
+
set: props.marketPhase
|
422
|
+
} : undefined,
|
423
|
+
marketVolatility: props.marketVolatility !== undefined ? {
|
424
|
+
set: props.marketVolatility
|
425
|
+
} : undefined,
|
426
|
+
thresholdsJson: props.thresholdsJson !== undefined ? {
|
427
|
+
set: props.thresholdsJson
|
428
|
+
} : undefined,
|
429
|
+
actions: props.actions ?
|
430
|
+
Array.isArray(props.actions) && props.actions.length > 0 && props.actions.every((item) => typeof item === 'object' && ('id' in item || 'symbol' in item) && Object.keys(item).length === 1) ? {
|
431
|
+
connect: props.actions.map((item) => ({
|
432
|
+
id: item.id
|
433
|
+
}))
|
434
|
+
} : { upsert: props.actions.map((item) => ({
|
435
|
+
where: {
|
436
|
+
id: item.id !== undefined ? item.id : undefined,
|
437
|
+
alpacaOrderId: item.alpacaOrderId !== undefined ? item.alpacaOrderId : undefined,
|
438
|
+
tradeId: item.tradeId !== undefined ? {
|
439
|
+
equals: item.tradeId
|
440
|
+
} : undefined,
|
441
|
+
},
|
442
|
+
update: {
|
443
|
+
id: item.id !== undefined ? {
|
444
|
+
set: item.id
|
445
|
+
} : undefined,
|
446
|
+
sequence: item.sequence !== undefined ? {
|
447
|
+
set: item.sequence
|
448
|
+
} : undefined,
|
449
|
+
type: item.type !== undefined ? {
|
450
|
+
set: item.type
|
451
|
+
} : undefined,
|
452
|
+
primary: item.primary !== undefined ? {
|
453
|
+
set: item.primary
|
454
|
+
} : undefined,
|
455
|
+
note: item.note !== undefined ? {
|
456
|
+
set: item.note
|
457
|
+
} : undefined,
|
458
|
+
status: item.status !== undefined ? {
|
459
|
+
set: item.status
|
460
|
+
} : undefined,
|
461
|
+
alpacaOrderId: item.alpacaOrderId !== undefined ? {
|
462
|
+
set: item.alpacaOrderId
|
463
|
+
} : undefined,
|
464
|
+
},
|
465
|
+
create: {
|
466
|
+
sequence: item.sequence !== undefined ? item.sequence : undefined,
|
467
|
+
type: item.type !== undefined ? item.type : undefined,
|
468
|
+
primary: item.primary !== undefined ? item.primary : undefined,
|
469
|
+
note: item.note !== undefined ? item.note : undefined,
|
470
|
+
status: item.status !== undefined ? item.status : undefined,
|
471
|
+
alpacaOrderId: item.alpacaOrderId !== undefined ? item.alpacaOrderId : undefined,
|
472
|
+
},
|
473
|
+
}))
|
474
|
+
} : undefined,
|
475
|
+
},
|
476
|
+
};
|
477
|
+
const filteredVariables = (0, utils_1.removeUndefinedProps)(variables);
|
478
|
+
const response = await client.mutate({
|
479
|
+
mutation: UPDATE_ONE_TRADE,
|
480
|
+
variables: filteredVariables,
|
481
|
+
// Don't cache mutations, but ensure we're using the freshest context
|
482
|
+
fetchPolicy: 'no-cache'
|
483
|
+
});
|
484
|
+
if (response.errors && response.errors.length > 0)
|
485
|
+
throw new Error(response.errors[0].message);
|
486
|
+
if (response && response.data && response.data.updateOneTrade) {
|
487
|
+
return response.data.updateOneTrade;
|
488
|
+
}
|
489
|
+
else {
|
490
|
+
return null;
|
491
|
+
}
|
369
492
|
}
|
370
|
-
|
371
|
-
|
493
|
+
catch (error) {
|
494
|
+
lastError = error;
|
495
|
+
// Check if this is a database connection error that we should retry
|
496
|
+
const isConnectionError = ((_a = error.message) === null || _a === void 0 ? void 0 : _a.includes('Server has closed the connection')) ||
|
497
|
+
((_b = error.message) === null || _b === void 0 ? void 0 : _b.includes('Cannot reach database server')) ||
|
498
|
+
((_c = error.message) === null || _c === void 0 ? void 0 : _c.includes('Connection timed out')) ||
|
499
|
+
((_d = error.message) === null || _d === void 0 ? void 0 : _d.includes('Accelerate')) || // Prisma Accelerate proxy errors
|
500
|
+
(error.networkError && ((_e = error.networkError.message) === null || _e === void 0 ? void 0 : _e.includes('Failed to fetch')));
|
501
|
+
if (isConnectionError && retryCount < MAX_RETRIES - 1) {
|
502
|
+
retryCount++;
|
503
|
+
const delay = Math.pow(2, retryCount) * 100; // Exponential backoff: 200ms, 400ms, 800ms
|
504
|
+
console.warn("Database connection error, retrying...");
|
505
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
506
|
+
continue;
|
507
|
+
}
|
508
|
+
// Log the error and rethrow
|
509
|
+
console.error("Database error occurred:", error);
|
510
|
+
throw error;
|
372
511
|
}
|
373
512
|
}
|
374
|
-
|
375
|
-
|
376
|
-
throw error;
|
377
|
-
}
|
513
|
+
// If we exhausted retries, throw the last error
|
514
|
+
throw lastError;
|
378
515
|
},
|
379
516
|
/**
|
380
517
|
* Upsert a single Trade record.
|
518
|
+
* Enhanced with connection resilience against Prisma connection errors.
|
381
519
|
* @param props - Properties to update.
|
382
520
|
* @param globalClient - Apollo Client instance.
|
383
521
|
* @returns The updated Trade or null.
|
384
522
|
*/
|
385
523
|
async upsert(props, globalClient) {
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
}
|
438
|
-
|
439
|
-
:
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
set: props.exitValue
|
503
|
-
} : undefined,
|
504
|
-
entryTime: props.entryTime !== undefined ? {
|
505
|
-
set: props.entryTime
|
506
|
-
} : undefined,
|
507
|
-
exitTime: props.exitTime !== undefined ? {
|
508
|
-
set: props.exitTime
|
509
|
-
} : undefined,
|
510
|
-
pnlAmount: props.pnlAmount !== undefined ? {
|
511
|
-
set: props.pnlAmount
|
512
|
-
} : undefined,
|
513
|
-
pnlPercent: props.pnlPercent !== undefined ? {
|
514
|
-
set: props.pnlPercent
|
515
|
-
} : undefined,
|
516
|
-
durationMinutes: props.durationMinutes !== undefined ? {
|
517
|
-
set: props.durationMinutes
|
518
|
-
} : undefined,
|
519
|
-
marketPhase: props.marketPhase !== undefined ? {
|
520
|
-
set: props.marketPhase
|
521
|
-
} : undefined,
|
522
|
-
marketVolatility: props.marketVolatility !== undefined ? {
|
523
|
-
set: props.marketVolatility
|
524
|
-
} : undefined,
|
525
|
-
thresholdsJson: props.thresholdsJson !== undefined ? {
|
526
|
-
set: props.thresholdsJson
|
527
|
-
} : undefined,
|
528
|
-
actions: props.actions ?
|
529
|
-
Array.isArray(props.actions) && props.actions.length > 0 && props.actions.every((item) => typeof item === 'object' && ('id' in item || 'symbol' in item) && Object.keys(item).length === 1) ? {
|
530
|
-
connect: props.actions.map((item) => ({
|
531
|
-
id: item.id
|
532
|
-
}))
|
533
|
-
} : { upsert: props.actions.map((item) => ({
|
534
|
-
where: {
|
535
|
-
id: item.id !== undefined ? item.id : undefined,
|
536
|
-
alpacaOrderId: item.alpacaOrderId !== undefined ? item.alpacaOrderId : undefined,
|
537
|
-
tradeId: item.tradeId !== undefined ? {
|
538
|
-
equals: item.tradeId
|
539
|
-
} : undefined,
|
540
|
-
},
|
541
|
-
update: {
|
542
|
-
id: item.id !== undefined ? {
|
543
|
-
set: item.id
|
544
|
-
} : undefined,
|
545
|
-
sequence: item.sequence !== undefined ? {
|
546
|
-
set: item.sequence
|
547
|
-
} : undefined,
|
548
|
-
type: item.type !== undefined ? {
|
549
|
-
set: item.type
|
550
|
-
} : undefined,
|
551
|
-
primary: item.primary !== undefined ? {
|
552
|
-
set: item.primary
|
553
|
-
} : undefined,
|
554
|
-
note: item.note !== undefined ? {
|
555
|
-
set: item.note
|
556
|
-
} : undefined,
|
557
|
-
status: item.status !== undefined ? {
|
558
|
-
set: item.status
|
559
|
-
} : undefined,
|
560
|
-
alpacaOrderId: item.alpacaOrderId !== undefined ? {
|
561
|
-
set: item.alpacaOrderId
|
524
|
+
var _a, _b, _c, _d, _e;
|
525
|
+
// Maximum number of retries for database connection issues
|
526
|
+
const MAX_RETRIES = 3;
|
527
|
+
let retryCount = 0;
|
528
|
+
let lastError = null;
|
529
|
+
// Retry loop to handle potential database connection issues
|
530
|
+
while (retryCount < MAX_RETRIES) {
|
531
|
+
try {
|
532
|
+
const [modules, client] = await Promise.all([
|
533
|
+
(0, client_1.getApolloModules)(),
|
534
|
+
globalClient
|
535
|
+
? Promise.resolve(globalClient)
|
536
|
+
: client_1.client
|
537
|
+
]);
|
538
|
+
const { gql, ApolloError } = modules;
|
539
|
+
const UPSERT_ONE_TRADE = gql `
|
540
|
+
mutation upsertOneTrade($where: TradeWhereUniqueInput!, $create: TradeCreateInput!, $update: TradeUpdateInput!) {
|
541
|
+
upsertOneTrade(where: $where, create: $create, update: $update) {
|
542
|
+
${selectionSet}
|
543
|
+
}
|
544
|
+
}`;
|
545
|
+
const variables = {
|
546
|
+
where: {
|
547
|
+
id: props.id !== undefined ? props.id : undefined,
|
548
|
+
alpacaAccountId: props.alpacaAccountId !== undefined ? props.alpacaAccountId : undefined,
|
549
|
+
signal: props.signal !== undefined ? {
|
550
|
+
equals: props.signal
|
551
|
+
} : undefined,
|
552
|
+
strategy: props.strategy !== undefined ? {
|
553
|
+
equals: props.strategy
|
554
|
+
} : undefined,
|
555
|
+
analysis: props.analysis !== undefined ? {
|
556
|
+
equals: props.analysis
|
557
|
+
} : undefined,
|
558
|
+
summary: props.summary !== undefined ? {
|
559
|
+
equals: props.summary
|
560
|
+
} : undefined,
|
561
|
+
confidence: props.confidence !== undefined ? {
|
562
|
+
equals: props.confidence
|
563
|
+
} : undefined,
|
564
|
+
timestamp: props.timestamp !== undefined ? {
|
565
|
+
equals: props.timestamp
|
566
|
+
} : undefined,
|
567
|
+
createdAt: props.createdAt !== undefined ? {
|
568
|
+
equals: props.createdAt
|
569
|
+
} : undefined,
|
570
|
+
updatedAt: props.updatedAt !== undefined ? {
|
571
|
+
equals: props.updatedAt
|
572
|
+
} : undefined,
|
573
|
+
status: props.status !== undefined ? {
|
574
|
+
equals: props.status
|
575
|
+
} : undefined,
|
576
|
+
symbol: props.symbol !== undefined ? props.symbol : undefined,
|
577
|
+
entryTime: props.entryTime !== undefined ? {
|
578
|
+
equals: props.entryTime
|
579
|
+
} : undefined,
|
580
|
+
exitTime: props.exitTime !== undefined ? {
|
581
|
+
equals: props.exitTime
|
582
|
+
} : undefined,
|
583
|
+
marketPhase: props.marketPhase !== undefined ? {
|
584
|
+
equals: props.marketPhase
|
585
|
+
} : undefined,
|
586
|
+
marketVolatility: props.marketVolatility !== undefined ? {
|
587
|
+
equals: props.marketVolatility
|
588
|
+
} : undefined,
|
589
|
+
thresholdsJson: props.thresholdsJson !== undefined ? {
|
590
|
+
equals: props.thresholdsJson
|
591
|
+
} : undefined,
|
592
|
+
},
|
593
|
+
create: {
|
594
|
+
alpacaAccountId: props.alpacaAccountId !== undefined ? props.alpacaAccountId : undefined,
|
595
|
+
signal: props.signal !== undefined ? props.signal : undefined,
|
596
|
+
strategy: props.strategy !== undefined ? props.strategy : undefined,
|
597
|
+
analysis: props.analysis !== undefined ? props.analysis : undefined,
|
598
|
+
summary: props.summary !== undefined ? props.summary : undefined,
|
599
|
+
confidence: props.confidence !== undefined ? props.confidence : undefined,
|
600
|
+
timestamp: props.timestamp !== undefined ? props.timestamp : undefined,
|
601
|
+
status: props.status !== undefined ? props.status : undefined,
|
602
|
+
symbol: props.symbol !== undefined ? props.symbol : undefined,
|
603
|
+
entryPrice: props.entryPrice !== undefined ? props.entryPrice : undefined,
|
604
|
+
exitPrice: props.exitPrice !== undefined ? props.exitPrice : undefined,
|
605
|
+
entryQty: props.entryQty !== undefined ? props.entryQty : undefined,
|
606
|
+
exitQty: props.exitQty !== undefined ? props.exitQty : undefined,
|
607
|
+
entryValue: props.entryValue !== undefined ? props.entryValue : undefined,
|
608
|
+
exitValue: props.exitValue !== undefined ? props.exitValue : undefined,
|
609
|
+
entryTime: props.entryTime !== undefined ? props.entryTime : undefined,
|
610
|
+
exitTime: props.exitTime !== undefined ? props.exitTime : undefined,
|
611
|
+
pnlAmount: props.pnlAmount !== undefined ? props.pnlAmount : undefined,
|
612
|
+
pnlPercent: props.pnlPercent !== undefined ? props.pnlPercent : undefined,
|
613
|
+
durationMinutes: props.durationMinutes !== undefined ? props.durationMinutes : undefined,
|
614
|
+
marketPhase: props.marketPhase !== undefined ? props.marketPhase : undefined,
|
615
|
+
marketVolatility: props.marketVolatility !== undefined ? props.marketVolatility : undefined,
|
616
|
+
thresholdsJson: props.thresholdsJson !== undefined ? props.thresholdsJson : undefined,
|
617
|
+
actions: props.actions ?
|
618
|
+
Array.isArray(props.actions) && props.actions.length > 0 && props.actions.every((item) => typeof item === 'object' && 'id' in item && Object.keys(item).length === 1) ? {
|
619
|
+
connect: props.actions.map((item) => ({
|
620
|
+
id: item.id
|
621
|
+
}))
|
622
|
+
}
|
623
|
+
: { connectOrCreate: props.actions.map((item) => ({
|
624
|
+
where: {
|
625
|
+
id: item.id !== undefined ? item.id : undefined,
|
626
|
+
alpacaOrderId: item.alpacaOrderId !== undefined ? item.alpacaOrderId : undefined,
|
627
|
+
tradeId: item.tradeId !== undefined ? {
|
628
|
+
equals: item.tradeId
|
629
|
+
} : undefined,
|
630
|
+
},
|
631
|
+
create: {
|
632
|
+
sequence: item.sequence !== undefined ? item.sequence : undefined,
|
633
|
+
type: item.type !== undefined ? item.type : undefined,
|
634
|
+
primary: item.primary !== undefined ? item.primary : undefined,
|
635
|
+
note: item.note !== undefined ? item.note : undefined,
|
636
|
+
status: item.status !== undefined ? item.status : undefined,
|
637
|
+
alpacaOrderId: item.alpacaOrderId !== undefined ? item.alpacaOrderId : undefined,
|
638
|
+
},
|
639
|
+
}))
|
562
640
|
} : undefined,
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
641
|
+
},
|
642
|
+
update: {
|
643
|
+
alpacaAccountId: props.alpacaAccountId !== undefined ? {
|
644
|
+
set: props.alpacaAccountId
|
645
|
+
} : undefined,
|
646
|
+
signal: props.signal !== undefined ? {
|
647
|
+
set: props.signal
|
648
|
+
} : undefined,
|
649
|
+
strategy: props.strategy !== undefined ? {
|
650
|
+
set: props.strategy
|
651
|
+
} : undefined,
|
652
|
+
analysis: props.analysis !== undefined ? {
|
653
|
+
set: props.analysis
|
654
|
+
} : undefined,
|
655
|
+
summary: props.summary !== undefined ? {
|
656
|
+
set: props.summary
|
657
|
+
} : undefined,
|
658
|
+
confidence: props.confidence !== undefined ? {
|
659
|
+
set: props.confidence
|
660
|
+
} : undefined,
|
661
|
+
timestamp: props.timestamp !== undefined ? {
|
662
|
+
set: props.timestamp
|
663
|
+
} : undefined,
|
664
|
+
status: props.status !== undefined ? {
|
665
|
+
set: props.status
|
666
|
+
} : undefined,
|
667
|
+
symbol: props.symbol !== undefined ? {
|
668
|
+
set: props.symbol
|
669
|
+
} : undefined,
|
670
|
+
entryPrice: props.entryPrice !== undefined ? {
|
671
|
+
set: props.entryPrice
|
672
|
+
} : undefined,
|
673
|
+
exitPrice: props.exitPrice !== undefined ? {
|
674
|
+
set: props.exitPrice
|
675
|
+
} : undefined,
|
676
|
+
entryQty: props.entryQty !== undefined ? {
|
677
|
+
set: props.entryQty
|
678
|
+
} : undefined,
|
679
|
+
exitQty: props.exitQty !== undefined ? {
|
680
|
+
set: props.exitQty
|
681
|
+
} : undefined,
|
682
|
+
entryValue: props.entryValue !== undefined ? {
|
683
|
+
set: props.entryValue
|
684
|
+
} : undefined,
|
685
|
+
exitValue: props.exitValue !== undefined ? {
|
686
|
+
set: props.exitValue
|
687
|
+
} : undefined,
|
688
|
+
entryTime: props.entryTime !== undefined ? {
|
689
|
+
set: props.entryTime
|
690
|
+
} : undefined,
|
691
|
+
exitTime: props.exitTime !== undefined ? {
|
692
|
+
set: props.exitTime
|
693
|
+
} : undefined,
|
694
|
+
pnlAmount: props.pnlAmount !== undefined ? {
|
695
|
+
set: props.pnlAmount
|
696
|
+
} : undefined,
|
697
|
+
pnlPercent: props.pnlPercent !== undefined ? {
|
698
|
+
set: props.pnlPercent
|
699
|
+
} : undefined,
|
700
|
+
durationMinutes: props.durationMinutes !== undefined ? {
|
701
|
+
set: props.durationMinutes
|
702
|
+
} : undefined,
|
703
|
+
marketPhase: props.marketPhase !== undefined ? {
|
704
|
+
set: props.marketPhase
|
705
|
+
} : undefined,
|
706
|
+
marketVolatility: props.marketVolatility !== undefined ? {
|
707
|
+
set: props.marketVolatility
|
708
|
+
} : undefined,
|
709
|
+
thresholdsJson: props.thresholdsJson !== undefined ? {
|
710
|
+
set: props.thresholdsJson
|
711
|
+
} : undefined,
|
712
|
+
actions: props.actions ?
|
713
|
+
Array.isArray(props.actions) && props.actions.length > 0 && props.actions.every((item) => typeof item === 'object' && ('id' in item || 'symbol' in item) && Object.keys(item).length === 1) ? {
|
714
|
+
connect: props.actions.map((item) => ({
|
715
|
+
id: item.id
|
716
|
+
}))
|
717
|
+
} : { upsert: props.actions.map((item) => ({
|
718
|
+
where: {
|
719
|
+
id: item.id !== undefined ? item.id : undefined,
|
720
|
+
alpacaOrderId: item.alpacaOrderId !== undefined ? item.alpacaOrderId : undefined,
|
721
|
+
tradeId: item.tradeId !== undefined ? {
|
722
|
+
equals: item.tradeId
|
723
|
+
} : undefined,
|
724
|
+
},
|
725
|
+
update: {
|
726
|
+
id: item.id !== undefined ? {
|
727
|
+
set: item.id
|
728
|
+
} : undefined,
|
729
|
+
sequence: item.sequence !== undefined ? {
|
730
|
+
set: item.sequence
|
731
|
+
} : undefined,
|
732
|
+
type: item.type !== undefined ? {
|
733
|
+
set: item.type
|
734
|
+
} : undefined,
|
735
|
+
primary: item.primary !== undefined ? {
|
736
|
+
set: item.primary
|
737
|
+
} : undefined,
|
738
|
+
note: item.note !== undefined ? {
|
739
|
+
set: item.note
|
740
|
+
} : undefined,
|
741
|
+
status: item.status !== undefined ? {
|
742
|
+
set: item.status
|
743
|
+
} : undefined,
|
744
|
+
alpacaOrderId: item.alpacaOrderId !== undefined ? {
|
745
|
+
set: item.alpacaOrderId
|
746
|
+
} : undefined,
|
747
|
+
},
|
748
|
+
create: {
|
749
|
+
sequence: item.sequence !== undefined ? item.sequence : undefined,
|
750
|
+
type: item.type !== undefined ? item.type : undefined,
|
751
|
+
primary: item.primary !== undefined ? item.primary : undefined,
|
752
|
+
note: item.note !== undefined ? item.note : undefined,
|
753
|
+
status: item.status !== undefined ? item.status : undefined,
|
754
|
+
alpacaOrderId: item.alpacaOrderId !== undefined ? item.alpacaOrderId : undefined,
|
755
|
+
},
|
756
|
+
}))
|
757
|
+
} : undefined,
|
758
|
+
},
|
759
|
+
};
|
760
|
+
const filteredVariables = (0, utils_1.removeUndefinedProps)(variables);
|
761
|
+
const response = await client.mutate({
|
762
|
+
mutation: UPSERT_ONE_TRADE,
|
763
|
+
variables: filteredVariables,
|
764
|
+
// Don't cache mutations, but ensure we're using the freshest context
|
765
|
+
fetchPolicy: 'no-cache'
|
766
|
+
});
|
767
|
+
if (response.errors && response.errors.length > 0)
|
768
|
+
throw new Error(response.errors[0].message);
|
769
|
+
if (response && response.data && response.data.upsertOneTrade) {
|
770
|
+
return response.data.upsertOneTrade;
|
771
|
+
}
|
772
|
+
else {
|
773
|
+
return null;
|
774
|
+
}
|
583
775
|
}
|
584
|
-
|
585
|
-
|
776
|
+
catch (error) {
|
777
|
+
lastError = error;
|
778
|
+
// Check if this is a database connection error that we should retry
|
779
|
+
const isConnectionError = ((_a = error.message) === null || _a === void 0 ? void 0 : _a.includes('Server has closed the connection')) ||
|
780
|
+
((_b = error.message) === null || _b === void 0 ? void 0 : _b.includes('Cannot reach database server')) ||
|
781
|
+
((_c = error.message) === null || _c === void 0 ? void 0 : _c.includes('Connection timed out')) ||
|
782
|
+
((_d = error.message) === null || _d === void 0 ? void 0 : _d.includes('Accelerate')) || // Prisma Accelerate proxy errors
|
783
|
+
(error.networkError && ((_e = error.networkError.message) === null || _e === void 0 ? void 0 : _e.includes('Failed to fetch')));
|
784
|
+
if (isConnectionError && retryCount < MAX_RETRIES - 1) {
|
785
|
+
retryCount++;
|
786
|
+
const delay = Math.pow(2, retryCount) * 100; // Exponential backoff: 200ms, 400ms, 800ms
|
787
|
+
console.warn("Database connection error, retrying...");
|
788
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
789
|
+
continue;
|
790
|
+
}
|
791
|
+
// Log the error and rethrow
|
792
|
+
console.error("Database error occurred:", error);
|
793
|
+
throw error;
|
586
794
|
}
|
587
795
|
}
|
588
|
-
|
589
|
-
|
590
|
-
throw error;
|
591
|
-
}
|
796
|
+
// If we exhausted retries, throw the last error
|
797
|
+
throw lastError;
|
592
798
|
},
|
593
799
|
/**
|
594
800
|
* Update multiple Trade records.
|
801
|
+
* Enhanced with connection resilience against Prisma connection errors.
|
595
802
|
* @param props - Array of Trade objects for the updated records.
|
596
803
|
* @param globalClient - Apollo Client instance.
|
597
804
|
* @returns The count of created records or null.
|
598
805
|
*/
|
599
806
|
async updateMany(props, globalClient) {
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
symbol: prop.symbol !== undefined ? {
|
620
|
-
equals: prop.symbol
|
621
|
-
} : undefined,
|
622
|
-
},
|
623
|
-
data: {
|
624
|
-
id: prop.id !== undefined ? {
|
625
|
-
set: prop.id
|
626
|
-
} : undefined,
|
627
|
-
alpacaAccountId: prop.alpacaAccountId !== undefined ? {
|
628
|
-
set: prop.alpacaAccountId
|
629
|
-
} : undefined,
|
630
|
-
signal: prop.signal !== undefined ? {
|
631
|
-
set: prop.signal
|
632
|
-
} : undefined,
|
633
|
-
strategy: prop.strategy !== undefined ? {
|
634
|
-
set: prop.strategy
|
635
|
-
} : undefined,
|
636
|
-
analysis: prop.analysis !== undefined ? {
|
637
|
-
set: prop.analysis
|
638
|
-
} : undefined,
|
639
|
-
summary: prop.summary !== undefined ? {
|
640
|
-
set: prop.summary
|
641
|
-
} : undefined,
|
642
|
-
confidence: prop.confidence !== undefined ? {
|
643
|
-
set: prop.confidence
|
644
|
-
} : undefined,
|
645
|
-
timestamp: prop.timestamp !== undefined ? {
|
646
|
-
set: prop.timestamp
|
647
|
-
} : undefined,
|
648
|
-
createdAt: prop.createdAt !== undefined ? {
|
649
|
-
set: prop.createdAt
|
650
|
-
} : undefined,
|
651
|
-
updatedAt: prop.updatedAt !== undefined ? {
|
652
|
-
set: prop.updatedAt
|
653
|
-
} : undefined,
|
654
|
-
status: prop.status !== undefined ? {
|
655
|
-
set: prop.status
|
656
|
-
} : undefined,
|
657
|
-
symbol: prop.symbol !== undefined ? {
|
658
|
-
set: prop.symbol
|
659
|
-
} : undefined,
|
660
|
-
entryPrice: prop.entryPrice !== undefined ? {
|
661
|
-
set: prop.entryPrice
|
662
|
-
} : undefined,
|
663
|
-
exitPrice: prop.exitPrice !== undefined ? {
|
664
|
-
set: prop.exitPrice
|
665
|
-
} : undefined,
|
666
|
-
entryQty: prop.entryQty !== undefined ? {
|
667
|
-
set: prop.entryQty
|
668
|
-
} : undefined,
|
669
|
-
exitQty: prop.exitQty !== undefined ? {
|
670
|
-
set: prop.exitQty
|
671
|
-
} : undefined,
|
672
|
-
entryValue: prop.entryValue !== undefined ? {
|
673
|
-
set: prop.entryValue
|
674
|
-
} : undefined,
|
675
|
-
exitValue: prop.exitValue !== undefined ? {
|
676
|
-
set: prop.exitValue
|
677
|
-
} : undefined,
|
678
|
-
entryTime: prop.entryTime !== undefined ? {
|
679
|
-
set: prop.entryTime
|
680
|
-
} : undefined,
|
681
|
-
exitTime: prop.exitTime !== undefined ? {
|
682
|
-
set: prop.exitTime
|
683
|
-
} : undefined,
|
684
|
-
pnlAmount: prop.pnlAmount !== undefined ? {
|
685
|
-
set: prop.pnlAmount
|
686
|
-
} : undefined,
|
687
|
-
pnlPercent: prop.pnlPercent !== undefined ? {
|
688
|
-
set: prop.pnlPercent
|
689
|
-
} : undefined,
|
690
|
-
durationMinutes: prop.durationMinutes !== undefined ? {
|
691
|
-
set: prop.durationMinutes
|
692
|
-
} : undefined,
|
693
|
-
marketPhase: prop.marketPhase !== undefined ? {
|
694
|
-
set: prop.marketPhase
|
695
|
-
} : undefined,
|
696
|
-
marketVolatility: prop.marketVolatility !== undefined ? {
|
697
|
-
set: prop.marketVolatility
|
698
|
-
} : undefined,
|
699
|
-
thresholdsJson: prop.thresholdsJson !== undefined ? {
|
700
|
-
set: prop.thresholdsJson
|
701
|
-
} : undefined,
|
702
|
-
actions: prop.actions ?
|
703
|
-
Array.isArray(prop.actions) && prop.actions.length > 0 && prop.actions.every((item) => typeof item === 'object' && ('id' in item || 'symbol' in item) && Object.keys(item).length === 1) ? {
|
704
|
-
connect: prop.actions.map((item) => ({
|
705
|
-
id: item.id
|
706
|
-
}))
|
707
|
-
} : { upsert: prop.actions.map((item) => ({
|
708
|
-
where: {
|
709
|
-
id: item.id !== undefined ? item.id : undefined,
|
710
|
-
alpacaOrderId: item.alpacaOrderId !== undefined ? item.alpacaOrderId : undefined,
|
711
|
-
tradeId: item.tradeId !== undefined ? {
|
712
|
-
equals: item.tradeId
|
713
|
-
} : undefined,
|
714
|
-
},
|
715
|
-
update: {
|
716
|
-
id: item.id !== undefined ? {
|
717
|
-
set: item.id
|
718
|
-
} : undefined,
|
719
|
-
sequence: item.sequence !== undefined ? {
|
720
|
-
set: item.sequence
|
721
|
-
} : undefined,
|
722
|
-
type: item.type !== undefined ? {
|
723
|
-
set: item.type
|
724
|
-
} : undefined,
|
725
|
-
primary: item.primary !== undefined ? {
|
726
|
-
set: item.primary
|
727
|
-
} : undefined,
|
728
|
-
note: item.note !== undefined ? {
|
729
|
-
set: item.note
|
730
|
-
} : undefined,
|
731
|
-
status: item.status !== undefined ? {
|
732
|
-
set: item.status
|
733
|
-
} : undefined,
|
734
|
-
alpacaOrderId: item.alpacaOrderId !== undefined ? {
|
735
|
-
set: item.alpacaOrderId
|
736
|
-
} : undefined,
|
737
|
-
},
|
738
|
-
create: {
|
739
|
-
sequence: item.sequence !== undefined ? item.sequence : undefined,
|
740
|
-
type: item.type !== undefined ? item.type : undefined,
|
741
|
-
primary: item.primary !== undefined ? item.primary : undefined,
|
742
|
-
note: item.note !== undefined ? item.note : undefined,
|
743
|
-
status: item.status !== undefined ? item.status : undefined,
|
744
|
-
alpacaOrderId: item.alpacaOrderId !== undefined ? item.alpacaOrderId : undefined,
|
745
|
-
},
|
746
|
-
}))
|
747
|
-
} : undefined,
|
748
|
-
},
|
749
|
-
}));
|
750
|
-
const filteredVariables = (0, utils_1.removeUndefinedProps)(variables);
|
751
|
-
try {
|
752
|
-
const response = await client.mutate({ mutation: UPDATE_MANY_TRADE, variables: filteredVariables });
|
753
|
-
if (response.errors && response.errors.length > 0)
|
754
|
-
throw new Error(response.errors[0].message);
|
755
|
-
if (response && response.data && response.data.updateManyTrade) {
|
756
|
-
return response.data.updateManyTrade;
|
807
|
+
var _a, _b, _c, _d, _e;
|
808
|
+
// Maximum number of retries for database connection issues
|
809
|
+
const MAX_RETRIES = 3;
|
810
|
+
let retryCount = 0;
|
811
|
+
let lastError = null;
|
812
|
+
// Retry loop to handle potential database connection issues
|
813
|
+
while (retryCount < MAX_RETRIES) {
|
814
|
+
try {
|
815
|
+
const [modules, client] = await Promise.all([
|
816
|
+
(0, client_1.getApolloModules)(),
|
817
|
+
globalClient
|
818
|
+
? Promise.resolve(globalClient)
|
819
|
+
: client_1.client
|
820
|
+
]);
|
821
|
+
const { gql, ApolloError } = modules;
|
822
|
+
const UPDATE_MANY_TRADE = gql `
|
823
|
+
mutation updateManyTrade($data: [TradeCreateManyInput!]!) {
|
824
|
+
updateManyTrade(data: $data) {
|
825
|
+
count
|
757
826
|
}
|
758
|
-
|
759
|
-
|
827
|
+
}`;
|
828
|
+
const variables = props.map(prop => ({
|
829
|
+
where: {
|
830
|
+
id: prop.id !== undefined ? prop.id : undefined,
|
831
|
+
alpacaAccountId: prop.alpacaAccountId !== undefined ? prop.alpacaAccountId : undefined,
|
832
|
+
signal: prop.signal !== undefined ? {
|
833
|
+
equals: prop.signal
|
834
|
+
} : undefined,
|
835
|
+
strategy: prop.strategy !== undefined ? {
|
836
|
+
equals: prop.strategy
|
837
|
+
} : undefined,
|
838
|
+
analysis: prop.analysis !== undefined ? {
|
839
|
+
equals: prop.analysis
|
840
|
+
} : undefined,
|
841
|
+
summary: prop.summary !== undefined ? {
|
842
|
+
equals: prop.summary
|
843
|
+
} : undefined,
|
844
|
+
confidence: prop.confidence !== undefined ? {
|
845
|
+
equals: prop.confidence
|
846
|
+
} : undefined,
|
847
|
+
timestamp: prop.timestamp !== undefined ? {
|
848
|
+
equals: prop.timestamp
|
849
|
+
} : undefined,
|
850
|
+
createdAt: prop.createdAt !== undefined ? {
|
851
|
+
equals: prop.createdAt
|
852
|
+
} : undefined,
|
853
|
+
updatedAt: prop.updatedAt !== undefined ? {
|
854
|
+
equals: prop.updatedAt
|
855
|
+
} : undefined,
|
856
|
+
status: prop.status !== undefined ? {
|
857
|
+
equals: prop.status
|
858
|
+
} : undefined,
|
859
|
+
symbol: prop.symbol !== undefined ? prop.symbol : undefined,
|
860
|
+
entryTime: prop.entryTime !== undefined ? {
|
861
|
+
equals: prop.entryTime
|
862
|
+
} : undefined,
|
863
|
+
exitTime: prop.exitTime !== undefined ? {
|
864
|
+
equals: prop.exitTime
|
865
|
+
} : undefined,
|
866
|
+
marketPhase: prop.marketPhase !== undefined ? {
|
867
|
+
equals: prop.marketPhase
|
868
|
+
} : undefined,
|
869
|
+
marketVolatility: prop.marketVolatility !== undefined ? {
|
870
|
+
equals: prop.marketVolatility
|
871
|
+
} : undefined,
|
872
|
+
thresholdsJson: prop.thresholdsJson !== undefined ? {
|
873
|
+
equals: prop.thresholdsJson
|
874
|
+
} : undefined,
|
875
|
+
},
|
876
|
+
data: {
|
877
|
+
id: prop.id !== undefined ? {
|
878
|
+
set: prop.id
|
879
|
+
} : undefined,
|
880
|
+
alpacaAccountId: prop.alpacaAccountId !== undefined ? {
|
881
|
+
set: prop.alpacaAccountId
|
882
|
+
} : undefined,
|
883
|
+
signal: prop.signal !== undefined ? {
|
884
|
+
set: prop.signal
|
885
|
+
} : undefined,
|
886
|
+
strategy: prop.strategy !== undefined ? {
|
887
|
+
set: prop.strategy
|
888
|
+
} : undefined,
|
889
|
+
analysis: prop.analysis !== undefined ? {
|
890
|
+
set: prop.analysis
|
891
|
+
} : undefined,
|
892
|
+
summary: prop.summary !== undefined ? {
|
893
|
+
set: prop.summary
|
894
|
+
} : undefined,
|
895
|
+
confidence: prop.confidence !== undefined ? {
|
896
|
+
set: prop.confidence
|
897
|
+
} : undefined,
|
898
|
+
timestamp: prop.timestamp !== undefined ? {
|
899
|
+
set: prop.timestamp
|
900
|
+
} : undefined,
|
901
|
+
createdAt: prop.createdAt !== undefined ? {
|
902
|
+
set: prop.createdAt
|
903
|
+
} : undefined,
|
904
|
+
updatedAt: prop.updatedAt !== undefined ? {
|
905
|
+
set: prop.updatedAt
|
906
|
+
} : undefined,
|
907
|
+
status: prop.status !== undefined ? {
|
908
|
+
set: prop.status
|
909
|
+
} : undefined,
|
910
|
+
symbol: prop.symbol !== undefined ? {
|
911
|
+
set: prop.symbol
|
912
|
+
} : undefined,
|
913
|
+
entryPrice: prop.entryPrice !== undefined ? {
|
914
|
+
set: prop.entryPrice
|
915
|
+
} : undefined,
|
916
|
+
exitPrice: prop.exitPrice !== undefined ? {
|
917
|
+
set: prop.exitPrice
|
918
|
+
} : undefined,
|
919
|
+
entryQty: prop.entryQty !== undefined ? {
|
920
|
+
set: prop.entryQty
|
921
|
+
} : undefined,
|
922
|
+
exitQty: prop.exitQty !== undefined ? {
|
923
|
+
set: prop.exitQty
|
924
|
+
} : undefined,
|
925
|
+
entryValue: prop.entryValue !== undefined ? {
|
926
|
+
set: prop.entryValue
|
927
|
+
} : undefined,
|
928
|
+
exitValue: prop.exitValue !== undefined ? {
|
929
|
+
set: prop.exitValue
|
930
|
+
} : undefined,
|
931
|
+
entryTime: prop.entryTime !== undefined ? {
|
932
|
+
set: prop.entryTime
|
933
|
+
} : undefined,
|
934
|
+
exitTime: prop.exitTime !== undefined ? {
|
935
|
+
set: prop.exitTime
|
936
|
+
} : undefined,
|
937
|
+
pnlAmount: prop.pnlAmount !== undefined ? {
|
938
|
+
set: prop.pnlAmount
|
939
|
+
} : undefined,
|
940
|
+
pnlPercent: prop.pnlPercent !== undefined ? {
|
941
|
+
set: prop.pnlPercent
|
942
|
+
} : undefined,
|
943
|
+
durationMinutes: prop.durationMinutes !== undefined ? {
|
944
|
+
set: prop.durationMinutes
|
945
|
+
} : undefined,
|
946
|
+
marketPhase: prop.marketPhase !== undefined ? {
|
947
|
+
set: prop.marketPhase
|
948
|
+
} : undefined,
|
949
|
+
marketVolatility: prop.marketVolatility !== undefined ? {
|
950
|
+
set: prop.marketVolatility
|
951
|
+
} : undefined,
|
952
|
+
thresholdsJson: prop.thresholdsJson !== undefined ? {
|
953
|
+
set: prop.thresholdsJson
|
954
|
+
} : undefined,
|
955
|
+
actions: prop.actions ?
|
956
|
+
Array.isArray(prop.actions) && prop.actions.length > 0 && prop.actions.every((item) => typeof item === 'object' && ('id' in item || 'symbol' in item) && Object.keys(item).length === 1) ? {
|
957
|
+
connect: prop.actions.map((item) => ({
|
958
|
+
id: item.id
|
959
|
+
}))
|
960
|
+
} : { upsert: prop.actions.map((item) => ({
|
961
|
+
where: {
|
962
|
+
id: item.id !== undefined ? item.id : undefined,
|
963
|
+
alpacaOrderId: item.alpacaOrderId !== undefined ? item.alpacaOrderId : undefined,
|
964
|
+
tradeId: item.tradeId !== undefined ? {
|
965
|
+
equals: item.tradeId
|
966
|
+
} : undefined,
|
967
|
+
},
|
968
|
+
update: {
|
969
|
+
id: item.id !== undefined ? {
|
970
|
+
set: item.id
|
971
|
+
} : undefined,
|
972
|
+
sequence: item.sequence !== undefined ? {
|
973
|
+
set: item.sequence
|
974
|
+
} : undefined,
|
975
|
+
type: item.type !== undefined ? {
|
976
|
+
set: item.type
|
977
|
+
} : undefined,
|
978
|
+
primary: item.primary !== undefined ? {
|
979
|
+
set: item.primary
|
980
|
+
} : undefined,
|
981
|
+
note: item.note !== undefined ? {
|
982
|
+
set: item.note
|
983
|
+
} : undefined,
|
984
|
+
status: item.status !== undefined ? {
|
985
|
+
set: item.status
|
986
|
+
} : undefined,
|
987
|
+
alpacaOrderId: item.alpacaOrderId !== undefined ? {
|
988
|
+
set: item.alpacaOrderId
|
989
|
+
} : undefined,
|
990
|
+
},
|
991
|
+
create: {
|
992
|
+
sequence: item.sequence !== undefined ? item.sequence : undefined,
|
993
|
+
type: item.type !== undefined ? item.type : undefined,
|
994
|
+
primary: item.primary !== undefined ? item.primary : undefined,
|
995
|
+
note: item.note !== undefined ? item.note : undefined,
|
996
|
+
status: item.status !== undefined ? item.status : undefined,
|
997
|
+
alpacaOrderId: item.alpacaOrderId !== undefined ? item.alpacaOrderId : undefined,
|
998
|
+
},
|
999
|
+
}))
|
1000
|
+
} : undefined,
|
1001
|
+
},
|
1002
|
+
}));
|
1003
|
+
const filteredVariables = (0, utils_1.removeUndefinedProps)(variables);
|
1004
|
+
const response = await client.mutate({
|
1005
|
+
mutation: UPDATE_MANY_TRADE,
|
1006
|
+
variables: filteredVariables,
|
1007
|
+
// Don't cache mutations, but ensure we're using the freshest context
|
1008
|
+
fetchPolicy: 'no-cache'
|
1009
|
+
});
|
1010
|
+
if (response.errors && response.errors.length > 0)
|
1011
|
+
throw new Error(response.errors[0].message);
|
1012
|
+
if (response && response.data && response.data.updateManyTrade) {
|
1013
|
+
return response.data.updateManyTrade;
|
1014
|
+
}
|
1015
|
+
else {
|
1016
|
+
return null;
|
1017
|
+
}
|
1018
|
+
}
|
1019
|
+
catch (error) {
|
1020
|
+
lastError = error;
|
1021
|
+
// Check if this is a database connection error that we should retry
|
1022
|
+
const isConnectionError = ((_a = error.message) === null || _a === void 0 ? void 0 : _a.includes('Server has closed the connection')) ||
|
1023
|
+
((_b = error.message) === null || _b === void 0 ? void 0 : _b.includes('Cannot reach database server')) ||
|
1024
|
+
((_c = error.message) === null || _c === void 0 ? void 0 : _c.includes('Connection timed out')) ||
|
1025
|
+
((_d = error.message) === null || _d === void 0 ? void 0 : _d.includes('Accelerate')) || // Prisma Accelerate proxy errors
|
1026
|
+
(error.networkError && ((_e = error.networkError.message) === null || _e === void 0 ? void 0 : _e.includes('Failed to fetch')));
|
1027
|
+
if (isConnectionError && retryCount < MAX_RETRIES - 1) {
|
1028
|
+
retryCount++;
|
1029
|
+
const delay = Math.pow(2, retryCount) * 100; // Exponential backoff: 200ms, 400ms, 800ms
|
1030
|
+
console.warn("Database connection error, retrying...");
|
1031
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
1032
|
+
continue;
|
1033
|
+
}
|
1034
|
+
// Log the error and rethrow
|
1035
|
+
console.error("Database error occurred:", error);
|
1036
|
+
throw error;
|
760
1037
|
}
|
761
1038
|
}
|
762
|
-
|
763
|
-
|
764
|
-
throw error;
|
765
|
-
}
|
1039
|
+
// If we exhausted retries, throw the last error
|
1040
|
+
throw lastError;
|
766
1041
|
},
|
767
1042
|
/**
|
768
1043
|
* Delete a single Trade record.
|
769
|
-
*
|
1044
|
+
* Enhanced with connection resilience against Prisma connection errors.
|
1045
|
+
* @param props - Properties to identify the record to delete.
|
770
1046
|
* @param globalClient - Apollo Client instance.
|
771
1047
|
* @returns The deleted Trade or null.
|
772
1048
|
*/
|
773
1049
|
async delete(props, globalClient) {
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
1050
|
+
var _a, _b, _c, _d, _e;
|
1051
|
+
// Maximum number of retries for database connection issues
|
1052
|
+
const MAX_RETRIES = 3;
|
1053
|
+
let retryCount = 0;
|
1054
|
+
let lastError = null;
|
1055
|
+
// Retry loop to handle potential database connection issues
|
1056
|
+
while (retryCount < MAX_RETRIES) {
|
1057
|
+
try {
|
1058
|
+
const [modules, client] = await Promise.all([
|
1059
|
+
(0, client_1.getApolloModules)(),
|
1060
|
+
globalClient
|
1061
|
+
? Promise.resolve(globalClient)
|
1062
|
+
: client_1.client
|
1063
|
+
]);
|
1064
|
+
const { gql, ApolloError } = modules;
|
1065
|
+
const DELETE_ONE_TRADE = gql `
|
1066
|
+
mutation deleteOneTrade($where: TradeWhereUniqueInput!) {
|
1067
|
+
deleteOneTrade(where: $where) {
|
1068
|
+
id
|
790
1069
|
}
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
1070
|
+
}`;
|
1071
|
+
const variables = {
|
1072
|
+
where: {
|
1073
|
+
id: props.id ? props.id : undefined,
|
1074
|
+
}
|
1075
|
+
};
|
1076
|
+
const filteredVariables = (0, utils_1.removeUndefinedProps)(variables);
|
1077
|
+
const response = await client.mutate({
|
1078
|
+
mutation: DELETE_ONE_TRADE,
|
1079
|
+
variables: filteredVariables,
|
1080
|
+
// Don't cache mutations, but ensure we're using the freshest context
|
1081
|
+
fetchPolicy: 'no-cache'
|
1082
|
+
});
|
1083
|
+
if (response.errors && response.errors.length > 0)
|
1084
|
+
throw new Error(response.errors[0].message);
|
1085
|
+
if (response && response.data && response.data.deleteOneTrade) {
|
1086
|
+
return response.data.deleteOneTrade;
|
1087
|
+
}
|
1088
|
+
else {
|
1089
|
+
return null;
|
1090
|
+
}
|
799
1091
|
}
|
800
|
-
|
801
|
-
|
1092
|
+
catch (error) {
|
1093
|
+
lastError = error;
|
1094
|
+
// Check if this is a database connection error that we should retry
|
1095
|
+
const isConnectionError = ((_a = error.message) === null || _a === void 0 ? void 0 : _a.includes('Server has closed the connection')) ||
|
1096
|
+
((_b = error.message) === null || _b === void 0 ? void 0 : _b.includes('Cannot reach database server')) ||
|
1097
|
+
((_c = error.message) === null || _c === void 0 ? void 0 : _c.includes('Connection timed out')) ||
|
1098
|
+
((_d = error.message) === null || _d === void 0 ? void 0 : _d.includes('Accelerate')) || // Prisma Accelerate proxy errors
|
1099
|
+
(error.networkError && ((_e = error.networkError.message) === null || _e === void 0 ? void 0 : _e.includes('Failed to fetch')));
|
1100
|
+
if (isConnectionError && retryCount < MAX_RETRIES - 1) {
|
1101
|
+
retryCount++;
|
1102
|
+
const delay = Math.pow(2, retryCount) * 100; // Exponential backoff: 200ms, 400ms, 800ms
|
1103
|
+
console.warn("Database connection error, retrying...");
|
1104
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
1105
|
+
continue;
|
1106
|
+
}
|
1107
|
+
// Log the error and rethrow
|
1108
|
+
console.error("Database error occurred:", error);
|
1109
|
+
throw error;
|
802
1110
|
}
|
803
1111
|
}
|
804
|
-
|
805
|
-
|
806
|
-
throw error;
|
807
|
-
}
|
1112
|
+
// If we exhausted retries, throw the last error
|
1113
|
+
throw lastError;
|
808
1114
|
},
|
809
1115
|
/**
|
810
1116
|
* Retrieve a single Trade record by ID.
|
811
|
-
*
|
1117
|
+
* Enhanced with connection resilience against Prisma connection errors.
|
1118
|
+
* @param props - Properties to identify the record.
|
812
1119
|
* @param globalClient - Apollo Client instance.
|
1120
|
+
* @param whereInput - Optional custom where input.
|
813
1121
|
* @returns The retrieved Trade or null.
|
814
1122
|
*/
|
815
1123
|
async get(props, globalClient, whereInput) {
|
816
|
-
var _a, _b;
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
1124
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
1125
|
+
// Maximum number of retries for database connection issues
|
1126
|
+
const MAX_RETRIES = 3;
|
1127
|
+
let retryCount = 0;
|
1128
|
+
let lastError = null;
|
1129
|
+
// Retry loop to handle potential database connection issues
|
1130
|
+
while (retryCount < MAX_RETRIES) {
|
1131
|
+
try {
|
1132
|
+
const [modules, client] = await Promise.all([
|
1133
|
+
(0, client_1.getApolloModules)(),
|
1134
|
+
globalClient
|
1135
|
+
? Promise.resolve(globalClient)
|
1136
|
+
: client_1.client
|
1137
|
+
]);
|
1138
|
+
const { gql, ApolloError } = modules;
|
1139
|
+
const GET_TRADE = gql `
|
1140
|
+
query getTrade($where: TradeWhereUniqueInput!) {
|
1141
|
+
getTrade(where: $where) {
|
1142
|
+
${selectionSet}
|
1143
|
+
}
|
1144
|
+
}`;
|
1145
|
+
const variables = {
|
1146
|
+
where: whereInput ? whereInput : {
|
1147
|
+
id: props.id !== undefined ? props.id : undefined,
|
1148
|
+
alpacaAccountId: props.alpacaAccountId !== undefined ? props.alpacaAccountId : undefined,
|
1149
|
+
signal: props.signal !== undefined ? {
|
1150
|
+
equals: props.signal
|
1151
|
+
} : undefined,
|
1152
|
+
strategy: props.strategy !== undefined ? {
|
1153
|
+
equals: props.strategy
|
1154
|
+
} : undefined,
|
1155
|
+
analysis: props.analysis !== undefined ? {
|
1156
|
+
equals: props.analysis
|
1157
|
+
} : undefined,
|
1158
|
+
summary: props.summary !== undefined ? {
|
1159
|
+
equals: props.summary
|
1160
|
+
} : undefined,
|
1161
|
+
confidence: props.confidence !== undefined ? {
|
1162
|
+
equals: props.confidence
|
1163
|
+
} : undefined,
|
1164
|
+
timestamp: props.timestamp !== undefined ? {
|
1165
|
+
equals: props.timestamp
|
1166
|
+
} : undefined,
|
1167
|
+
createdAt: props.createdAt !== undefined ? {
|
1168
|
+
equals: props.createdAt
|
1169
|
+
} : undefined,
|
1170
|
+
updatedAt: props.updatedAt !== undefined ? {
|
1171
|
+
equals: props.updatedAt
|
1172
|
+
} : undefined,
|
1173
|
+
status: props.status !== undefined ? {
|
1174
|
+
equals: props.status
|
1175
|
+
} : undefined,
|
1176
|
+
symbol: props.symbol !== undefined ? props.symbol : undefined,
|
1177
|
+
entryTime: props.entryTime !== undefined ? {
|
1178
|
+
equals: props.entryTime
|
1179
|
+
} : undefined,
|
1180
|
+
exitTime: props.exitTime !== undefined ? {
|
1181
|
+
equals: props.exitTime
|
1182
|
+
} : undefined,
|
1183
|
+
marketPhase: props.marketPhase !== undefined ? {
|
1184
|
+
equals: props.marketPhase
|
1185
|
+
} : undefined,
|
1186
|
+
marketVolatility: props.marketVolatility !== undefined ? {
|
1187
|
+
equals: props.marketVolatility
|
1188
|
+
} : undefined,
|
1189
|
+
thresholdsJson: props.thresholdsJson !== undefined ? {
|
1190
|
+
equals: props.thresholdsJson
|
1191
|
+
} : undefined,
|
1192
|
+
},
|
1193
|
+
};
|
1194
|
+
const filteredVariables = (0, utils_1.removeUndefinedProps)(variables);
|
1195
|
+
const response = await client.query({
|
1196
|
+
query: GET_TRADE,
|
1197
|
+
variables: filteredVariables,
|
1198
|
+
fetchPolicy: 'network-only', // Force network request to avoid stale cache
|
1199
|
+
});
|
1200
|
+
if (response.errors && response.errors.length > 0)
|
1201
|
+
throw new Error(response.errors[0].message);
|
1202
|
+
return (_b = (_a = response.data) === null || _a === void 0 ? void 0 : _a.getTrade) !== null && _b !== void 0 ? _b : null;
|
851
1203
|
}
|
852
|
-
|
853
|
-
|
1204
|
+
catch (error) {
|
1205
|
+
lastError = error;
|
1206
|
+
// Check if this is a "No record found" error - this is an expected condition, not a failure
|
1207
|
+
if (error.message === 'No Trade found') {
|
1208
|
+
return null;
|
1209
|
+
}
|
1210
|
+
// Check if this is a database connection error that we should retry
|
1211
|
+
const isConnectionError = ((_c = error.message) === null || _c === void 0 ? void 0 : _c.includes('Server has closed the connection')) ||
|
1212
|
+
((_d = error.message) === null || _d === void 0 ? void 0 : _d.includes('Cannot reach database server')) ||
|
1213
|
+
((_e = error.message) === null || _e === void 0 ? void 0 : _e.includes('Connection timed out')) ||
|
1214
|
+
((_f = error.message) === null || _f === void 0 ? void 0 : _f.includes('Accelerate')) || // Prisma Accelerate proxy errors
|
1215
|
+
(error.networkError && ((_g = error.networkError.message) === null || _g === void 0 ? void 0 : _g.includes('Failed to fetch')));
|
1216
|
+
if (isConnectionError && retryCount < MAX_RETRIES - 1) {
|
1217
|
+
retryCount++;
|
1218
|
+
const delay = Math.pow(2, retryCount) * 100; // Exponential backoff: 200ms, 400ms, 800ms
|
1219
|
+
console.warn("Database connection error, retrying...");
|
1220
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
1221
|
+
continue;
|
1222
|
+
}
|
1223
|
+
// Log the error and rethrow
|
1224
|
+
console.error("Database error occurred:", error);
|
854
1225
|
throw error;
|
855
1226
|
}
|
856
1227
|
}
|
1228
|
+
// If we exhausted retries, throw the last error
|
1229
|
+
throw lastError;
|
857
1230
|
},
|
858
1231
|
/**
|
859
1232
|
* Retrieve all Trades records.
|
1233
|
+
* Enhanced with connection resilience against Prisma connection errors.
|
860
1234
|
* @param globalClient - Apollo Client instance.
|
861
1235
|
* @returns An array of Trade records or null.
|
862
1236
|
*/
|
863
1237
|
async getAll(globalClient) {
|
864
|
-
var _a, _b;
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
1238
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
1239
|
+
// Maximum number of retries for database connection issues
|
1240
|
+
const MAX_RETRIES = 3;
|
1241
|
+
let retryCount = 0;
|
1242
|
+
let lastError = null;
|
1243
|
+
// Retry loop to handle potential database connection issues
|
1244
|
+
while (retryCount < MAX_RETRIES) {
|
1245
|
+
try {
|
1246
|
+
const [modules, client] = await Promise.all([
|
1247
|
+
(0, client_1.getApolloModules)(),
|
1248
|
+
globalClient
|
1249
|
+
? Promise.resolve(globalClient)
|
1250
|
+
: client_1.client
|
1251
|
+
]);
|
1252
|
+
const { gql, ApolloError } = modules;
|
1253
|
+
const GET_ALL_TRADE = gql `
|
1254
|
+
query getAllTrade {
|
1255
|
+
trades {
|
1256
|
+
${selectionSet}
|
1257
|
+
}
|
1258
|
+
}`;
|
1259
|
+
const response = await client.query({
|
1260
|
+
query: GET_ALL_TRADE,
|
1261
|
+
fetchPolicy: 'network-only', // Force network request to avoid stale cache
|
1262
|
+
});
|
1263
|
+
if (response.errors && response.errors.length > 0)
|
1264
|
+
throw new Error(response.errors[0].message);
|
1265
|
+
return (_b = (_a = response.data) === null || _a === void 0 ? void 0 : _a.trades) !== null && _b !== void 0 ? _b : null;
|
887
1266
|
}
|
888
|
-
|
889
|
-
|
1267
|
+
catch (error) {
|
1268
|
+
lastError = error;
|
1269
|
+
// Check if this is a "No record found" error - this is an expected condition, not a failure
|
1270
|
+
if (error.message === 'No Trade found') {
|
1271
|
+
return null;
|
1272
|
+
}
|
1273
|
+
// Check if this is a database connection error that we should retry
|
1274
|
+
const isConnectionError = ((_c = error.message) === null || _c === void 0 ? void 0 : _c.includes('Server has closed the connection')) ||
|
1275
|
+
((_d = error.message) === null || _d === void 0 ? void 0 : _d.includes('Cannot reach database server')) ||
|
1276
|
+
((_e = error.message) === null || _e === void 0 ? void 0 : _e.includes('Connection timed out')) ||
|
1277
|
+
((_f = error.message) === null || _f === void 0 ? void 0 : _f.includes('Accelerate')) || // Prisma Accelerate proxy errors
|
1278
|
+
(error.networkError && ((_g = error.networkError.message) === null || _g === void 0 ? void 0 : _g.includes('Failed to fetch')));
|
1279
|
+
if (isConnectionError && retryCount < MAX_RETRIES - 1) {
|
1280
|
+
retryCount++;
|
1281
|
+
const delay = Math.pow(2, retryCount) * 100; // Exponential backoff: 200ms, 400ms, 800ms
|
1282
|
+
console.warn("Database connection error, retrying...");
|
1283
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
1284
|
+
continue;
|
1285
|
+
}
|
1286
|
+
// Log the error and rethrow
|
1287
|
+
console.error("Database error occurred:", error);
|
890
1288
|
throw error;
|
891
1289
|
}
|
892
1290
|
}
|
1291
|
+
// If we exhausted retries, throw the last error
|
1292
|
+
throw lastError;
|
893
1293
|
},
|
894
1294
|
/**
|
895
1295
|
* Find multiple Trade records based on conditions.
|
1296
|
+
* Enhanced with connection resilience against Prisma connection errors.
|
896
1297
|
* @param props - Conditions to find records.
|
897
1298
|
* @param globalClient - Apollo Client instance.
|
1299
|
+
* @param whereInput - Optional custom where input.
|
898
1300
|
* @returns An array of found Trade records or null.
|
899
1301
|
*/
|
900
1302
|
async findMany(props, globalClient, whereInput) {
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
equals: props.alpacaAccountId
|
921
|
-
} : undefined,
|
922
|
-
symbol: props.symbol !== undefined ? {
|
923
|
-
equals: props.symbol
|
924
|
-
} : undefined,
|
925
|
-
},
|
926
|
-
};
|
927
|
-
const filteredVariables = (0, utils_1.removeUndefinedProps)(variables);
|
928
|
-
try {
|
929
|
-
const response = await client.query({ query: FIND_MANY_TRADE, variables: filteredVariables });
|
930
|
-
if (response.errors && response.errors.length > 0)
|
931
|
-
throw new Error(response.errors[0].message);
|
932
|
-
if (response && response.data && response.data.trades) {
|
933
|
-
return response.data.trades;
|
1303
|
+
var _a, _b, _c, _d, _e;
|
1304
|
+
// Maximum number of retries for database connection issues
|
1305
|
+
const MAX_RETRIES = 3;
|
1306
|
+
let retryCount = 0;
|
1307
|
+
let lastError = null;
|
1308
|
+
// Retry loop to handle potential database connection issues
|
1309
|
+
while (retryCount < MAX_RETRIES) {
|
1310
|
+
try {
|
1311
|
+
const [modules, client] = await Promise.all([
|
1312
|
+
(0, client_1.getApolloModules)(),
|
1313
|
+
globalClient
|
1314
|
+
? Promise.resolve(globalClient)
|
1315
|
+
: client_1.client
|
1316
|
+
]);
|
1317
|
+
const { gql, ApolloError } = modules;
|
1318
|
+
const FIND_MANY_TRADE = gql `
|
1319
|
+
query findManyTrade($where: TradeWhereInput!) {
|
1320
|
+
trades(where: $where) {
|
1321
|
+
${selectionSet}
|
934
1322
|
}
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
|
1323
|
+
}`;
|
1324
|
+
const variables = {
|
1325
|
+
where: whereInput ? whereInput : {
|
1326
|
+
id: props.id !== undefined ? props.id : undefined,
|
1327
|
+
alpacaAccountId: props.alpacaAccountId !== undefined ? props.alpacaAccountId : undefined,
|
1328
|
+
signal: props.signal !== undefined ? {
|
1329
|
+
equals: props.signal
|
1330
|
+
} : undefined,
|
1331
|
+
strategy: props.strategy !== undefined ? {
|
1332
|
+
equals: props.strategy
|
1333
|
+
} : undefined,
|
1334
|
+
analysis: props.analysis !== undefined ? {
|
1335
|
+
equals: props.analysis
|
1336
|
+
} : undefined,
|
1337
|
+
summary: props.summary !== undefined ? {
|
1338
|
+
equals: props.summary
|
1339
|
+
} : undefined,
|
1340
|
+
confidence: props.confidence !== undefined ? {
|
1341
|
+
equals: props.confidence
|
1342
|
+
} : undefined,
|
1343
|
+
timestamp: props.timestamp !== undefined ? {
|
1344
|
+
equals: props.timestamp
|
1345
|
+
} : undefined,
|
1346
|
+
createdAt: props.createdAt !== undefined ? {
|
1347
|
+
equals: props.createdAt
|
1348
|
+
} : undefined,
|
1349
|
+
updatedAt: props.updatedAt !== undefined ? {
|
1350
|
+
equals: props.updatedAt
|
1351
|
+
} : undefined,
|
1352
|
+
status: props.status !== undefined ? {
|
1353
|
+
equals: props.status
|
1354
|
+
} : undefined,
|
1355
|
+
symbol: props.symbol !== undefined ? props.symbol : undefined,
|
1356
|
+
entryTime: props.entryTime !== undefined ? {
|
1357
|
+
equals: props.entryTime
|
1358
|
+
} : undefined,
|
1359
|
+
exitTime: props.exitTime !== undefined ? {
|
1360
|
+
equals: props.exitTime
|
1361
|
+
} : undefined,
|
1362
|
+
marketPhase: props.marketPhase !== undefined ? {
|
1363
|
+
equals: props.marketPhase
|
1364
|
+
} : undefined,
|
1365
|
+
marketVolatility: props.marketVolatility !== undefined ? {
|
1366
|
+
equals: props.marketVolatility
|
1367
|
+
} : undefined,
|
1368
|
+
thresholdsJson: props.thresholdsJson !== undefined ? {
|
1369
|
+
equals: props.thresholdsJson
|
1370
|
+
} : undefined,
|
1371
|
+
},
|
1372
|
+
};
|
1373
|
+
const filteredVariables = (0, utils_1.removeUndefinedProps)(variables);
|
1374
|
+
const response = await client.query({
|
1375
|
+
query: FIND_MANY_TRADE,
|
1376
|
+
variables: filteredVariables,
|
1377
|
+
fetchPolicy: 'network-only', // Force network request to avoid stale cache
|
1378
|
+
});
|
1379
|
+
if (response.errors && response.errors.length > 0)
|
1380
|
+
throw new Error(response.errors[0].message);
|
1381
|
+
if (response && response.data && response.data.trades) {
|
1382
|
+
return response.data.trades;
|
1383
|
+
}
|
1384
|
+
else {
|
1385
|
+
return [];
|
1386
|
+
}
|
942
1387
|
}
|
943
|
-
|
944
|
-
|
1388
|
+
catch (error) {
|
1389
|
+
lastError = error;
|
1390
|
+
// Check if this is a "No record found" error - this is an expected condition, not a failure
|
1391
|
+
if (error.message === 'No Trade found') {
|
1392
|
+
return null;
|
1393
|
+
}
|
1394
|
+
// Check if this is a database connection error that we should retry
|
1395
|
+
const isConnectionError = ((_a = error.message) === null || _a === void 0 ? void 0 : _a.includes('Server has closed the connection')) ||
|
1396
|
+
((_b = error.message) === null || _b === void 0 ? void 0 : _b.includes('Cannot reach database server')) ||
|
1397
|
+
((_c = error.message) === null || _c === void 0 ? void 0 : _c.includes('Connection timed out')) ||
|
1398
|
+
((_d = error.message) === null || _d === void 0 ? void 0 : _d.includes('Accelerate')) || // Prisma Accelerate proxy errors
|
1399
|
+
(error.networkError && ((_e = error.networkError.message) === null || _e === void 0 ? void 0 : _e.includes('Failed to fetch')));
|
1400
|
+
if (isConnectionError && retryCount < MAX_RETRIES - 1) {
|
1401
|
+
retryCount++;
|
1402
|
+
const delay = Math.pow(2, retryCount) * 100; // Exponential backoff: 200ms, 400ms, 800ms
|
1403
|
+
console.warn("Database connection error, retrying...");
|
1404
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
1405
|
+
continue;
|
1406
|
+
}
|
1407
|
+
// Log the error and rethrow
|
1408
|
+
console.error("Database error occurred:", error);
|
945
1409
|
throw error;
|
946
1410
|
}
|
947
1411
|
}
|
1412
|
+
// If we exhausted retries, throw the last error
|
1413
|
+
throw lastError;
|
948
1414
|
}
|
949
1415
|
};
|
950
1416
|
//# sourceMappingURL=Trade.js.map
|