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