@empline/preflight 1.1.9 → 1.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/checks/card-processing/image-workflow-validation.js +37 -5
- package/dist/checks/card-processing/image-workflow-validation.js.map +1 -1
- package/dist/checks/card-processing/import-workflow-validation.d.ts +23 -0
- package/dist/checks/card-processing/import-workflow-validation.d.ts.map +1 -0
- package/dist/checks/card-processing/import-workflow-validation.js +518 -0
- package/dist/checks/card-processing/import-workflow-validation.js.map +1 -0
- package/dist/checks/turbopack/prisma-computed-property.d.ts +45 -0
- package/dist/checks/turbopack/prisma-computed-property.d.ts.map +1 -0
- package/dist/checks/turbopack/prisma-computed-property.js +319 -0
- package/dist/checks/turbopack/prisma-computed-property.js.map +1 -0
- package/dist/checks/ui/ui-consistency-validation.d.ts +51 -6
- package/dist/checks/ui/ui-consistency-validation.d.ts.map +1 -1
- package/dist/checks/ui/ui-consistency-validation.js +438 -26
- package/dist/checks/ui/ui-consistency-validation.js.map +1 -1
- package/dist/checks/ui/z-index-check.d.ts.map +1 -1
- package/dist/checks/ui/z-index-check.js +12 -3
- package/dist/checks/ui/z-index-check.js.map +1 -1
- package/dist/utils/console-chars.d.ts +2 -0
- package/dist/utils/console-chars.d.ts.map +1 -1
- package/dist/utils/console-chars.js +1 -0
- package/dist/utils/console-chars.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Import Workflow Validation
|
|
4
|
+
*
|
|
5
|
+
* Validates that WooCommerce/Shopify import processes follow best practices:
|
|
6
|
+
* 1. Retry logic with exponential backoff
|
|
7
|
+
* 2. Partial image success (don't block on single image failure)
|
|
8
|
+
* 3. Image processing timeouts
|
|
9
|
+
* 4. Reasonable batch sizes
|
|
10
|
+
* 5. SKU normalization for duplicate detection
|
|
11
|
+
* 6. Pre-processed image flow (from ImageReviewStep)
|
|
12
|
+
* 7. Progress state persistence (localStorage)
|
|
13
|
+
* 8. SSE progress streaming support
|
|
14
|
+
*/
|
|
15
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
18
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
19
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
20
|
+
}
|
|
21
|
+
Object.defineProperty(o, k2, desc);
|
|
22
|
+
}) : (function(o, m, k, k2) {
|
|
23
|
+
if (k2 === undefined) k2 = k;
|
|
24
|
+
o[k2] = m[k];
|
|
25
|
+
}));
|
|
26
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
27
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
28
|
+
}) : function(o, v) {
|
|
29
|
+
o["default"] = v;
|
|
30
|
+
});
|
|
31
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
32
|
+
var ownKeys = function(o) {
|
|
33
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
34
|
+
var ar = [];
|
|
35
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
36
|
+
return ar;
|
|
37
|
+
};
|
|
38
|
+
return ownKeys(o);
|
|
39
|
+
};
|
|
40
|
+
return function (mod) {
|
|
41
|
+
if (mod && mod.__esModule) return mod;
|
|
42
|
+
var result = {};
|
|
43
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
44
|
+
__setModuleDefault(result, mod);
|
|
45
|
+
return result;
|
|
46
|
+
};
|
|
47
|
+
})();
|
|
48
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49
|
+
exports.description = exports.blocking = exports.category = exports.name = exports.id = void 0;
|
|
50
|
+
exports.run = run;
|
|
51
|
+
const fs = __importStar(require("fs"));
|
|
52
|
+
const path = __importStar(require("path"));
|
|
53
|
+
const console_chars_1 = require("../../utils/console-chars");
|
|
54
|
+
// Check metadata (required for preflight runner discovery)
|
|
55
|
+
exports.id = "card-processing/import-workflow-validation";
|
|
56
|
+
exports.name = "Import Workflow Validation";
|
|
57
|
+
exports.category = "card-processing";
|
|
58
|
+
exports.blocking = true;
|
|
59
|
+
exports.description = "Validates WooCommerce/Shopify import processes follow best practices (retry logic, timeouts, batch sizes, SSE streaming)";
|
|
60
|
+
// Base path for the trading-card-system
|
|
61
|
+
const BASE_PATH = process.cwd();
|
|
62
|
+
function readFile(relativePath) {
|
|
63
|
+
try {
|
|
64
|
+
const fullPath = path.join(BASE_PATH, relativePath);
|
|
65
|
+
return fs.readFileSync(fullPath, "utf8");
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Check 1: Retry Logic with Exponential Backoff
|
|
73
|
+
*/
|
|
74
|
+
function checkRetryLogic() {
|
|
75
|
+
const errors = [];
|
|
76
|
+
const warnings = [];
|
|
77
|
+
// Check import-utils.ts exists and has retry functions
|
|
78
|
+
const importUtils = readFile("lib/import-utils.ts");
|
|
79
|
+
if (!importUtils) {
|
|
80
|
+
errors.push("Missing lib/import-utils.ts - should contain retry utilities");
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
if (!importUtils.includes("withRetry")) {
|
|
84
|
+
errors.push("lib/import-utils.ts missing withRetry function");
|
|
85
|
+
}
|
|
86
|
+
if (!importUtils.includes("exponential") || !importUtils.includes("backoff")) {
|
|
87
|
+
warnings.push("lib/import-utils.ts should document exponential backoff behavior");
|
|
88
|
+
}
|
|
89
|
+
if (!importUtils.includes("isTransientError")) {
|
|
90
|
+
errors.push("lib/import-utils.ts missing isTransientError function for identifying retryable errors");
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Check image-variants-generator uses retry logic
|
|
94
|
+
const imageVariants = readFile("lib/image-variants-generator.ts");
|
|
95
|
+
if (imageVariants) {
|
|
96
|
+
if (!imageVariants.includes("fetchWithRetry") && !imageVariants.includes("withRetry")) {
|
|
97
|
+
errors.push("lib/image-variants-generator.ts should use retry logic for image downloads");
|
|
98
|
+
}
|
|
99
|
+
if (!imageVariants.includes("uploadToR2WithRetry")) {
|
|
100
|
+
warnings.push("lib/image-variants-generator.ts should use retry logic for R2 uploads");
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
name: "Retry Logic with Exponential Backoff",
|
|
105
|
+
passed: errors.length === 0,
|
|
106
|
+
errors,
|
|
107
|
+
warnings,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Check 2: Partial Image Success
|
|
112
|
+
*/
|
|
113
|
+
function checkPartialImageSuccess() {
|
|
114
|
+
const errors = [];
|
|
115
|
+
const warnings = [];
|
|
116
|
+
const importRoutes = [
|
|
117
|
+
{ name: "WooCommerce", path: "app/api/store/integrations/woocommerce/import/route.ts" },
|
|
118
|
+
{ name: "Shopify", path: "app/api/store/integrations/shopify/import-products/route.ts" },
|
|
119
|
+
];
|
|
120
|
+
for (const { name, path: routePath } of importRoutes) {
|
|
121
|
+
const content = readFile(routePath);
|
|
122
|
+
if (!content)
|
|
123
|
+
continue;
|
|
124
|
+
// Check for partial success pattern - multiple valid patterns:
|
|
125
|
+
// 1. Explicit "successful.length > 0" check
|
|
126
|
+
// 2. Catches errors with logger.warn (graceful degradation)
|
|
127
|
+
// 3. Only blocks when "successful.length === 0"
|
|
128
|
+
const hasPartialSuccessCheck = content.includes("variantsResult.successful.length > 0") ||
|
|
129
|
+
content.includes("successful.length > 0");
|
|
130
|
+
const hasGracefulDegradation = content.includes("logger.warn") &&
|
|
131
|
+
(content.includes("Failed to upload") || content.includes("Failed to process")) &&
|
|
132
|
+
!content.includes("throw new Error");
|
|
133
|
+
const hasOnlyBlockOnAllFail = content.includes("variantsResult.successful.length === 0") ||
|
|
134
|
+
(content.includes("BLOCK") && content.includes("length === 0"));
|
|
135
|
+
// For Shopify-style graceful handling (catch errors, log warnings, continue)
|
|
136
|
+
const hasTryCatchWithWarn = content.includes("try {") &&
|
|
137
|
+
content.includes("catch (imgError)") &&
|
|
138
|
+
content.includes("logger.warn");
|
|
139
|
+
const allowsPartialSuccess = hasPartialSuccessCheck ||
|
|
140
|
+
hasGracefulDegradation ||
|
|
141
|
+
hasTryCatchWithWarn;
|
|
142
|
+
if (!allowsPartialSuccess) {
|
|
143
|
+
errors.push(`${name} import should allow partial image success (if at least 1 image succeeds)`);
|
|
144
|
+
}
|
|
145
|
+
// Only warn about blocking if we don't have graceful degradation
|
|
146
|
+
if (!hasOnlyBlockOnAllFail && !hasGracefulDegradation && !hasTryCatchWithWarn) {
|
|
147
|
+
warnings.push(`${name} import should only block when ALL images fail, not on partial failure`);
|
|
148
|
+
}
|
|
149
|
+
// Check that it doesn't throw on partial failure (only for WooCommerce which has explicit checks)
|
|
150
|
+
if (name === "WooCommerce" && content.includes("failed.length > 0") && content.includes("throw new Error")) {
|
|
151
|
+
// Check if it's in a conditional that also checks successful > 0
|
|
152
|
+
const failedCheck = content.indexOf("failed.length > 0");
|
|
153
|
+
const successCheck = content.indexOf("successful.length > 0");
|
|
154
|
+
// This is a heuristic - if failed check throws without success check nearby, flag it
|
|
155
|
+
if (successCheck === -1 || Math.abs(failedCheck - successCheck) > 500) {
|
|
156
|
+
warnings.push(`${name} import may be throwing on partial image failure - verify logic`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return {
|
|
161
|
+
name: "Partial Image Success",
|
|
162
|
+
passed: errors.length === 0,
|
|
163
|
+
errors,
|
|
164
|
+
warnings,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Check 3: Image Processing Timeouts
|
|
169
|
+
*/
|
|
170
|
+
function checkImageTimeouts() {
|
|
171
|
+
const errors = [];
|
|
172
|
+
const warnings = [];
|
|
173
|
+
const importUtils = readFile("lib/import-utils.ts");
|
|
174
|
+
if (importUtils) {
|
|
175
|
+
if (!importUtils.includes("IMAGE_DOWNLOAD_TIMEOUT")) {
|
|
176
|
+
errors.push("lib/import-utils.ts missing IMAGE_DOWNLOAD_TIMEOUT constant");
|
|
177
|
+
}
|
|
178
|
+
if (!importUtils.includes("IMAGE_PROCESSING_TIMEOUT")) {
|
|
179
|
+
errors.push("lib/import-utils.ts missing IMAGE_PROCESSING_TIMEOUT constant");
|
|
180
|
+
}
|
|
181
|
+
if (!importUtils.includes("fetchWithTimeout")) {
|
|
182
|
+
errors.push("lib/import-utils.ts missing fetchWithTimeout function");
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
const imageVariants = readFile("lib/image-variants-generator.ts");
|
|
186
|
+
if (imageVariants) {
|
|
187
|
+
if (!imageVariants.includes("timeoutMs") && !imageVariants.includes("TIMEOUT")) {
|
|
188
|
+
warnings.push("lib/image-variants-generator.ts should use timeout for image downloads");
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
name: "Image Processing Timeouts",
|
|
193
|
+
passed: errors.length === 0,
|
|
194
|
+
errors,
|
|
195
|
+
warnings,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Check 4: Reasonable Batch Sizes
|
|
200
|
+
*/
|
|
201
|
+
function checkBatchSizes() {
|
|
202
|
+
const errors = [];
|
|
203
|
+
const warnings = [];
|
|
204
|
+
const clientFiles = [
|
|
205
|
+
{ name: "WooCommerce", path: "app/store/integrations/woocommerce/WooCommerceIntegrationClient.tsx" },
|
|
206
|
+
{ name: "Shopify", path: "app/store/integrations/shopify/ShopifyIntegrationClient.tsx" },
|
|
207
|
+
];
|
|
208
|
+
for (const { name, path: filePath } of clientFiles) {
|
|
209
|
+
const content = readFile(filePath);
|
|
210
|
+
if (!content)
|
|
211
|
+
continue;
|
|
212
|
+
// Look for BATCH_SIZE constant
|
|
213
|
+
const batchSizeMatch = content.match(/BATCH_SIZE\s*=\s*(\d+)/);
|
|
214
|
+
if (batchSizeMatch) {
|
|
215
|
+
const batchSize = parseInt(batchSizeMatch[1], 10);
|
|
216
|
+
if (batchSize > 10) {
|
|
217
|
+
errors.push(`${name} BATCH_SIZE is ${batchSize}, should be 10 or less for better error isolation`);
|
|
218
|
+
}
|
|
219
|
+
else if (batchSize > 8) {
|
|
220
|
+
warnings.push(`${name} BATCH_SIZE is ${batchSize}, consider reducing to 5 for better reliability`);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
warnings.push(`${name} should define BATCH_SIZE constant for image processing batches`);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return {
|
|
228
|
+
name: "Reasonable Batch Sizes",
|
|
229
|
+
passed: errors.length === 0,
|
|
230
|
+
errors,
|
|
231
|
+
warnings,
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Check 5: SKU Normalization
|
|
236
|
+
*/
|
|
237
|
+
function checkSkuNormalization() {
|
|
238
|
+
const errors = [];
|
|
239
|
+
const warnings = [];
|
|
240
|
+
const importUtils = readFile("lib/import-utils.ts");
|
|
241
|
+
if (!importUtils) {
|
|
242
|
+
errors.push("Missing lib/import-utils.ts");
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
if (!importUtils.includes("normalizeSku")) {
|
|
246
|
+
errors.push("lib/import-utils.ts missing normalizeSku function");
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
// Check that import routes use normalized SKU comparison
|
|
250
|
+
const woocommerceImport = readFile("app/api/store/integrations/woocommerce/import/route.ts");
|
|
251
|
+
if (woocommerceImport) {
|
|
252
|
+
if (!woocommerceImport.includes("normalizeSku")) {
|
|
253
|
+
errors.push("WooCommerce import should use normalizeSku for duplicate detection");
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
const shopifyImport = readFile("app/api/store/integrations/shopify/import-products/route.ts");
|
|
257
|
+
if (shopifyImport) {
|
|
258
|
+
if (!shopifyImport.includes("normalizeSku")) {
|
|
259
|
+
errors.push("Shopify import should use normalizeSku for duplicate detection");
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return {
|
|
263
|
+
name: "SKU Normalization",
|
|
264
|
+
passed: errors.length === 0,
|
|
265
|
+
errors,
|
|
266
|
+
warnings,
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Check 6: Pre-Processed Image Flow
|
|
271
|
+
*/
|
|
272
|
+
function checkPreProcessedImageFlow() {
|
|
273
|
+
const errors = [];
|
|
274
|
+
const warnings = [];
|
|
275
|
+
const importRoutes = [
|
|
276
|
+
{ name: "WooCommerce", path: "app/api/store/integrations/woocommerce/import/route.ts" },
|
|
277
|
+
{ name: "Shopify", path: "app/api/store/integrations/shopify/import-products/route.ts" },
|
|
278
|
+
];
|
|
279
|
+
for (const { name, path: routePath } of importRoutes) {
|
|
280
|
+
const content = readFile(routePath);
|
|
281
|
+
if (!content)
|
|
282
|
+
continue;
|
|
283
|
+
// Check for pre-processed image handling
|
|
284
|
+
const hasPreProcessedCheck = content.includes("processedImages") || content.includes("preProcessedImages");
|
|
285
|
+
const hasPreProcessedUpload = content.includes("uploadMultiplePreProcessedImages");
|
|
286
|
+
const hasFallback = content.includes("generateMultipleImageVariants");
|
|
287
|
+
if (!hasPreProcessedCheck) {
|
|
288
|
+
errors.push(`${name} import must check for processedImages from ImageReviewStep`);
|
|
289
|
+
}
|
|
290
|
+
if (!hasPreProcessedUpload) {
|
|
291
|
+
errors.push(`${name} import must use uploadMultiplePreProcessedImages for pre-processed images`);
|
|
292
|
+
}
|
|
293
|
+
if (!hasFallback) {
|
|
294
|
+
warnings.push(`${name} import should have fallback to generateMultipleImageVariants`);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
return {
|
|
298
|
+
name: "Pre-Processed Image Flow",
|
|
299
|
+
passed: errors.length === 0,
|
|
300
|
+
errors,
|
|
301
|
+
warnings,
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Check 7: Progress State Persistence
|
|
306
|
+
*
|
|
307
|
+
* All import wizards (WooCommerce, Shopify, CSV) should use the shared
|
|
308
|
+
* useWizardProgress hook for localStorage persistence and resume capability.
|
|
309
|
+
*/
|
|
310
|
+
function checkProgressPersistence() {
|
|
311
|
+
const errors = [];
|
|
312
|
+
const warnings = [];
|
|
313
|
+
// Check shared hook exists
|
|
314
|
+
const wizardProgressHook = readFile("hooks/useWizardProgress.ts");
|
|
315
|
+
if (!wizardProgressHook) {
|
|
316
|
+
errors.push("Missing hooks/useWizardProgress.ts - shared wizard progress persistence hook");
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
if (!wizardProgressHook.includes("localStorage")) {
|
|
320
|
+
errors.push("useWizardProgress hook should use localStorage for persistence");
|
|
321
|
+
}
|
|
322
|
+
if (!wizardProgressHook.includes("saveProgress") || !wizardProgressHook.includes("clearProgress")) {
|
|
323
|
+
errors.push("useWizardProgress hook missing saveProgress/clearProgress functions");
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
// Check WooCommerce uses the shared hook
|
|
327
|
+
const woocommerceClient = readFile("app/store/integrations/woocommerce/WooCommerceIntegrationClient.tsx");
|
|
328
|
+
if (woocommerceClient) {
|
|
329
|
+
if (!woocommerceClient.includes("useWizardProgress")) {
|
|
330
|
+
errors.push("WooCommerce client should use shared useWizardProgress hook");
|
|
331
|
+
}
|
|
332
|
+
if (!woocommerceClient.includes("showResumeDialog") && !woocommerceClient.includes("Resume")) {
|
|
333
|
+
warnings.push("WooCommerce client should offer option to resume from saved progress");
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
// Check Shopify uses the shared hook
|
|
337
|
+
const shopifyClient = readFile("app/store/integrations/shopify/ShopifyIntegrationClient.tsx");
|
|
338
|
+
if (shopifyClient) {
|
|
339
|
+
if (!shopifyClient.includes("useWizardProgress")) {
|
|
340
|
+
errors.push("Shopify client should use shared useWizardProgress hook");
|
|
341
|
+
}
|
|
342
|
+
if (!shopifyClient.includes("showResumeDialog") && !shopifyClient.includes("Resume")) {
|
|
343
|
+
warnings.push("Shopify client should offer option to resume from saved progress");
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
// Check CSV import uses the shared hook
|
|
347
|
+
const csvHook = readFile("hooks/useSellerCSVImport.ts");
|
|
348
|
+
if (csvHook) {
|
|
349
|
+
if (!csvHook.includes("useWizardProgress")) {
|
|
350
|
+
errors.push("CSV import hook should use shared useWizardProgress hook");
|
|
351
|
+
}
|
|
352
|
+
if (!csvHook.includes("showResumeDialog") && !csvHook.includes("handleResumeProgress")) {
|
|
353
|
+
warnings.push("CSV import should offer option to resume from saved progress");
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
return {
|
|
357
|
+
name: "Progress State Persistence",
|
|
358
|
+
passed: errors.length === 0,
|
|
359
|
+
errors,
|
|
360
|
+
warnings,
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Check 8: SSE Progress Streaming
|
|
365
|
+
*/
|
|
366
|
+
function checkSseProgressStreaming() {
|
|
367
|
+
const errors = [];
|
|
368
|
+
const warnings = [];
|
|
369
|
+
// Check for SSE endpoint
|
|
370
|
+
const sseEndpoint = readFile("app/api/store/integrations/import-progress/route.ts");
|
|
371
|
+
if (!sseEndpoint) {
|
|
372
|
+
errors.push("Missing SSE progress endpoint at app/api/store/integrations/import-progress/route.ts");
|
|
373
|
+
}
|
|
374
|
+
else {
|
|
375
|
+
if (!sseEndpoint.includes("text/event-stream")) {
|
|
376
|
+
errors.push("SSE endpoint should return text/event-stream content type");
|
|
377
|
+
}
|
|
378
|
+
if (!sseEndpoint.includes("updateImportProgress")) {
|
|
379
|
+
errors.push("SSE endpoint should export updateImportProgress function");
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
// Check for client-side hook
|
|
383
|
+
const progressHook = readFile("hooks/useImportProgress.ts");
|
|
384
|
+
if (!progressHook) {
|
|
385
|
+
warnings.push("Missing useImportProgress hook for client-side SSE consumption");
|
|
386
|
+
}
|
|
387
|
+
else {
|
|
388
|
+
if (!progressHook.includes("EventSource")) {
|
|
389
|
+
errors.push("useImportProgress should use EventSource for SSE connection");
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
return {
|
|
393
|
+
name: "SSE Progress Streaming",
|
|
394
|
+
passed: errors.length === 0,
|
|
395
|
+
errors,
|
|
396
|
+
warnings,
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Check 9: AI-Based Catalog Matching
|
|
401
|
+
*/
|
|
402
|
+
function checkAiCatalogMatching() {
|
|
403
|
+
const errors = [];
|
|
404
|
+
const warnings = [];
|
|
405
|
+
const aiMatcher = readFile("lib/ai-catalog-matcher.ts");
|
|
406
|
+
if (!aiMatcher) {
|
|
407
|
+
warnings.push("Missing lib/ai-catalog-matcher.ts for AI-based catalog matching");
|
|
408
|
+
}
|
|
409
|
+
else {
|
|
410
|
+
if (!aiMatcher.includes("findCatalogMatch")) {
|
|
411
|
+
errors.push("ai-catalog-matcher.ts missing findCatalogMatch function");
|
|
412
|
+
}
|
|
413
|
+
if (!aiMatcher.includes("confidence")) {
|
|
414
|
+
warnings.push("ai-catalog-matcher.ts should use confidence scoring for matches");
|
|
415
|
+
}
|
|
416
|
+
if (!aiMatcher.includes("normalizeForMatch")) {
|
|
417
|
+
warnings.push("ai-catalog-matcher.ts should normalize strings for comparison");
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
return {
|
|
421
|
+
name: "AI-Based Catalog Matching",
|
|
422
|
+
passed: errors.length === 0,
|
|
423
|
+
errors,
|
|
424
|
+
warnings,
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Run all import workflow checks
|
|
429
|
+
*/
|
|
430
|
+
async function run() {
|
|
431
|
+
console.log(`\n${console_chars_1.emoji.rocket} Starting Import Workflow Validation...\n`);
|
|
432
|
+
console.log(`${console_chars_1.emoji.robot} IMPORT WORKFLOW VALIDATION`);
|
|
433
|
+
console.log("━".repeat(80));
|
|
434
|
+
const checks = [
|
|
435
|
+
checkRetryLogic,
|
|
436
|
+
checkPartialImageSuccess,
|
|
437
|
+
checkImageTimeouts,
|
|
438
|
+
checkBatchSizes,
|
|
439
|
+
checkSkuNormalization,
|
|
440
|
+
checkPreProcessedImageFlow,
|
|
441
|
+
checkProgressPersistence,
|
|
442
|
+
checkSseProgressStreaming,
|
|
443
|
+
checkAiCatalogMatching,
|
|
444
|
+
];
|
|
445
|
+
const results = checks.map((check) => check());
|
|
446
|
+
const passed = results.filter((r) => r.passed);
|
|
447
|
+
const failed = results.filter((r) => !r.passed);
|
|
448
|
+
// Display results
|
|
449
|
+
if (passed.length > 0) {
|
|
450
|
+
console.log(`\n${console_chars_1.emoji.success} PASSED CHECKS (${passed.length})`);
|
|
451
|
+
console.log("─".repeat(60));
|
|
452
|
+
for (const result of passed) {
|
|
453
|
+
console.log(` ${console_chars_1.emoji.success} ${result.name}`);
|
|
454
|
+
for (const warning of result.warnings) {
|
|
455
|
+
console.log(` ${console_chars_1.emoji.warning} ${warning}`);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
if (failed.length > 0) {
|
|
460
|
+
console.log(`\n${console_chars_1.emoji.error} FAILED CHECKS (${failed.length})`);
|
|
461
|
+
console.log("━".repeat(60));
|
|
462
|
+
for (const result of failed) {
|
|
463
|
+
console.log(` ${console_chars_1.emoji.error} ${result.name}`);
|
|
464
|
+
for (const error of result.errors) {
|
|
465
|
+
console.log(` ${console_chars_1.emoji.bullet} ${error}`);
|
|
466
|
+
}
|
|
467
|
+
for (const warning of result.warnings) {
|
|
468
|
+
console.log(` ${console_chars_1.emoji.warning} ${warning}`);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
// Summary
|
|
473
|
+
const totalWarnings = results.reduce((sum, r) => sum + r.warnings.length, 0);
|
|
474
|
+
console.log(`\n${console_chars_1.emoji.chart} SUMMARY`);
|
|
475
|
+
console.log("━".repeat(60));
|
|
476
|
+
console.log(` ${console_chars_1.emoji.bullet} Passed: ${passed.length}/${results.length}`);
|
|
477
|
+
console.log(` ${console_chars_1.emoji.bullet} Failed: ${failed.length}/${results.length}`);
|
|
478
|
+
console.log(` ${console_chars_1.emoji.bullet} Warnings: ${totalWarnings}`);
|
|
479
|
+
// Workflow reminder
|
|
480
|
+
console.log(`\n${console_chars_1.emoji.book} IMPORT WORKFLOW BEST PRACTICES`);
|
|
481
|
+
console.log("━".repeat(80));
|
|
482
|
+
console.log(`
|
|
483
|
+
${console_chars_1.emoji.target} Retry Logic:
|
|
484
|
+
1. Use withRetry() for transient failures (network, rate limits, 5xx)
|
|
485
|
+
2. Exponential backoff: 1s → 2s → 4s delays
|
|
486
|
+
3. Max 3 retry attempts
|
|
487
|
+
|
|
488
|
+
${console_chars_1.emoji.lightning} Partial Image Success:
|
|
489
|
+
1. Allow import if at least 1 image uploads successfully
|
|
490
|
+
2. Only block when ALL images fail
|
|
491
|
+
3. Log warnings for partial failures
|
|
492
|
+
|
|
493
|
+
${console_chars_1.emoji.clock} Timeouts:
|
|
494
|
+
1. 30 seconds for image download
|
|
495
|
+
2. 60 seconds for image processing
|
|
496
|
+
3. Graceful degradation on timeout
|
|
497
|
+
|
|
498
|
+
${console_chars_1.emoji.stack} Batch Processing:
|
|
499
|
+
1. Batch size of 5 products for error isolation
|
|
500
|
+
2. One timeout only affects 5 products, not 20
|
|
501
|
+
3. Process images in parallel within batches
|
|
502
|
+
|
|
503
|
+
${console_chars_1.emoji.search} Duplicate Detection:
|
|
504
|
+
1. Normalize SKUs before comparison (lowercase, remove special chars)
|
|
505
|
+
2. Check for existing catalog entries with AI matching
|
|
506
|
+
3. Use confidence threshold (85%) for catalog matches
|
|
507
|
+
`);
|
|
508
|
+
if (failed.length > 0) {
|
|
509
|
+
console.log(`\n${console_chars_1.emoji.bell} BUILD BLOCKED: ${failed.length} critical issues found`);
|
|
510
|
+
process.exit(1);
|
|
511
|
+
}
|
|
512
|
+
console.log(`\n${console_chars_1.emoji.success} Import workflow validation passed\n`);
|
|
513
|
+
}
|
|
514
|
+
// Allow direct execution
|
|
515
|
+
if (require.main === module) {
|
|
516
|
+
run().catch(console.error);
|
|
517
|
+
}
|
|
518
|
+
//# sourceMappingURL=import-workflow-validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import-workflow-validation.js","sourceRoot":"","sources":["../../../src/checks/card-processing/import-workflow-validation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* Turbopack Prisma Computed Property Preflight (BLOCKING)
|
|
4
|
+
*
|
|
5
|
+
* Detects computed property names in Prisma `where` clauses that can get
|
|
6
|
+
* mangled by Turbopack during build, resulting in "column not found" errors.
|
|
7
|
+
*
|
|
8
|
+
* Problem Pattern:
|
|
9
|
+
* const field = resolveCatalogIdField(productType);
|
|
10
|
+
* await prisma.coreListings.findMany({
|
|
11
|
+
* where: {
|
|
12
|
+
* [field]: catalogId, // Turbopack mangles `field` -> "_field" -> undefined
|
|
13
|
+
* }
|
|
14
|
+
* });
|
|
15
|
+
*
|
|
16
|
+
* Safe Pattern:
|
|
17
|
+
* // Use explicit property names with switch statement
|
|
18
|
+
* let catalogWhere = {};
|
|
19
|
+
* switch (productType) {
|
|
20
|
+
* case ProductType.SPORTS_CARD:
|
|
21
|
+
* catalogWhere = { sportsCardCatalogId: catalogId };
|
|
22
|
+
* break;
|
|
23
|
+
* }
|
|
24
|
+
* await prisma.coreListings.findMany({
|
|
25
|
+
* where: { ...baseWhere, ...catalogWhere }
|
|
26
|
+
* });
|
|
27
|
+
*
|
|
28
|
+
* Why this matters:
|
|
29
|
+
* - Turbopack's minification can mangle computed property key variable names
|
|
30
|
+
* - Results in Prisma runtime error: "column '(not available)' does not exist"
|
|
31
|
+
* - Breaks production builds silently - works in dev but fails in prod
|
|
32
|
+
*
|
|
33
|
+
* Usage:
|
|
34
|
+
* pnpm preflight turbopack/prisma-computed-property
|
|
35
|
+
* pnpm preflight turbopack/prisma-computed-property --verbose
|
|
36
|
+
*/
|
|
37
|
+
export declare const id = "turbopack/prisma-computed-property";
|
|
38
|
+
export declare const name = "Turbopack Prisma Computed Property Safety";
|
|
39
|
+
export declare const category = "turbopack";
|
|
40
|
+
export declare const blocking = true;
|
|
41
|
+
export declare const description = "Detects computed property names in Prisma where clauses that may cause Turbopack mangling";
|
|
42
|
+
export declare const tags: string[];
|
|
43
|
+
export declare const requires: any[];
|
|
44
|
+
export declare function run(): Promise<void>;
|
|
45
|
+
//# sourceMappingURL=prisma-computed-property.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prisma-computed-property.d.ts","sourceRoot":"","sources":["../../../src/checks/turbopack/prisma-computed-property.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAOH,eAAO,MAAM,EAAE,uCAAuC,CAAC;AACvD,eAAO,MAAM,IAAI,8CAA8C,CAAC;AAChE,eAAO,MAAM,QAAQ,cAAc,CAAC;AACpC,eAAO,MAAM,QAAQ,OAAO,CAAC;AAC7B,eAAO,MAAM,WAAW,8FAA8F,CAAC;AACvH,eAAO,MAAM,IAAI,UAAmD,CAAC;AACrE,eAAO,MAAM,QAAQ,OAAK,CAAC;AAqJ3B,wBAAsB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CA8HzC"}
|