adaptic-backend 1.0.340 → 1.0.341

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