From 62c30420fa1409cfe5f24304b5d2c6110fc16e1d Mon Sep 17 00:00:00 2001 From: Torben Sorensen Date: Tue, 2 Dec 2025 20:28:28 -0800 Subject: [PATCH] one lazy ai --- src/routes/ai.test.ts | 42 ------------------------------------------ src/routes/ai.ts | 40 ---------------------------------------- 2 files changed, 82 deletions(-) diff --git a/src/routes/ai.test.ts b/src/routes/ai.test.ts index 55bfed8d..41097960 100644 --- a/src/routes/ai.test.ts +++ b/src/routes/ai.test.ts @@ -58,48 +58,6 @@ describe('AI Routes (/api/ai)', () => { }); }); - describe('POST /process-flyer', () => { - it('should process an uploaded flyer image and return extracted data', async () => { - // Arrange: - // 1. Define the mock data the AI service will "extract". - const mockExtractedData = { - store_name: 'Test Store', - items: [{ item: 'Test Item', price_display: '$1.99' }], - } as Awaited>; - mockedAiService.extractCoreDataFromFlyerImage.mockResolvedValue(mockExtractedData); - - // 2. Define the other form fields that are sent along with the file. - const mockMasterItems = [{ master_item_id: 1, item_name: 'Milk' }]; - - // 3. Define the path to a dummy file to upload. - // The path is resolved from the current file's directory (`src/routes`) to the assets directory. - const imagePath = path.resolve(__dirname, '../tests/assets/test-flyer-image.jpg'); - - // Act: - // Use supertest to build the multipart/form-data request. - const response = await supertest(app) - .post('/api/ai/process-flyer') - .field('masterItems', JSON.stringify(mockMasterItems)) // Attach regular form fields - .attach('flyerImages', imagePath); // Attach the file for upload - - // Assert: - // 1. Check for a successful HTTP status. - expect(response.status).toBe(200); - - // 2. Verify the AI service was called correctly by the route handler. - // Multer adds properties like 'path' to the file object. We check that the service - // received an array of files with these properties. - expect(mockedAiService.extractCoreDataFromFlyerImage).toHaveBeenCalledTimes(1); - expect(mockedAiService.extractCoreDataFromFlyerImage).toHaveBeenCalledWith( - expect.arrayContaining([expect.objectContaining({ mimetype: 'image/jpeg' })]), - mockMasterItems - ); - - // 3. Ensure the response body contains the data we mocked. - expect(response.body.data).toEqual(mockExtractedData); - }); - }); - describe('POST /flyers/process', () => { const imagePath = path.resolve(__dirname, '../tests/assets/test-flyer-image.jpg'); const mockDataPayload = { diff --git a/src/routes/ai.ts b/src/routes/ai.ts index 2f11ff32..a59c0d2d 100644 --- a/src/routes/ai.ts +++ b/src/routes/ai.ts @@ -127,47 +127,7 @@ router.get('/jobs/:jobId/status', async (req, res) => { res.json({ id: job.id, state, progress, returnValue, failedReason }); }); -/** - * This endpoint processes a flyer using AI. It uses `optionalAuth` middleware to allow - * both authenticated and anonymous users to upload flyers. - */ -router.post('/process-flyer', optionalAuth, uploadToDisk.array('flyerImages'), async (req: Request, res: Response, next: NextFunction) => { - try { - const files = req.files as Express.Multer.File[]; - const totalSize = files ? files.reduce((acc, file) => acc + file.size, 0) : 0; - const totalSizeMB = (totalSize / (1024 * 1024)).toFixed(2); - // --- AI ROUTE DEBUG LOGGING --- - logger.debug('[API /ai/process-flyer] Request received.'); - logger.debug(`[API /ai/process-flyer] Files received: ${files ? files.length : 0}. Total size: ${totalSizeMB} MB.`); - // --- END DEBUG LOGGING --- - - if (!req.files || !Array.isArray(req.files) || req.files.length === 0) { - return res.status(400).json({ message: 'Flyer image files are required.' }); - } - - const masterItems = JSON.parse(req.body.masterItems); - const imagePaths = (req.files as Express.Multer.File[]).map(file => ({ - path: file.path, - mimetype: file.mimetype - })); - - logger.debug(`[API /ai/process-flyer] Processing image paths:`, { imagePaths }); - - const user = req.user as UserProfile | undefined; - const logIdentifier = user ? `user ID: ${user.user_id}` : 'anonymous user'; - - logger.info(`Starting AI flyer data extraction for ${imagePaths.length} image(s) for ${logIdentifier}.`); - - const extractedData = await aiService.extractCoreDataFromFlyerImage(imagePaths, masterItems); - logger.info(`Completed AI flyer data extraction. Found ${extractedData.items.length} items.`); - - res.status(200).json({ data: extractedData }); - } catch (error) { - logger.error('Error in /api/ai/process-flyer endpoint:', { error }); - next(error); - } -}); /** * This endpoint saves the processed flyer data to the database. It is the final step