@researchdatabox/redbox-core 0.0.1-beta.9700 → 0.0.1-beta.9873

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 (125) hide show
  1. package/dist/HarvestRunService.d.ts +49 -0
  2. package/dist/HarvestRunService.d.ts.map +1 -0
  3. package/dist/HarvestRunService.js +13 -0
  4. package/dist/api-routes/groups/harvest-runs.d.ts +5 -0
  5. package/dist/api-routes/groups/harvest-runs.d.ts.map +1 -0
  6. package/dist/api-routes/groups/harvest-runs.js +79 -0
  7. package/dist/api-routes/groups/named-query.d.ts +8 -0
  8. package/dist/api-routes/groups/named-query.d.ts.map +1 -0
  9. package/dist/api-routes/groups/named-query.js +54 -0
  10. package/dist/api-routes/groups/records.d.ts.map +1 -1
  11. package/dist/api-routes/groups/records.js +6 -2
  12. package/dist/api-routes/groups/reports.d.ts +6 -0
  13. package/dist/api-routes/groups/reports.d.ts.map +1 -1
  14. package/dist/api-routes/groups/reports.js +45 -2
  15. package/dist/api-routes/groups/users.js +3 -3
  16. package/dist/api-routes/index.d.ts +2 -0
  17. package/dist/api-routes/index.d.ts.map +1 -1
  18. package/dist/api-routes/index.js +3 -1
  19. package/dist/api-routes/openapi.d.ts +0 -1
  20. package/dist/api-routes/openapi.d.ts.map +1 -1
  21. package/dist/api-routes/openapi.js +27 -8
  22. package/dist/api-routes/route-registry.d.ts.map +1 -1
  23. package/dist/api-routes/route-registry.js +5 -1
  24. package/dist/api-routes/route-resolution.d.ts.map +1 -1
  25. package/dist/api-routes/route-resolution.js +15 -1
  26. package/dist/api-routes/schemas/common.d.ts +1 -2
  27. package/dist/api-routes/schemas/common.d.ts.map +1 -1
  28. package/dist/api-routes/schemas/common.js +10 -11
  29. package/dist/api-routes/schemas/responses.d.ts +6635 -1887
  30. package/dist/api-routes/schemas/responses.d.ts.map +1 -1
  31. package/dist/api-routes/schemas/responses.js +364 -269
  32. package/dist/api-routes/zod-openapi.d.ts +3 -0
  33. package/dist/api-routes/zod-openapi.d.ts.map +1 -0
  34. package/dist/api-routes/zod-openapi.js +8 -0
  35. package/dist/bootstrap.js +3 -3
  36. package/dist/config/auth.config.d.ts.map +1 -1
  37. package/dist/config/auth.config.js +8 -1
  38. package/dist/config/brandingConfigurationDefaults.config.d.ts.map +1 -1
  39. package/dist/config/brandingConfigurationDefaults.config.js +4 -2
  40. package/dist/config/harvestRuns.config.d.ts +9 -0
  41. package/dist/config/harvestRuns.config.d.ts.map +1 -0
  42. package/dist/config/harvestRuns.config.js +11 -0
  43. package/dist/config/index.d.ts +4 -3
  44. package/dist/config/index.d.ts.map +1 -1
  45. package/dist/config/index.js +4 -3
  46. package/dist/config/namedQuery.config.d.ts +16 -2
  47. package/dist/config/namedQuery.config.d.ts.map +1 -1
  48. package/dist/config/namedQuery.config.js +7 -350
  49. package/dist/config/report.config.d.ts +2 -11
  50. package/dist/config/report.config.d.ts.map +1 -1
  51. package/dist/config/report.config.js +3 -49
  52. package/dist/config/reusableContributorFormDefinitions.config.d.ts.map +1 -1
  53. package/dist/config/reusableContributorFormDefinitions.config.js +10 -4
  54. package/dist/config/routes.config.d.ts.map +1 -1
  55. package/dist/config/routes.config.js +15 -1
  56. package/dist/configmodels/AdminSidebarConfig.d.ts.map +1 -1
  57. package/dist/configmodels/AdminSidebarConfig.js +2 -1
  58. package/dist/controllers/AdminController.d.ts +1 -0
  59. package/dist/controllers/AdminController.d.ts.map +1 -1
  60. package/dist/controllers/AdminController.js +5 -1
  61. package/dist/controllers/NamedQueryController.d.ts +8 -0
  62. package/dist/controllers/NamedQueryController.d.ts.map +1 -0
  63. package/dist/controllers/NamedQueryController.js +17 -0
  64. package/dist/controllers/ReportController.d.ts +7 -0
  65. package/dist/controllers/ReportController.d.ts.map +1 -1
  66. package/dist/controllers/ReportController.js +75 -2
  67. package/dist/controllers/ReportsController.d.ts +1 -0
  68. package/dist/controllers/ReportsController.d.ts.map +1 -1
  69. package/dist/controllers/ReportsController.js +12 -2
  70. package/dist/controllers/index.d.ts.map +1 -1
  71. package/dist/controllers/index.js +10 -1
  72. package/dist/controllers/webservice/HarvestRunController.d.ts +13 -0
  73. package/dist/controllers/webservice/HarvestRunController.d.ts.map +1 -0
  74. package/dist/controllers/webservice/HarvestRunController.js +148 -0
  75. package/dist/controllers/webservice/NamedQueryController.d.ts +17 -0
  76. package/dist/controllers/webservice/NamedQueryController.d.ts.map +1 -0
  77. package/dist/controllers/webservice/NamedQueryController.js +127 -0
  78. package/dist/controllers/webservice/RecordController.d.ts.map +1 -1
  79. package/dist/controllers/webservice/RecordController.js +30 -74
  80. package/dist/controllers/webservice/ReportController.d.ts +7 -0
  81. package/dist/controllers/webservice/ReportController.d.ts.map +1 -1
  82. package/dist/controllers/webservice/ReportController.js +111 -3
  83. package/dist/form-config/dataRecord-1.0-draft.js +3 -3
  84. package/dist/form-config/default-1.0-draft.js +2 -2
  85. package/dist/index.d.ts +2 -0
  86. package/dist/index.d.ts.map +1 -1
  87. package/dist/index.js +2 -1
  88. package/dist/model/config/ReportConfig.d.ts +1 -1
  89. package/dist/model/config/ReportConfig.d.ts.map +1 -1
  90. package/dist/model/config/ReportConfig.js +2 -2
  91. package/dist/model/storage/HarvestRunModel.d.ts +140 -0
  92. package/dist/model/storage/HarvestRunModel.d.ts.map +1 -0
  93. package/dist/model/storage/HarvestRunModel.js +110 -0
  94. package/dist/model/storage/ReportModel.d.ts +1 -0
  95. package/dist/model/storage/ReportModel.d.ts.map +1 -1
  96. package/dist/model/storage/index.d.ts +1 -0
  97. package/dist/model/storage/index.d.ts.map +1 -1
  98. package/dist/model/storage/index.js +10 -2
  99. package/dist/services/HarvestRunService.d.ts +73 -0
  100. package/dist/services/HarvestRunService.d.ts.map +1 -0
  101. package/dist/services/HarvestRunService.js +1317 -0
  102. package/dist/services/NamedQueryService.d.ts +25 -4
  103. package/dist/services/NamedQueryService.d.ts.map +1 -1
  104. package/dist/services/NamedQueryService.js +444 -115
  105. package/dist/services/ReportsService.d.ts +57 -1
  106. package/dist/services/ReportsService.d.ts.map +1 -1
  107. package/dist/services/ReportsService.js +252 -34
  108. package/dist/services/index.d.ts +3 -0
  109. package/dist/services/index.d.ts.map +1 -1
  110. package/dist/services/index.js +7 -2
  111. package/dist/visitor/construct.visitor.d.ts.map +1 -1
  112. package/dist/visitor/construct.visitor.js +8 -3
  113. package/dist/waterline-models/HarvestRecordEvent.d.ts +43 -0
  114. package/dist/waterline-models/HarvestRecordEvent.d.ts.map +1 -0
  115. package/dist/waterline-models/HarvestRecordEvent.js +107 -0
  116. package/dist/waterline-models/HarvestRun.d.ts +51 -0
  117. package/dist/waterline-models/HarvestRun.d.ts.map +1 -0
  118. package/dist/waterline-models/HarvestRun.js +125 -0
  119. package/dist/waterline-models/HarvestRunChunk.d.ts +57 -0
  120. package/dist/waterline-models/HarvestRunChunk.d.ts.map +1 -0
  121. package/dist/waterline-models/HarvestRunChunk.js +140 -0
  122. package/dist/waterline-models/index.d.ts +6 -0
  123. package/dist/waterline-models/index.d.ts.map +1 -1
  124. package/dist/waterline-models/index.js +10 -1
  125. package/package.json +27 -27
@@ -0,0 +1,1317 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.Services = void 0;
37
+ const _ = __importStar(require("lodash"));
38
+ const node_crypto_1 = require("node:crypto");
39
+ const rxjs_1 = require("rxjs");
40
+ const CoreService_1 = require("../CoreService");
41
+ const HarvestRunService_1 = require("../HarvestRunService");
42
+ const APIHarvestResponse_1 = require("../model/APIHarvestResponse");
43
+ const HarvestRunModel_1 = require("../model/storage/HarvestRunModel");
44
+ require("../waterline-models/types");
45
+ var Services;
46
+ (function (Services) {
47
+ class HarvestRunService extends CoreService_1.Services.Core.Service {
48
+ _exportedMethods = [
49
+ 'submitCompatibilityRecords',
50
+ 'submitLegacyRecords',
51
+ 'submitChunk',
52
+ 'listRuns',
53
+ 'getRun',
54
+ 'runExists',
55
+ 'listRunEvents',
56
+ ];
57
+ constructor() {
58
+ super();
59
+ this.logHeader = 'HarvestRunService::';
60
+ }
61
+ asError(error) {
62
+ return error instanceof Error ? error : new Error(String(error));
63
+ }
64
+ resolveBrandId(brand) {
65
+ if (typeof brand === 'string') {
66
+ return brand.trim();
67
+ }
68
+ return String(brand?.id ?? brand?.name ?? '').trim();
69
+ }
70
+ resolveRecordTypeName(recordTypeModel) {
71
+ return String(recordTypeModel?.name ?? '').trim();
72
+ }
73
+ nowIso() {
74
+ return new Date().toISOString();
75
+ }
76
+ parsePositiveInt(value, fallback) {
77
+ const parsed = Number.parseInt(String(value ?? ''), 10);
78
+ return Number.isInteger(parsed) && parsed > 0 ? parsed : fallback;
79
+ }
80
+ harvestRunConfig() {
81
+ const configured = (_.isPlainObject(sails.config?.harvestRuns) ? sails.config.harvestRuns : {});
82
+ return {
83
+ maxRecordsPerChunk: this.parsePositiveInt(configured.maxRecordsPerChunk, 250),
84
+ maxChunkBytes: this.parsePositiveInt(configured.maxChunkBytes, 5_000_000),
85
+ processingChunkTimeoutMinutes: this.parsePositiveInt(configured.processingChunkTimeoutMinutes, 30),
86
+ eventCreateBatchSize: this.parsePositiveInt(configured.eventCreateBatchSize, 250),
87
+ failedSnapshotMaxBytes: this.parsePositiveInt(configured.failedSnapshotMaxBytes, 32 * 1024),
88
+ };
89
+ }
90
+ isProcessingChunkStale(chunk) {
91
+ const submittedAt = new Date(String(chunk.submittedAt ?? '')).getTime();
92
+ if (Number.isNaN(submittedAt)) {
93
+ return false;
94
+ }
95
+ return Date.now() - submittedAt > this.harvestRunConfig().processingChunkTimeoutMinutes * 60 * 1000;
96
+ }
97
+ normalizeTrackedOperation(value) {
98
+ switch (String(value ?? HarvestRunModel_1.HarvestOperation.upsert).trim()) {
99
+ case HarvestRunModel_1.HarvestOperation.create:
100
+ return HarvestRunModel_1.HarvestOperation.create;
101
+ case HarvestRunModel_1.HarvestOperation.update:
102
+ return HarvestRunModel_1.HarvestOperation.update;
103
+ case HarvestRunModel_1.HarvestOperation.upsert:
104
+ return HarvestRunModel_1.HarvestOperation.upsert;
105
+ case HarvestRunModel_1.HarvestOperation.delete:
106
+ return HarvestRunModel_1.HarvestOperation.delete;
107
+ default:
108
+ return 'invalid';
109
+ }
110
+ }
111
+ normalizeTrackedUpdateStrategy(value) {
112
+ switch (String(value ?? 'replace').trim()) {
113
+ case 'merge':
114
+ return 'merge';
115
+ case 'ignoreIfExists':
116
+ return 'ignoreIfExists';
117
+ default:
118
+ return 'replace';
119
+ }
120
+ }
121
+ buildEmptyCounters() {
122
+ return {
123
+ totalProcessed: 0,
124
+ created: 0,
125
+ updated: 0,
126
+ deleted: 0,
127
+ unchanged: 0,
128
+ failed: 0,
129
+ };
130
+ }
131
+ incrementCounters(counters, outcome) {
132
+ counters.totalProcessed += 1;
133
+ switch (outcome) {
134
+ case HarvestRunModel_1.HarvestOutcome.created:
135
+ counters.created += 1;
136
+ break;
137
+ case HarvestRunModel_1.HarvestOutcome.updated:
138
+ counters.updated += 1;
139
+ break;
140
+ case HarvestRunModel_1.HarvestOutcome.deleted:
141
+ counters.deleted += 1;
142
+ break;
143
+ case HarvestRunModel_1.HarvestOutcome.unchanged:
144
+ counters.unchanged += 1;
145
+ break;
146
+ case HarvestRunModel_1.HarvestOutcome.failed:
147
+ default:
148
+ counters.failed += 1;
149
+ break;
150
+ }
151
+ }
152
+ normalizeMetadata(recordRequest) {
153
+ const metadata = _.get(recordRequest, 'metadata');
154
+ if (_.isPlainObject(metadata)) {
155
+ return metadata;
156
+ }
157
+ return (_.isPlainObject(recordRequest) ? recordRequest : {});
158
+ }
159
+ isMetadataEqual(meta1, meta2) {
160
+ return _.isEqual(meta1, meta2);
161
+ }
162
+ async updateRunWithOptimisticRetry(run, criteriaFields, buildUpdates) {
163
+ const runId = String(run.id ?? '').trim();
164
+ if (_.isEmpty(runId)) {
165
+ throw new Error('Harvest run identifier is required to persist counters.');
166
+ }
167
+ let currentRun = run;
168
+ for (let attempt = 0; attempt < 5; attempt += 1) {
169
+ const criteria = { id: runId };
170
+ for (const field of criteriaFields) {
171
+ if (!_.isUndefined(currentRun[field])) {
172
+ criteria[field] = currentRun[field];
173
+ }
174
+ }
175
+ const updates = buildUpdates(currentRun);
176
+ const updated = await HarvestRun.updateOne(criteria).set(updates);
177
+ if (updated) {
178
+ return updated;
179
+ }
180
+ const reloaded = await HarvestRun.findOne({ id: runId });
181
+ if (!reloaded) {
182
+ return { ...currentRun, ...updates };
183
+ }
184
+ if (_.isMatch(reloaded, updates)) {
185
+ return reloaded;
186
+ }
187
+ currentRun = reloaded;
188
+ }
189
+ throw new Error(`Harvest run ${runId} was modified concurrently and could not be updated safely.`);
190
+ }
191
+ getHarvestRunCollection() {
192
+ const datastore = typeof HarvestRun.getDatastore === 'function'
193
+ ? HarvestRun.getDatastore()
194
+ : null;
195
+ if (!datastore?.manager || typeof datastore.manager.collection !== 'function') {
196
+ return null;
197
+ }
198
+ return datastore.manager.collection('harvestrun');
199
+ }
200
+ toNativeRunId(runId, collection) {
201
+ if (!runId || _.isEmpty(runId)) {
202
+ return null;
203
+ }
204
+ const createPk = collection?.s?.pkFactory?.createPk;
205
+ if (typeof createPk !== 'function') {
206
+ return null;
207
+ }
208
+ const sampleId = createPk();
209
+ if (!sampleId || typeof sampleId !== 'object') {
210
+ return null;
211
+ }
212
+ const ObjectIdConstructor = sampleId.constructor;
213
+ if (!ObjectIdConstructor || typeof ObjectIdConstructor !== 'function') {
214
+ return null;
215
+ }
216
+ if (typeof ObjectIdConstructor.isValid === 'function' && !ObjectIdConstructor.isValid(runId)) {
217
+ return null;
218
+ }
219
+ try {
220
+ const nativeRunId = new ObjectIdConstructor(runId);
221
+ return typeof nativeRunId.toHexString === 'function' ? nativeRunId : null;
222
+ }
223
+ catch {
224
+ return null;
225
+ }
226
+ }
227
+ extractUpdatedRun(result) {
228
+ if (_.isNil(result)) {
229
+ return null;
230
+ }
231
+ const normalizeRow = (row) => {
232
+ if (_.isNil(row)) {
233
+ return null;
234
+ }
235
+ const rawId = row._id;
236
+ if (_.isNil(row.id) && !_.isNil(rawId)) {
237
+ return {
238
+ ...row,
239
+ id: String(rawId),
240
+ };
241
+ }
242
+ return row;
243
+ };
244
+ if (_.isPlainObject(result) && 'value' in result) {
245
+ return normalizeRow(result.value);
246
+ }
247
+ return normalizeRow(result);
248
+ }
249
+ buildAtomicRunCounterUpdate(counters, completedAt, finalChunk) {
250
+ const failedExpression = {
251
+ $add: [{ $ifNull: ['$failed', 0] }, counters.failed],
252
+ };
253
+ const updateStage = {
254
+ lastChunkAt: completedAt,
255
+ totalProcessed: { $add: [{ $ifNull: ['$totalProcessed', 0] }, counters.totalProcessed] },
256
+ created: { $add: [{ $ifNull: ['$created', 0] }, counters.created] },
257
+ updated: { $add: [{ $ifNull: ['$updated', 0] }, counters.updated] },
258
+ deleted: { $add: [{ $ifNull: ['$deleted', 0] }, counters.deleted] },
259
+ unchanged: { $add: [{ $ifNull: ['$unchanged', 0] }, counters.unchanged] },
260
+ failed: failedExpression,
261
+ chunksProcessed: { $add: [{ $ifNull: ['$chunksProcessed', 0] }, 1] },
262
+ };
263
+ if (finalChunk) {
264
+ updateStage.status = {
265
+ $cond: [
266
+ { $gt: [failedExpression, 0] },
267
+ HarvestRunModel_1.HarvestRunStatus.completedWithErrors,
268
+ HarvestRunModel_1.HarvestRunStatus.completed,
269
+ ],
270
+ };
271
+ updateStage.completedAt = completedAt;
272
+ }
273
+ else if (counters.failed > 0) {
274
+ updateStage.status = {
275
+ $cond: [
276
+ { $eq: ['$status', HarvestRunModel_1.HarvestRunStatus.completed] },
277
+ HarvestRunModel_1.HarvestRunStatus.completedWithErrors,
278
+ '$status',
279
+ ],
280
+ };
281
+ }
282
+ return [{ $set: updateStage }];
283
+ }
284
+ toRunModel(row) {
285
+ return new HarvestRunModel_1.HarvestRunModel({
286
+ id: row.id,
287
+ sourceRunId: String(row.sourceRunId ?? ''),
288
+ brandId: String(row.brandId ?? ''),
289
+ recordType: String(row.recordType ?? ''),
290
+ sourceName: String(row.sourceName ?? ''),
291
+ sourceUri: row.sourceUri ? String(row.sourceUri) : undefined,
292
+ status: row.status ?? HarvestRunModel_1.HarvestRunStatus.running,
293
+ startedAt: String(row.startedAt ?? ''),
294
+ completedAt: row.completedAt ? String(row.completedAt) : undefined,
295
+ startedBy: row.startedBy ? String(row.startedBy) : undefined,
296
+ lastChunkAt: row.lastChunkAt ? String(row.lastChunkAt) : undefined,
297
+ totalProcessed: Number(row.totalProcessed ?? 0),
298
+ created: Number(row.created ?? 0),
299
+ updated: Number(row.updated ?? 0),
300
+ deleted: Number(row.deleted ?? 0),
301
+ unchanged: Number(row.unchanged ?? 0),
302
+ failed: Number(row.failed ?? 0),
303
+ chunksProcessed: Number(row.chunksProcessed ?? 0),
304
+ duplicateChunks: Number(row.duplicateChunks ?? 0),
305
+ metadata: row.metadata ?? undefined,
306
+ });
307
+ }
308
+ toChunkModel(row, duplicateOverride) {
309
+ return new HarvestRunModel_1.HarvestRunChunkModel({
310
+ id: row.id,
311
+ runId: String(row.runId ?? ''),
312
+ brandId: String(row.brandId ?? ''),
313
+ recordType: String(row.recordType ?? ''),
314
+ sourceRunId: String(row.sourceRunId ?? ''),
315
+ contentHash: String(row.contentHash ?? ''),
316
+ attempt: Number(row.attempt ?? 1),
317
+ chunkIndex: row.chunkIndex == null ? undefined : Number(row.chunkIndex),
318
+ chunkLabel: row.chunkLabel ? String(row.chunkLabel) : undefined,
319
+ totalExpected: row.totalExpected == null ? undefined : Number(row.totalExpected),
320
+ status: row.status ?? HarvestRunModel_1.HarvestChunkStatus.processed,
321
+ recordCount: Number(row.recordCount ?? 0),
322
+ totalProcessed: Number(row.totalProcessed ?? 0),
323
+ created: Number(row.created ?? 0),
324
+ updated: Number(row.updated ?? 0),
325
+ deleted: Number(row.deleted ?? 0),
326
+ unchanged: Number(row.unchanged ?? 0),
327
+ failed: Number(row.failed ?? 0),
328
+ duplicate: duplicateOverride ?? Boolean(row.duplicate),
329
+ submittedAt: String(row.submittedAt ?? ''),
330
+ completedAt: row.completedAt ? String(row.completedAt) : undefined,
331
+ errorMessage: row.errorMessage ? String(row.errorMessage) : undefined,
332
+ responseSummary: row.responseSummary ?? undefined,
333
+ });
334
+ }
335
+ toEventModel(row) {
336
+ const outcome = row.outcome ?? HarvestRunModel_1.HarvestOutcome.failed;
337
+ return new HarvestRunModel_1.HarvestRecordEventModel({
338
+ id: row.id,
339
+ runId: String(row.runId ?? ''),
340
+ chunkId: String(row.chunkId ?? ''),
341
+ brandId: String(row.brandId ?? ''),
342
+ recordType: String(row.recordType ?? ''),
343
+ sourceRunId: String(row.sourceRunId ?? ''),
344
+ harvestId: String(row.harvestId ?? ''),
345
+ oid: row.oid ? String(row.oid) : undefined,
346
+ operation: row.operation ?? HarvestRunModel_1.HarvestOperation.upsert,
347
+ outcome,
348
+ status: row.status == null ? outcome !== HarvestRunModel_1.HarvestOutcome.failed : Boolean(row.status),
349
+ message: row.message ? String(row.message) : undefined,
350
+ details: row.details ? String(row.details) : undefined,
351
+ errorCode: row.errorCode ? String(row.errorCode) : undefined,
352
+ recordSnapshot: row.recordSnapshot ?? undefined,
353
+ createdAt: String(row.createdAt ?? ''),
354
+ });
355
+ }
356
+ async findExistingHarvestRecord(harvestId, recordType) {
357
+ return await Record.find({
358
+ harvestId,
359
+ 'metaMetadata.type': recordType,
360
+ }).meta({
361
+ enableExperimentalDeepTargets: true,
362
+ });
363
+ }
364
+ async findExistingTrackedHarvestRecordsBatch(brandId, harvestIds, recordType) {
365
+ const uniqueHarvestIds = _.uniq(harvestIds.filter(harvestId => !_.isEmpty(harvestId)));
366
+ if (uniqueHarvestIds.length === 0) {
367
+ return new Map();
368
+ }
369
+ const rows = await Record.find({
370
+ harvestId: { in: uniqueHarvestIds },
371
+ 'metaMetadata.type': recordType,
372
+ 'metaMetadata.brandId': brandId,
373
+ }).meta({
374
+ enableExperimentalDeepTargets: true,
375
+ });
376
+ const byHarvestId = new Map();
377
+ for (const row of rows) {
378
+ const harvestId = String(row.harvestId ?? '').trim();
379
+ if (_.isEmpty(harvestId)) {
380
+ continue;
381
+ }
382
+ const matches = byHarvestId.get(harvestId) ?? [];
383
+ matches.push(row);
384
+ byHarvestId.set(harvestId, matches);
385
+ }
386
+ return byHarvestId;
387
+ }
388
+ async legacyUpdateHarvestRecord(brand, recordTypeModel, updateMode, body, oid, harvestId, user) {
389
+ const shouldMerge = updateMode === 'merge';
390
+ try {
391
+ const record = await RecordsService.getMeta(oid);
392
+ if (_.isEmpty(record)) {
393
+ return new APIHarvestResponse_1.APIHarvestResponse(harvestId, oid, false, `Failed to update meta, cannot find existing record with oid: ${oid}`);
394
+ }
395
+ if (shouldMerge) {
396
+ record['metadata'] = _.mergeWith(record.metadata, body, (objValue, srcValue) => {
397
+ if (_.isArray(objValue)) {
398
+ return objValue.concat(srcValue);
399
+ }
400
+ return undefined;
401
+ });
402
+ }
403
+ else {
404
+ record['metadata'] = body;
405
+ }
406
+ const sourceMetadata = body?.['sourceMetadata'];
407
+ if (!_.isEmpty(sourceMetadata)) {
408
+ record['metaMetadata']['sourceMetadata'] = `${sourceMetadata}`;
409
+ }
410
+ await RecordsService.updateMeta(brand, oid, record, user);
411
+ return new APIHarvestResponse_1.APIHarvestResponse(harvestId, oid, true, shouldMerge ? 'Record merged successfully' : 'Record updated successfully');
412
+ }
413
+ catch (error) {
414
+ const result = new APIHarvestResponse_1.APIHarvestResponse(harvestId, oid, false, error instanceof Error ? error.message : 'Failed to update meta');
415
+ this.logger.error(`${this.logHeader} Failed to update harvest record ${oid}`, error);
416
+ return result;
417
+ }
418
+ }
419
+ async legacyCreateHarvestRecord(brand, recordTypeModel, body, harvestId, updateMode, user) {
420
+ const metadata = body?.['metadata'];
421
+ const workflowStage = body?.['workflowStage'];
422
+ const request = {};
423
+ if (updateMode !== 'create') {
424
+ request['harvestId'] = harvestId;
425
+ }
426
+ request['metadata'] = metadata == null ? body : metadata;
427
+ try {
428
+ const response = await RecordsService.create(brand, request, recordTypeModel, user);
429
+ if (workflowStage) {
430
+ try {
431
+ const wfStep = await (0, rxjs_1.firstValueFrom)(WorkflowStepsService.get(recordTypeModel, String(workflowStage)));
432
+ RecordsService.setWorkflowStepRelatedMetadata(request, wfStep);
433
+ }
434
+ catch (error) {
435
+ this.logger.warn(`${this.logHeader} Failed to resolve workflow step ${String(workflowStage)}`, error);
436
+ }
437
+ }
438
+ if (response.isSuccessful()) {
439
+ return new APIHarvestResponse_1.APIHarvestResponse(harvestId, response.oid, true, 'Record created successfully');
440
+ }
441
+ this.logger.error(`${this.logHeader} Record creation failed for harvestId ${harvestId}`);
442
+ return new APIHarvestResponse_1.APIHarvestResponse(harvestId, '', false, 'Record creation failed');
443
+ }
444
+ catch (error) {
445
+ this.logger.error(`${this.logHeader} Exception creating harvest record ${harvestId}`, error);
446
+ return new APIHarvestResponse_1.APIHarvestResponse(harvestId, '', false, String(error));
447
+ }
448
+ }
449
+ buildTrackedFailureResponse(harvestId, operation, message, details = '', oid = '') {
450
+ return {
451
+ harvestId,
452
+ oid,
453
+ operation: String(operation),
454
+ outcome: HarvestRunModel_1.HarvestOutcome.failed,
455
+ status: false,
456
+ message,
457
+ details,
458
+ };
459
+ }
460
+ async createTrackedRecord(brand, recordTypeModel, recordRequest, harvestId, user) {
461
+ const request = {
462
+ harvestId,
463
+ metadata: this.normalizeMetadata(recordRequest),
464
+ };
465
+ try {
466
+ const response = await RecordsService.create(brand, request, recordTypeModel, user);
467
+ if (response.isSuccessful()) {
468
+ return {
469
+ harvestId,
470
+ oid: String(response.oid ?? ''),
471
+ operation: HarvestRunModel_1.HarvestOperation.create,
472
+ outcome: HarvestRunModel_1.HarvestOutcome.created,
473
+ status: true,
474
+ message: 'Record created successfully',
475
+ details: '',
476
+ };
477
+ }
478
+ return this.buildTrackedFailureResponse(harvestId, HarvestRunModel_1.HarvestOperation.create, String(response.message ?? 'Record creation failed'), typeof response.details === 'string' ? response.details : '');
479
+ }
480
+ catch (error) {
481
+ return this.buildTrackedFailureResponse(harvestId, HarvestRunModel_1.HarvestOperation.create, this.asError(error).message);
482
+ }
483
+ }
484
+ async updateTrackedRecord(brand, recordTypeModel, metadata, oid, user, strategy) {
485
+ const shouldMerge = strategy === 'merge';
486
+ try {
487
+ const record = await RecordsService.getMeta(oid);
488
+ if (_.isEmpty(record)) {
489
+ return {
490
+ success: false,
491
+ message: `Failed to update meta, cannot find existing record with oid: ${oid}`,
492
+ details: '',
493
+ };
494
+ }
495
+ const previousRecord = _.cloneDeep(record);
496
+ if (shouldMerge) {
497
+ record['metadata'] = _.mergeWith(record.metadata, metadata, (objValue, srcValue) => {
498
+ if (_.isArray(objValue)) {
499
+ return objValue.concat(srcValue);
500
+ }
501
+ return undefined;
502
+ });
503
+ }
504
+ else {
505
+ record['metadata'] = metadata;
506
+ }
507
+ const sourceMetadata = metadata['sourceMetadata'];
508
+ if (!_.isEmpty(sourceMetadata)) {
509
+ record['metaMetadata']['sourceMetadata'] = `${sourceMetadata}`;
510
+ }
511
+ const response = await RecordsService.updateMeta(brand, oid, record, user);
512
+ if (!response.isSuccessful()) {
513
+ return {
514
+ success: false,
515
+ message: String(response.message ?? 'Failed to update meta'),
516
+ details: typeof response.details === 'string' ? response.details : '',
517
+ };
518
+ }
519
+ return {
520
+ success: true,
521
+ message: shouldMerge ? 'Record merged successfully' : 'Record updated successfully',
522
+ details: '',
523
+ previousRecord,
524
+ };
525
+ }
526
+ catch (error) {
527
+ return {
528
+ success: false,
529
+ message: this.asError(error).message,
530
+ details: '',
531
+ };
532
+ }
533
+ }
534
+ async rollbackCreatedTrackedRecord(oid, recordTypeModel, user) {
535
+ const currentRecord = await RecordsService.getMeta(oid);
536
+ const response = await RecordsService.delete(oid, false, currentRecord, recordTypeModel, user);
537
+ if (!response.isSuccessful()) {
538
+ throw new Error(String(response.message ?? `Failed to rollback created record ${oid}.`));
539
+ }
540
+ }
541
+ async rollbackUpdatedTrackedRecord(brand, oid, previousRecord, user) {
542
+ const response = await RecordsService.updateMeta(brand, oid, _.cloneDeep(previousRecord), user);
543
+ if (!response.isSuccessful()) {
544
+ throw new Error(String(response.message ?? `Failed to rollback updated record ${oid}.`));
545
+ }
546
+ }
547
+ async rollbackDeletedTrackedRecord(oid, user) {
548
+ const response = await RecordsService.restoreRecord(oid, user);
549
+ if (!response.isSuccessful()) {
550
+ throw new Error(String(response.message ?? `Failed to rollback deleted record ${oid}.`));
551
+ }
552
+ }
553
+ captureRecordSnapshot(record) {
554
+ const snapshot = {
555
+ harvestId: String(record.harvestId ?? ''),
556
+ operation: String(record.operation ?? HarvestRunModel_1.HarvestOperation.upsert),
557
+ updateStrategy: String(record.updateStrategy ?? 'replace'),
558
+ reason: record.reason,
559
+ recordRequest: _.isPlainObject(record.recordRequest) ? record.recordRequest : undefined,
560
+ };
561
+ const serialized = JSON.stringify(snapshot);
562
+ const maxBytes = this.harvestRunConfig().failedSnapshotMaxBytes;
563
+ if (Buffer.byteLength(serialized, 'utf8') <= maxBytes) {
564
+ return snapshot;
565
+ }
566
+ return {
567
+ truncated: true,
568
+ sizeBytes: Buffer.byteLength(serialized, 'utf8'),
569
+ preview: serialized.slice(0, maxBytes),
570
+ };
571
+ }
572
+ buildTrackedEvent(run, chunk, recordTypeName, request, response, errorCode) {
573
+ return {
574
+ runId: String(run.id ?? ''),
575
+ chunkId: String(chunk.id ?? ''),
576
+ brandId: String(run.brandId ?? ''),
577
+ recordType: recordTypeName,
578
+ sourceRunId: String(run.sourceRunId ?? ''),
579
+ harvestId: response.harvestId,
580
+ oid: response.oid || undefined,
581
+ operation: response.operation,
582
+ outcome: response.outcome,
583
+ status: response.status,
584
+ message: response.message || undefined,
585
+ details: response.details || undefined,
586
+ errorCode,
587
+ recordSnapshot: response.status ? undefined : this.captureRecordSnapshot(request),
588
+ createdAt: this.nowIso(),
589
+ };
590
+ }
591
+ bufferTrackedEvent(context, run, chunk, recordTypeName, request, response, errorCode) {
592
+ context.events.push(this.buildTrackedEvent(run, chunk, recordTypeName, request, response, errorCode));
593
+ }
594
+ async persistTrackedEvents(events) {
595
+ if (events.length === 0) {
596
+ return;
597
+ }
598
+ const batchSize = this.harvestRunConfig().eventCreateBatchSize;
599
+ for (let index = 0; index < events.length; index += batchSize) {
600
+ await HarvestRecordEvent.createEach(events.slice(index, index + batchSize));
601
+ }
602
+ }
603
+ buildCountersFromTrackedEvents(events) {
604
+ const counters = this.buildEmptyCounters();
605
+ for (const event of events) {
606
+ this.incrementCounters(counters, (event.outcome ?? HarvestRunModel_1.HarvestOutcome.failed));
607
+ }
608
+ return counters;
609
+ }
610
+ async listCheckpointedChunkEvents(runId, brandId, chunkIds) {
611
+ const resolvedChunkIds = _.uniq(chunkIds.filter(chunkId => !_.isEmpty(chunkId)));
612
+ if (_.isEmpty(runId) || resolvedChunkIds.length === 0) {
613
+ return [];
614
+ }
615
+ return await HarvestRecordEvent.find({
616
+ runId,
617
+ brandId,
618
+ chunkId: { in: resolvedChunkIds },
619
+ }).sort('createdAt ASC');
620
+ }
621
+ async checkpointChunkProgress(chunkId, recordCount, counters) {
622
+ if (_.isEmpty(chunkId)) {
623
+ return;
624
+ }
625
+ await HarvestRunChunk.updateOne({ id: chunkId }).set({
626
+ recordCount,
627
+ totalProcessed: counters.totalProcessed,
628
+ created: counters.created,
629
+ updated: counters.updated,
630
+ deleted: counters.deleted,
631
+ unchanged: counters.unchanged,
632
+ failed: counters.failed,
633
+ responseSummary: this.buildChunkResponseSummary(counters),
634
+ });
635
+ }
636
+ canonicalizeValue(value, seen = new WeakSet()) {
637
+ if (value === undefined) {
638
+ return undefined;
639
+ }
640
+ if (value === null || typeof value === 'boolean') {
641
+ return value;
642
+ }
643
+ if (typeof value === 'string') {
644
+ return value.normalize('NFC');
645
+ }
646
+ if (typeof value === 'number') {
647
+ if (!Number.isFinite(value)) {
648
+ throw new HarvestRunService_1.HarvestRunServiceError('Tracked harvest payload contains an invalid number value.', 400);
649
+ }
650
+ return Object.is(value, -0) ? 0 : value;
651
+ }
652
+ if (typeof value === 'bigint' || typeof value === 'function' || typeof value === 'symbol') {
653
+ throw new HarvestRunService_1.HarvestRunServiceError('Tracked harvest payload contains a non-serializable value.', 400);
654
+ }
655
+ if (Array.isArray(value)) {
656
+ return value.map(entry => this.canonicalizeValue(entry, seen));
657
+ }
658
+ if (value instanceof Date) {
659
+ return value.toISOString();
660
+ }
661
+ if (typeof value === 'object') {
662
+ if (seen.has(value)) {
663
+ throw new HarvestRunService_1.HarvestRunServiceError('Tracked harvest payload contains circular data.', 400);
664
+ }
665
+ seen.add(value);
666
+ const result = Object.keys(value)
667
+ .sort((left, right) => left.localeCompare(right))
668
+ .reduce((acc, key) => {
669
+ const normalized = this.canonicalizeValue(value[key], seen);
670
+ if (normalized !== undefined) {
671
+ acc[key] = normalized;
672
+ }
673
+ return acc;
674
+ }, {});
675
+ seen.delete(value);
676
+ return result;
677
+ }
678
+ return value;
679
+ }
680
+ buildChunkContentHash(brandId, recordTypeName, request) {
681
+ const payload = {
682
+ algorithm: 'redbox-harvest-chunk-v1',
683
+ brandId,
684
+ recordType: recordTypeName,
685
+ sourceName: request.sourceName,
686
+ sourceRunId: request.sourceRunId,
687
+ chunkIndex: request.chunk?.index,
688
+ records: this.canonicalizeValue(request.records),
689
+ };
690
+ return (0, node_crypto_1.createHash)('sha256').update(JSON.stringify(payload)).digest('hex');
691
+ }
692
+ validateTrackedChunkRequest(body) {
693
+ const request = (_.isPlainObject(body) ? body : {});
694
+ let serializedRequest;
695
+ try {
696
+ serializedRequest = JSON.stringify(request);
697
+ }
698
+ catch {
699
+ throw new HarvestRunService_1.HarvestRunServiceError('Tracked harvest payload contains non-serializable data.', 400);
700
+ }
701
+ if (Buffer.byteLength(serializedRequest, 'utf8') > this.harvestRunConfig().maxChunkBytes) {
702
+ throw new HarvestRunService_1.HarvestRunServiceError('Tracked harvest request exceeds the configured maximum payload size.', 413);
703
+ }
704
+ const sourceRunId = String(request.sourceRunId ?? '').trim();
705
+ const sourceName = String(request.sourceName ?? '').trim();
706
+ const records = Array.isArray(request.records) ? request.records : [];
707
+ const chunk = (_.isPlainObject(request.chunk) ? request.chunk : {});
708
+ const chunkIndex = chunk.index;
709
+ if (!sourceRunId || !sourceName || records.length === 0 || !Number.isInteger(chunkIndex) || Number(chunkIndex) < 0) {
710
+ throw new HarvestRunService_1.HarvestRunServiceError('Invalid tracked harvest request body.', 400);
711
+ }
712
+ if (records.length > this.harvestRunConfig().maxRecordsPerChunk) {
713
+ throw new HarvestRunService_1.HarvestRunServiceError('Tracked harvest request exceeds the configured maximum records per chunk.', 413);
714
+ }
715
+ return {
716
+ sourceRunId,
717
+ sourceName,
718
+ sourceUri: request.sourceUri ? String(request.sourceUri) : undefined,
719
+ finalChunk: Boolean(request.finalChunk),
720
+ chunk: {
721
+ index: Number(chunkIndex),
722
+ label: chunk.label ? String(chunk.label) : undefined,
723
+ totalExpected: chunk.totalExpected == null ? undefined : Number(chunk.totalExpected),
724
+ },
725
+ records,
726
+ };
727
+ }
728
+ async findOrCreateRun(brand, recordTypeModel, request, user) {
729
+ const brandId = this.resolveBrandId(brand);
730
+ const recordTypeName = this.resolveRecordTypeName(recordTypeModel);
731
+ const where = {
732
+ brandId,
733
+ recordType: recordTypeName,
734
+ sourceName: request.sourceName,
735
+ sourceRunId: request.sourceRunId,
736
+ };
737
+ const existing = await HarvestRun.findOne(where);
738
+ if (existing) {
739
+ return existing;
740
+ }
741
+ const now = this.nowIso();
742
+ try {
743
+ return await HarvestRun.create({
744
+ ...where,
745
+ sourceUri: request.sourceUri,
746
+ status: HarvestRunModel_1.HarvestRunStatus.running,
747
+ startedAt: now,
748
+ lastChunkAt: now,
749
+ startedBy: String(user?.username ?? ''),
750
+ totalProcessed: 0,
751
+ created: 0,
752
+ updated: 0,
753
+ deleted: 0,
754
+ unchanged: 0,
755
+ failed: 0,
756
+ chunksProcessed: 0,
757
+ duplicateChunks: 0,
758
+ }).fetch();
759
+ }
760
+ catch (error) {
761
+ const recovered = await HarvestRun.findOne(where);
762
+ if (recovered) {
763
+ return recovered;
764
+ }
765
+ throw error;
766
+ }
767
+ }
768
+ async updateRunAfterChunk(run, counters, finalChunk, completedAt) {
769
+ const collection = this.getHarvestRunCollection();
770
+ const nativeRunId = this.toNativeRunId(run.id, collection);
771
+ if (collection && nativeRunId) {
772
+ const updated = this.extractUpdatedRun(await collection.findOneAndUpdate({ _id: nativeRunId }, this.buildAtomicRunCounterUpdate(counters, completedAt, finalChunk), { returnDocument: 'after' }));
773
+ if (updated) {
774
+ return updated;
775
+ }
776
+ }
777
+ return await this.updateRunWithOptimisticRetry(run, ['totalProcessed', 'created', 'updated', 'deleted', 'unchanged', 'failed', 'chunksProcessed', 'status'], currentRun => {
778
+ const nextFailed = Number(currentRun.failed ?? 0) + counters.failed;
779
+ const updates = {
780
+ lastChunkAt: completedAt,
781
+ totalProcessed: Number(currentRun.totalProcessed ?? 0) + counters.totalProcessed,
782
+ created: Number(currentRun.created ?? 0) + counters.created,
783
+ updated: Number(currentRun.updated ?? 0) + counters.updated,
784
+ deleted: Number(currentRun.deleted ?? 0) + counters.deleted,
785
+ unchanged: Number(currentRun.unchanged ?? 0) + counters.unchanged,
786
+ failed: nextFailed,
787
+ chunksProcessed: Number(currentRun.chunksProcessed ?? 0) + 1,
788
+ };
789
+ if (finalChunk) {
790
+ updates.status = nextFailed > 0 ? HarvestRunModel_1.HarvestRunStatus.completedWithErrors : HarvestRunModel_1.HarvestRunStatus.completed;
791
+ updates.completedAt = completedAt;
792
+ }
793
+ else if (counters.failed > 0 && currentRun.status === HarvestRunModel_1.HarvestRunStatus.completed) {
794
+ updates.status = HarvestRunModel_1.HarvestRunStatus.completedWithErrors;
795
+ }
796
+ return updates;
797
+ });
798
+ }
799
+ async bumpDuplicateChunkCount(run) {
800
+ const collection = this.getHarvestRunCollection();
801
+ const nativeRunId = this.toNativeRunId(run.id, collection);
802
+ if (collection && nativeRunId) {
803
+ const updated = this.extractUpdatedRun(await collection.findOneAndUpdate({ _id: nativeRunId }, [{
804
+ $set: {
805
+ duplicateChunks: { $add: [{ $ifNull: ['$duplicateChunks', 0] }, 1] },
806
+ lastChunkAt: this.nowIso(),
807
+ },
808
+ }], { returnDocument: 'after' }));
809
+ if (updated) {
810
+ return updated;
811
+ }
812
+ }
813
+ const updatedAt = this.nowIso();
814
+ return await this.updateRunWithOptimisticRetry(run, ['duplicateChunks'], currentRun => ({
815
+ duplicateChunks: Number(currentRun.duplicateChunks ?? 0) + 1,
816
+ lastChunkAt: updatedAt,
817
+ }));
818
+ }
819
+ async processTrackedRecord(brand, recordTypeModel, run, chunk, request, user, context) {
820
+ const recordTypeName = String(run.recordType ?? '');
821
+ const operation = this.normalizeTrackedOperation(request.operation);
822
+ const harvestId = String(request.harvestId ?? '').trim();
823
+ if (!harvestId) {
824
+ const response = this.buildTrackedFailureResponse('', HarvestRunModel_1.HarvestOperation.upsert, 'HarvestId was not specified');
825
+ this.bufferTrackedEvent(context, run, chunk, recordTypeName, request, response, 'missing-harvest-id');
826
+ return { response };
827
+ }
828
+ if (operation === 'invalid') {
829
+ const response = this.buildTrackedFailureResponse(harvestId, String(request.operation ?? ''), 'Invalid record operation supplied.');
830
+ this.bufferTrackedEvent(context, run, chunk, recordTypeName, request, response, 'invalid-operation');
831
+ return { response };
832
+ }
833
+ if (context.duplicateHarvestIds.has(harvestId)) {
834
+ const response = this.buildTrackedFailureResponse(harvestId, operation, `HarvestId ${harvestId} appears more than once in this chunk.`);
835
+ this.bufferTrackedEvent(context, run, chunk, recordTypeName, request, response, 'duplicate-harvest-id-in-chunk');
836
+ return { response };
837
+ }
838
+ const existingRecords = context.existingByHarvestId.get(harvestId) ?? [];
839
+ if (existingRecords.length > 1) {
840
+ const response = this.buildTrackedFailureResponse(harvestId, operation, `Multiple records were found for harvestId ${harvestId}.`);
841
+ this.bufferTrackedEvent(context, run, chunk, recordTypeName, request, response, 'duplicate-harvest-id');
842
+ return { response };
843
+ }
844
+ const recordRequest = (_.isPlainObject(request.recordRequest) ? request.recordRequest : {});
845
+ const metadata = this.normalizeMetadata(recordRequest);
846
+ const updateStrategy = this.normalizeTrackedUpdateStrategy(request.updateStrategy);
847
+ switch (operation) {
848
+ case HarvestRunModel_1.HarvestOperation.create: {
849
+ if (existingRecords.length > 0) {
850
+ const response = this.buildTrackedFailureResponse(harvestId, operation, `Record already exists for harvestId ${harvestId}.`, '', String(existingRecords[0]?.redboxOid ?? ''));
851
+ this.bufferTrackedEvent(context, run, chunk, recordTypeName, request, response, 'record-exists');
852
+ return { response };
853
+ }
854
+ const response = await this.createTrackedRecord(brand, recordTypeModel, recordRequest, harvestId, user);
855
+ this.bufferTrackedEvent(context, run, chunk, recordTypeName, request, response, response.status ? undefined : 'create-failed');
856
+ return {
857
+ response,
858
+ rollback: response.status && !_.isEmpty(response.oid)
859
+ ? async () => await this.rollbackCreatedTrackedRecord(response.oid, recordTypeModel, user)
860
+ : undefined,
861
+ };
862
+ }
863
+ case HarvestRunModel_1.HarvestOperation.update: {
864
+ if (existingRecords.length === 0) {
865
+ const response = this.buildTrackedFailureResponse(harvestId, operation, `No record was found for harvestId ${harvestId}.`);
866
+ this.bufferTrackedEvent(context, run, chunk, recordTypeName, request, response, 'missing-record');
867
+ return { response };
868
+ }
869
+ const existingRecord = existingRecords[0];
870
+ const oid = String(existingRecord.redboxOid ?? '');
871
+ const existingMetadata = (existingRecord.metadata ?? {});
872
+ if (this.isMetadataEqual(metadata, existingMetadata)) {
873
+ const response = {
874
+ harvestId,
875
+ oid,
876
+ operation,
877
+ outcome: HarvestRunModel_1.HarvestOutcome.unchanged,
878
+ status: true,
879
+ message: `Record metadata is unchanged, skipping update. oid: ${oid}`,
880
+ details: '',
881
+ };
882
+ this.bufferTrackedEvent(context, run, chunk, recordTypeName, request, response);
883
+ return { response };
884
+ }
885
+ const updateResult = await this.updateTrackedRecord(brand, recordTypeModel, metadata, oid, user, updateStrategy);
886
+ const response = {
887
+ harvestId,
888
+ oid,
889
+ operation,
890
+ outcome: updateResult.success ? HarvestRunModel_1.HarvestOutcome.updated : HarvestRunModel_1.HarvestOutcome.failed,
891
+ status: updateResult.success,
892
+ message: updateResult.message,
893
+ details: updateResult.details,
894
+ };
895
+ this.bufferTrackedEvent(context, run, chunk, recordTypeName, request, response, updateResult.success ? undefined : 'update-failed');
896
+ return {
897
+ response,
898
+ rollback: updateResult.success && updateResult.previousRecord
899
+ ? async () => await this.rollbackUpdatedTrackedRecord(brand, oid, updateResult.previousRecord, user)
900
+ : undefined,
901
+ };
902
+ }
903
+ case HarvestRunModel_1.HarvestOperation.delete: {
904
+ if (existingRecords.length === 0) {
905
+ const response = this.buildTrackedFailureResponse(harvestId, operation, `No record was found for harvestId ${harvestId}.`);
906
+ this.bufferTrackedEvent(context, run, chunk, recordTypeName, request, response, 'missing-record');
907
+ return { response };
908
+ }
909
+ const existingRecord = existingRecords[0];
910
+ const oid = String(existingRecord.redboxOid ?? '');
911
+ try {
912
+ const deleteResponse = await RecordsService.delete(oid, false, existingRecord, recordTypeModel, user);
913
+ const response = {
914
+ harvestId,
915
+ oid,
916
+ operation,
917
+ outcome: deleteResponse.isSuccessful() ? HarvestRunModel_1.HarvestOutcome.deleted : HarvestRunModel_1.HarvestOutcome.failed,
918
+ status: deleteResponse.isSuccessful(),
919
+ message: deleteResponse.isSuccessful()
920
+ ? 'Record deleted successfully'
921
+ : String(deleteResponse.message ?? 'Record deletion failed'),
922
+ details: typeof deleteResponse.details === 'string' ? deleteResponse.details : '',
923
+ };
924
+ this.bufferTrackedEvent(context, run, chunk, recordTypeName, request, response, response.status ? undefined : 'delete-failed');
925
+ return {
926
+ response,
927
+ rollback: response.status && !_.isEmpty(oid)
928
+ ? async () => await this.rollbackDeletedTrackedRecord(oid, user)
929
+ : undefined,
930
+ };
931
+ }
932
+ catch (error) {
933
+ const response = this.buildTrackedFailureResponse(harvestId, operation, this.asError(error).message, '', oid);
934
+ this.bufferTrackedEvent(context, run, chunk, recordTypeName, request, response, 'delete-failed');
935
+ return { response };
936
+ }
937
+ }
938
+ case HarvestRunModel_1.HarvestOperation.upsert:
939
+ default: {
940
+ if (existingRecords.length === 0) {
941
+ const response = await this.createTrackedRecord(brand, recordTypeModel, recordRequest, harvestId, user);
942
+ response.operation = HarvestRunModel_1.HarvestOperation.upsert;
943
+ this.bufferTrackedEvent(context, run, chunk, recordTypeName, request, response, response.status ? undefined : 'create-failed');
944
+ return {
945
+ response,
946
+ rollback: response.status && !_.isEmpty(response.oid)
947
+ ? async () => await this.rollbackCreatedTrackedRecord(response.oid, recordTypeModel, user)
948
+ : undefined,
949
+ };
950
+ }
951
+ const existingRecord = existingRecords[0];
952
+ const oid = String(existingRecord.redboxOid ?? '');
953
+ if (updateStrategy === 'ignoreIfExists') {
954
+ const response = {
955
+ harvestId,
956
+ oid,
957
+ operation,
958
+ outcome: HarvestRunModel_1.HarvestOutcome.unchanged,
959
+ status: true,
960
+ message: `Record ignored as the record already exists. oid: ${oid}`,
961
+ details: '',
962
+ };
963
+ this.bufferTrackedEvent(context, run, chunk, recordTypeName, request, response);
964
+ return { response };
965
+ }
966
+ const existingMetadata = (existingRecord.metadata ?? {});
967
+ if (this.isMetadataEqual(metadata, existingMetadata)) {
968
+ const response = {
969
+ harvestId,
970
+ oid,
971
+ operation,
972
+ outcome: HarvestRunModel_1.HarvestOutcome.unchanged,
973
+ status: true,
974
+ message: `Record metadata is unchanged, skipping update. oid: ${oid}`,
975
+ details: '',
976
+ };
977
+ this.bufferTrackedEvent(context, run, chunk, recordTypeName, request, response);
978
+ return { response };
979
+ }
980
+ const updateResult = await this.updateTrackedRecord(brand, recordTypeModel, metadata, oid, user, updateStrategy);
981
+ const response = {
982
+ harvestId,
983
+ oid,
984
+ operation,
985
+ outcome: updateResult.success ? HarvestRunModel_1.HarvestOutcome.updated : HarvestRunModel_1.HarvestOutcome.failed,
986
+ status: updateResult.success,
987
+ message: updateResult.message,
988
+ details: updateResult.details,
989
+ };
990
+ this.bufferTrackedEvent(context, run, chunk, recordTypeName, request, response, updateResult.success ? undefined : 'update-failed');
991
+ return {
992
+ response,
993
+ rollback: updateResult.success && updateResult.previousRecord
994
+ ? async () => await this.rollbackUpdatedTrackedRecord(brand, oid, updateResult.previousRecord, user)
995
+ : undefined,
996
+ };
997
+ }
998
+ }
999
+ }
1000
+ async submitCompatibilityRecords(brand, recordTypeModel, body, updateMode, user) {
1001
+ if (body == null || _.isEmpty(body['records'])) {
1002
+ throw new HarvestRunService_1.HarvestRunServiceError('Invalid request body', 400);
1003
+ }
1004
+ const recordType = this.resolveRecordTypeName(recordTypeModel);
1005
+ const records = body['records'];
1006
+ const recordResponses = [];
1007
+ for (const record of records) {
1008
+ const harvestId = String(record['harvestId'] ?? '');
1009
+ if (_.isEmpty(harvestId)) {
1010
+ recordResponses.push(new APIHarvestResponse_1.APIHarvestResponse(harvestId, '', false, 'HarvestId was not specified'));
1011
+ continue;
1012
+ }
1013
+ const recordRequest = (_.isPlainObject(record['recordRequest']) ? record['recordRequest'] : undefined);
1014
+ const existingRecord = await this.findExistingHarvestRecord(harvestId, recordType);
1015
+ if (existingRecord.length === 0 || updateMode === 'create') {
1016
+ recordResponses.push(await this.legacyCreateHarvestRecord(brand, recordTypeModel, (recordRequest ?? {}), harvestId, updateMode, user));
1017
+ continue;
1018
+ }
1019
+ const oid = String(existingRecord[0]?.redboxOid ?? '');
1020
+ if (updateMode === 'ignore') {
1021
+ recordResponses.push(new APIHarvestResponse_1.APIHarvestResponse(harvestId, oid, true, `Record ignored as the record already exists. oid: ${oid}`));
1022
+ continue;
1023
+ }
1024
+ const newMetadata = this.normalizeMetadata(recordRequest);
1025
+ const existingMetadata = (existingRecord[0]?.metadata ?? {});
1026
+ if (this.isMetadataEqual(newMetadata, existingMetadata)) {
1027
+ recordResponses.push(new APIHarvestResponse_1.APIHarvestResponse(harvestId, oid, true, `Record metadata is unchanged, skipping update. oid: ${oid}`));
1028
+ continue;
1029
+ }
1030
+ recordResponses.push(await this.legacyUpdateHarvestRecord(brand, recordTypeModel, updateMode, (recordRequest?.metadata ?? {}), oid, harvestId, user));
1031
+ }
1032
+ return recordResponses;
1033
+ }
1034
+ async submitLegacyRecords(brand, recordTypeModel, body, merge, user) {
1035
+ if (body == null || _.isEmpty(body['records'])) {
1036
+ throw new HarvestRunService_1.HarvestRunServiceError('Invalid request body', 400);
1037
+ }
1038
+ const recordType = this.resolveRecordTypeName(recordTypeModel);
1039
+ const records = body['records'];
1040
+ const responses = [];
1041
+ for (const record of records) {
1042
+ const harvestId = String(record['harvest_id'] ?? '');
1043
+ if (_.isEmpty(harvestId)) {
1044
+ responses.push(new APIHarvestResponse_1.APIHarvestResponse(harvestId, '', false, 'HarvestId was not specified'));
1045
+ continue;
1046
+ }
1047
+ const metadata = (_.isPlainObject(record['metadata']) ? record['metadata'] : undefined);
1048
+ const existingRecord = await this.findExistingHarvestRecord(harvestId, recordType);
1049
+ if (existingRecord.length === 0) {
1050
+ responses.push(await this.legacyCreateHarvestRecord(brand, recordTypeModel, (metadata?.data ?? {}), harvestId, 'update', user));
1051
+ continue;
1052
+ }
1053
+ const updateMode = merge ? 'merge' : 'update';
1054
+ const oid = String(existingRecord[0]?.redboxOid ?? '');
1055
+ const oldMetadata = (existingRecord[0]?.metadata ?? {});
1056
+ const newMetadata = (metadata?.data ?? {});
1057
+ if (this.isMetadataEqual(newMetadata, oldMetadata)) {
1058
+ responses.push(new APIHarvestResponse_1.APIHarvestResponse(harvestId, oid, true, `skip update of harvestId ${harvestId} oid ${oid} metadata sent is equal to metadata in existing record`));
1059
+ continue;
1060
+ }
1061
+ responses.push(await this.legacyUpdateHarvestRecord(brand, recordTypeModel, updateMode, newMetadata, oid, harvestId, user));
1062
+ }
1063
+ return responses;
1064
+ }
1065
+ getDuplicateHarvestIds(records) {
1066
+ const seen = new Set();
1067
+ const duplicates = new Set();
1068
+ for (const record of records) {
1069
+ const harvestId = String(record.harvestId ?? '').trim();
1070
+ if (_.isEmpty(harvestId)) {
1071
+ continue;
1072
+ }
1073
+ if (seen.has(harvestId)) {
1074
+ duplicates.add(harvestId);
1075
+ }
1076
+ seen.add(harvestId);
1077
+ }
1078
+ return duplicates;
1079
+ }
1080
+ buildChunkResponseSummary(counters) {
1081
+ return {
1082
+ totalProcessed: counters.totalProcessed,
1083
+ created: counters.created,
1084
+ updated: counters.updated,
1085
+ deleted: counters.deleted,
1086
+ unchanged: counters.unchanged,
1087
+ failed: counters.failed,
1088
+ };
1089
+ }
1090
+ async findMatchingChunks(runId, contentHash) {
1091
+ if (_.isEmpty(runId)) {
1092
+ return [];
1093
+ }
1094
+ return await HarvestRunChunk.find({
1095
+ runId,
1096
+ contentHash,
1097
+ }).sort('attempt DESC');
1098
+ }
1099
+ async submitChunk(brand, recordTypeModel, requestBody, user) {
1100
+ const request = this.validateTrackedChunkRequest(requestBody);
1101
+ const brandId = this.resolveBrandId(brand);
1102
+ const recordTypeName = this.resolveRecordTypeName(recordTypeModel);
1103
+ const run = await this.findOrCreateRun(brand, recordTypeModel, request, user);
1104
+ const contentHash = this.buildChunkContentHash(brandId, recordTypeName, request);
1105
+ const existingChunks = await this.findMatchingChunks(run.id, contentHash);
1106
+ const processedChunk = existingChunks.find(chunk => chunk.status === HarvestRunModel_1.HarvestChunkStatus.processed);
1107
+ if (processedChunk) {
1108
+ const updatedRun = await this.bumpDuplicateChunkCount(run);
1109
+ return {
1110
+ run: this.toRunModel(updatedRun),
1111
+ chunk: this.toChunkModel(processedChunk, true),
1112
+ };
1113
+ }
1114
+ const processingChunk = existingChunks.find(chunk => chunk.status === HarvestRunModel_1.HarvestChunkStatus.processing);
1115
+ const resumeChunkIds = existingChunks
1116
+ .filter(chunk => chunk.status === HarvestRunModel_1.HarvestChunkStatus.failed || chunk.status === HarvestRunModel_1.HarvestChunkStatus.failedStale)
1117
+ .map(chunk => String(chunk.id ?? ''));
1118
+ if (processingChunk) {
1119
+ if (!this.isProcessingChunkStale(processingChunk)) {
1120
+ throw new HarvestRunService_1.HarvestRunServiceError('Chunk is already processing', 409);
1121
+ }
1122
+ await HarvestRunChunk.updateOne({ id: processingChunk.id }).set({
1123
+ status: HarvestRunModel_1.HarvestChunkStatus.failedStale,
1124
+ completedAt: this.nowIso(),
1125
+ errorMessage: 'Processing chunk was marked stale before retry.',
1126
+ });
1127
+ resumeChunkIds.push(String(processingChunk.id ?? ''));
1128
+ }
1129
+ const checkpointedEvents = await this.listCheckpointedChunkEvents(run.id, brandId, resumeChunkIds);
1130
+ if (checkpointedEvents.length > request.records.length) {
1131
+ throw new HarvestRunService_1.HarvestRunServiceError('Tracked harvest retry state is inconsistent with the submitted payload.', 409);
1132
+ }
1133
+ const submittedAt = this.nowIso();
1134
+ const nextAttempt = existingChunks.reduce((maxAttempt, chunk) => Math.max(maxAttempt, Number(chunk.attempt ?? 1)), 0) + 1;
1135
+ const createdChunk = await HarvestRunChunk.create({
1136
+ runId: String(run.id ?? ''),
1137
+ brandId,
1138
+ recordType: recordTypeName,
1139
+ sourceRunId: request.sourceRunId,
1140
+ contentHash,
1141
+ attempt: nextAttempt,
1142
+ chunkIndex: request.chunk?.index,
1143
+ chunkLabel: request.chunk?.label,
1144
+ totalExpected: request.chunk?.totalExpected,
1145
+ status: HarvestRunModel_1.HarvestChunkStatus.processing,
1146
+ recordCount: request.records.length,
1147
+ totalProcessed: 0,
1148
+ created: 0,
1149
+ updated: 0,
1150
+ deleted: 0,
1151
+ unchanged: 0,
1152
+ failed: 0,
1153
+ duplicate: false,
1154
+ submittedAt,
1155
+ responseSummary: this.buildChunkResponseSummary(this.buildEmptyCounters()),
1156
+ }).fetch();
1157
+ const counters = this.buildCountersFromTrackedEvents(checkpointedEvents);
1158
+ try {
1159
+ const duplicateHarvestIds = this.getDuplicateHarvestIds(request.records);
1160
+ const existingByHarvestId = await this.findExistingTrackedHarvestRecordsBatch(brandId, request.records.map(record => String(record.harvestId ?? '').trim()), recordTypeName);
1161
+ const context = {
1162
+ duplicateHarvestIds,
1163
+ existingByHarvestId,
1164
+ events: [],
1165
+ };
1166
+ for (const record of request.records.slice(checkpointedEvents.length)) {
1167
+ const processed = await this.processTrackedRecord(brand, recordTypeModel, run, createdChunk, record, user, context);
1168
+ try {
1169
+ await this.persistTrackedEvents(context.events);
1170
+ }
1171
+ catch (error) {
1172
+ context.events = [];
1173
+ if (processed.rollback) {
1174
+ try {
1175
+ await processed.rollback();
1176
+ }
1177
+ catch (rollbackError) {
1178
+ throw new Error(`Failed to persist tracked harvest events: ${this.asError(error).message}. ` +
1179
+ `Record rollback also failed: ${this.asError(rollbackError).message}`);
1180
+ }
1181
+ }
1182
+ throw error;
1183
+ }
1184
+ context.events = [];
1185
+ this.incrementCounters(counters, processed.response.outcome);
1186
+ await this.checkpointChunkProgress(createdChunk.id, request.records.length, counters);
1187
+ }
1188
+ const completedAt = this.nowIso();
1189
+ const chunkUpdates = {
1190
+ status: HarvestRunModel_1.HarvestChunkStatus.processed,
1191
+ recordCount: request.records.length,
1192
+ totalProcessed: counters.totalProcessed,
1193
+ created: counters.created,
1194
+ updated: counters.updated,
1195
+ deleted: counters.deleted,
1196
+ unchanged: counters.unchanged,
1197
+ failed: counters.failed,
1198
+ completedAt,
1199
+ responseSummary: this.buildChunkResponseSummary(counters),
1200
+ };
1201
+ const updatedChunk = await HarvestRunChunk.updateOne({ id: createdChunk.id }).set(chunkUpdates);
1202
+ const updatedRun = await this.updateRunAfterChunk(run, counters, Boolean(request.finalChunk), completedAt);
1203
+ return {
1204
+ run: this.toRunModel(updatedRun),
1205
+ chunk: this.toChunkModel(updatedChunk ?? { ...createdChunk, ...chunkUpdates }),
1206
+ };
1207
+ }
1208
+ catch (error) {
1209
+ await HarvestRunChunk.updateOne({ id: createdChunk.id }).set({
1210
+ status: HarvestRunModel_1.HarvestChunkStatus.failed,
1211
+ recordCount: request.records.length,
1212
+ totalProcessed: counters.totalProcessed,
1213
+ created: counters.created,
1214
+ updated: counters.updated,
1215
+ deleted: counters.deleted,
1216
+ unchanged: counters.unchanged,
1217
+ failed: counters.failed,
1218
+ completedAt: this.nowIso(),
1219
+ errorMessage: this.asError(error).message,
1220
+ responseSummary: this.buildChunkResponseSummary(counters),
1221
+ });
1222
+ throw error;
1223
+ }
1224
+ }
1225
+ async listRuns(brand, params) {
1226
+ const brandId = this.resolveBrandId(brand);
1227
+ const page = this.parsePositiveInt(params.page, 1);
1228
+ const pageSize = Math.min(100, this.parsePositiveInt(params.pageSize, 20));
1229
+ const skip = (page - 1) * pageSize;
1230
+ const where = { brandId };
1231
+ if (!_.isEmpty(params.status)) {
1232
+ where.status = String(params.status);
1233
+ }
1234
+ if (!_.isEmpty(params.recordType)) {
1235
+ where.recordType = String(params.recordType);
1236
+ }
1237
+ if (!_.isEmpty(params.sourceName)) {
1238
+ where.sourceName = String(params.sourceName);
1239
+ }
1240
+ const startedAtFilters = {};
1241
+ if (params.dateFrom instanceof Date && !Number.isNaN(params.dateFrom.getTime())) {
1242
+ startedAtFilters['>='] = params.dateFrom.toISOString();
1243
+ }
1244
+ if (params.dateTo instanceof Date && !Number.isNaN(params.dateTo.getTime())) {
1245
+ startedAtFilters['<='] = params.dateTo.toISOString();
1246
+ }
1247
+ if (!_.isEmpty(startedAtFilters)) {
1248
+ where.startedAt = startedAtFilters;
1249
+ }
1250
+ const total = await HarvestRun.count(where);
1251
+ const rows = await HarvestRun.find(where).sort('startedAt DESC').skip(skip).limit(pageSize);
1252
+ return {
1253
+ rows: rows.map(row => this.toRunModel(row)),
1254
+ total: Number(total ?? 0),
1255
+ };
1256
+ }
1257
+ async getRun(brand, runId) {
1258
+ const brandId = this.resolveBrandId(brand);
1259
+ const run = await HarvestRun.findOne({ id: runId, brandId });
1260
+ if (!run) {
1261
+ return null;
1262
+ }
1263
+ const chunks = await HarvestRunChunk.find({ runId, brandId }).sort('submittedAt ASC').limit(100);
1264
+ const events = await HarvestRecordEvent.find({ runId, brandId }).sort('createdAt DESC').limit(20);
1265
+ return {
1266
+ run: this.toRunModel(run),
1267
+ chunks: chunks.map(row => this.toChunkModel(row)),
1268
+ events: events.map(row => this.toEventModel(row)),
1269
+ aggregateCounts: {
1270
+ totalProcessed: Number(run.totalProcessed ?? 0),
1271
+ created: Number(run.created ?? 0),
1272
+ updated: Number(run.updated ?? 0),
1273
+ deleted: Number(run.deleted ?? 0),
1274
+ unchanged: Number(run.unchanged ?? 0),
1275
+ failed: Number(run.failed ?? 0),
1276
+ chunksProcessed: Number(run.chunksProcessed ?? 0),
1277
+ duplicateChunks: Number(run.duplicateChunks ?? 0),
1278
+ },
1279
+ };
1280
+ }
1281
+ async runExists(brand, runId) {
1282
+ const brandId = this.resolveBrandId(brand);
1283
+ const run = await HarvestRun.findOne({ id: runId, brandId });
1284
+ return !_.isNil(run);
1285
+ }
1286
+ async listRunEvents(brand, runId, params) {
1287
+ const brandId = this.resolveBrandId(brand);
1288
+ const page = this.parsePositiveInt(params.page, 1);
1289
+ const pageSize = Math.min(100, this.parsePositiveInt(params.pageSize, 20));
1290
+ const skip = (page - 1) * pageSize;
1291
+ const where = {
1292
+ runId,
1293
+ brandId,
1294
+ };
1295
+ if (!_.isEmpty(params.outcome)) {
1296
+ where.outcome = String(params.outcome);
1297
+ }
1298
+ if (!_.isEmpty(params.operation)) {
1299
+ where.operation = String(params.operation);
1300
+ }
1301
+ if (!_.isEmpty(params.harvestId)) {
1302
+ where.harvestId = String(params.harvestId);
1303
+ }
1304
+ if (!_.isEmpty(params.oid)) {
1305
+ where.oid = String(params.oid);
1306
+ }
1307
+ const total = await HarvestRecordEvent.count(where);
1308
+ const rows = await HarvestRecordEvent.find(where).sort('createdAt DESC').skip(skip).limit(pageSize);
1309
+ return {
1310
+ rows: rows.map(row => this.toEventModel(row)),
1311
+ total: Number(total ?? 0),
1312
+ };
1313
+ }
1314
+ }
1315
+ Services.HarvestRunService = HarvestRunService;
1316
+ })(Services || (exports.Services = Services = {}));
1317
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSGFydmVzdFJ1blNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZXMvSGFydmVzdFJ1blNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsMENBQTRCO0FBQzVCLDZDQUF5QztBQUN6QywrQkFBa0Q7QUFFbEQsZ0RBQXNEO0FBRXRELDREQUFrTztBQUNsTyxvRUFBaUU7QUFLakUsc0VBYzBDO0FBSzFDLHFDQUFtQztBQTJDbkMsSUFBaUIsUUFBUSxDQWtsRHhCO0FBbGxERCxXQUFpQixRQUFRO0lBQ3ZCLE1BQWEsaUJBQWtCLFNBQVEsc0JBQVEsQ0FBQyxJQUFJLENBQUMsT0FBTztRQUN2QyxnQkFBZ0IsR0FBYTtZQUM5Qyw0QkFBNEI7WUFDNUIscUJBQXFCO1lBQ3JCLGFBQWE7WUFDYixVQUFVO1lBQ1YsUUFBUTtZQUNSLFdBQVc7WUFDWCxlQUFlO1NBQ2hCLENBQUM7UUFFRjtZQUNFLEtBQUssRUFBRSxDQUFDO1lBQ1IsSUFBSSxDQUFDLFNBQVMsR0FBRyxxQkFBcUIsQ0FBQztRQUN6QyxDQUFDO1FBRU8sT0FBTyxDQUFDLEtBQWM7WUFDNUIsT0FBTyxLQUFLLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQ25FLENBQUM7UUFFTyxjQUFjLENBQUMsS0FBNkI7WUFDbEQsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLEVBQUUsQ0FBQztnQkFDOUIsT0FBTyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDdEIsQ0FBQztZQUNELE9BQU8sTUFBTSxDQUFDLEtBQUssRUFBRSxFQUFFLElBQUksS0FBSyxFQUFFLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUN2RCxDQUFDO1FBRU8s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