> flyer-crawler@0.9.84 test:integration > node scripts/check-linux.js && cross-env NODE_ENV=test tsx --max-old-space-size=8192 ./node_modules/vitest/vitest.mjs run --project integration -c vitest.config.integration.ts [DEBUG] Loading vitest.config.integration.ts... [DEBUG] Merging with base vite config, but excluding its "test" configuration. [DEBUG] --- INTEGRATION CONFIG SETUP --- [DEBUG] Stripped "test" config. Original test config existed: true [DEBUG] Does baseViteConfig have "test"? false [DEBUG] Base vite config keys: [ 'plugins', 'server', 'resolve' ] [DEBUG] Integration Final Config - INCLUDE: [ 'src/tests/integration/**/*.test.{ts,tsx}' ] [DEBUG] Integration Final Config - EXCLUDE: [] [DEBUG] ----------------------------------  RUN  v4.0.16 /app --- [EXECUTION PROOF] tailwind.config.js is being loaded. --- --- [EXECUTION PROOF] postcss.config.js is being loaded. --- [POSTCSS] Attempting to use Tailwind config at: /app/tailwind.config.js [POSTCSS] Imported tailwind.config.js object: { "content": [ "./index.html", "./src/**/*.{js,ts,jsx,tsx}" ] } [SETUP] Created storage directory: /app/flyer-images --- [PID:12017] Running Integration Test GLOBAL Setup --- [SETUP] STORAGE_PATH: /app/flyer-images [SETUP] REDIS_URL: redis://redis:6379 [SETUP] REDIS_PASSWORD is set: false [SETUP] About to call cleanAllQueues()... [PID:12017] [QUEUE CLEANUP] Starting BullMQ queue cleanup... Sourcemap for "/app/node_modules/bullmq/dist/esm/index.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/classes/index.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/classes/async-fifo-queue.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/classes/backoffs.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/classes/child.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/enums/index.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/enums/child-command.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/enums/error-code.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/enums/parent-command.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/enums/metrics-time.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/enums/telemetry-attributes.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/classes/child-pool.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/classes/child-processor.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/utils/index.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/classes/errors/index.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/classes/errors/delayed-error.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/classes/errors/rate-limit-error.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/classes/errors/unrecoverable-error.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/classes/errors/waiting-children-error.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/classes/errors/waiting-error.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/classes/flow-producer.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/classes/job.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/utils/create-scripts.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/classes/scripts.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/version.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/classes/queue-keys.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/classes/redis-connection.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/index.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/addDelayedJob-6.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/addJobScheduler-11.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/addLog-2.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/addParentJob-6.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/addPrioritizedJob-9.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/addRepeatableJob-2.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/addStandardJob-9.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/changeDelay-4.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/changePriority-7.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/cleanJobsInSet-3.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/drain-5.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/extendLock-2.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/extendLocks-1.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/getCounts-1.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/getCountsPerPriority-4.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/getDependencyCounts-4.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/getJobScheduler-1.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/getMetrics-2.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/getRanges-1.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/getRateLimitTtl-2.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/getState-8.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/getStateV2-8.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/isFinished-3.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/isJobInList-1.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/isMaxed-2.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/moveJobFromActiveToWait-9.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/moveJobsToWait-8.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/moveStalledJobsToWait-8.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/moveToActive-11.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/moveToDelayed-8.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/moveToFinished-14.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/moveToWaitingChildren-7.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/obliterate-2.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/paginate-1.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/pause-7.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/promote-9.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/releaseLock-1.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/removeChildDependency-1.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/removeDeduplicationKey-1.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/removeJob-2.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/removeJobScheduler-3.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/removeRepeatable-3.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/removeUnprocessedChildren-2.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/reprocessJob-8.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/retryJob-11.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/saveStacktrace-1.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/updateData-1.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/updateJobScheduler-12.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/updateProgress-3.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/scripts/updateRepeatableJobMillis-1.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/classes/job-scheduler.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/classes/queue-base.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/classes/lock-manager.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/classes/queue-events.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/classes/queue-events-producer.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/classes/queue-getters.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/classes/queue.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/classes/repeat.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/classes/sandbox.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/classes/worker.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/interfaces/index.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/interfaces/queue-options.js" points to missing source files Sourcemap for "/app/node_modules/bullmq/dist/esm/types/index.js" points to missing source files [QUEUE CLEANUP] Successfully imported queue modules {"level":30,"time":1768077901653,"pid":12017,"hostname":"27443fa088eb","msg":"[Redis] Connection established successfully."} [QUEUE CLEANUP] Queue "flyer-processing" before cleanup: {"active":0,"completed":8,"delayed":0,"failed":0,"paused":0,"prioritized":0,"waiting":0,"waiting-children":0} ✅ [QUEUE CLEANUP] Cleaned queue: flyer-processing [QUEUE CLEANUP] Queue "file-cleanup" before cleanup: {"active":0,"completed":0,"delayed":0,"failed":0,"paused":0,"prioritized":0,"waiting":0,"waiting-children":0} ✅ [QUEUE CLEANUP] Cleaned queue: file-cleanup [QUEUE CLEANUP] Queue "email-sending" before cleanup: {"active":0,"completed":0,"delayed":0,"failed":0,"paused":0,"prioritized":0,"waiting":0,"waiting-children":0} ✅ [QUEUE CLEANUP] Cleaned queue: email-sending [QUEUE CLEANUP] Queue "analytics-reporting" before cleanup: {"active":0,"completed":0,"delayed":0,"failed":0,"paused":0,"prioritized":0,"waiting":0,"waiting-children":0} ✅ [QUEUE CLEANUP] Cleaned queue: analytics-reporting [QUEUE CLEANUP] Queue "weekly-analytics-reporting" before cleanup: {"active":0,"completed":0,"delayed":0,"failed":0,"paused":0,"prioritized":0,"waiting":0,"waiting-children":0} ✅ [QUEUE CLEANUP] Cleaned queue: weekly-analytics-reporting [PID:12017] Running database seed script... [QUEUE CLEANUP] Queue "token-cleanup" before cleanup: {"active":0,"completed":0,"delayed":0,"failed":0,"paused":0,"prioritized":0,"waiting":0,"waiting-children":0} ✅ [QUEUE CLEANUP] Cleaned queue: token-cleanup ✅ [PID:12017] [QUEUE CLEANUP] All queues cleaned successfully. [SETUP] cleanAllQueues() completed. {"level":30,"time":1768077915775,"pid":12090,"hostname":"27443fa088eb","msg":"Connected to the database for seeding."} {"level":30,"time":1768077915794,"pid":12090,"hostname":"27443fa088eb","msg":"--- Wiping and rebuilding schema... ---"} {"level":30,"time":1768077916645,"pid":12090,"hostname":"27443fa088eb","msg":"All tables dropped successfully."} {"level":30,"time":1768077941958,"pid":12090,"hostname":"27443fa088eb","msg":"Schema rebuilt and static data seeded successfully from master_schema_rollup.sql."} {"level":30,"time":1768077941959,"pid":12090,"hostname":"27443fa088eb","msg":"--- Seeding Stores... ---"} {"level":30,"time":1768077942005,"pid":12090,"hostname":"27443fa088eb","msg":"Seeded/verified 5 total stores."} {"level":30,"time":1768077942011,"pid":12090,"hostname":"27443fa088eb","msg":"--- Seeding Users & Profiles... ---"} {"level":30,"time":1768077942506,"pid":12090,"hostname":"27443fa088eb","msg":"Seeded admin user (admin@example.com / adminpass)"} {"level":30,"time":1768077942507,"pid":12090,"hostname":"27443fa088eb","msg":"> Role for 34261825-38f4-4bf1-afc6-e5acd0a4cba4 set to 'admin'."} {"level":30,"time":1768077942511,"pid":12090,"hostname":"27443fa088eb","msg":"Seeded regular user (user@example.com / userpass)"} {"level":30,"time":1768077942512,"pid":12090,"hostname":"27443fa088eb","msg":"--- Seeding a Sample Flyer... ---"} {"level":30,"time":1768077942676,"pid":12090,"hostname":"27443fa088eb","msg":"Seeded flyer for Safeway (ID: 1)."} {"level":30,"time":1768077942677,"pid":12090,"hostname":"27443fa088eb","msg":"--- Seeding Flyer Items... ---"} {"level":30,"time":1768077942757,"pid":12090,"hostname":"27443fa088eb","msg":"Seeded 4 items for the Safeway flyer."} {"level":30,"time":1768077942757,"pid":12090,"hostname":"27443fa088eb","msg":"--- Seeding Watched Items... ---"} {"level":30,"time":1768077942771,"pid":12090,"hostname":"27443fa088eb","msg":"Seeded 3 watched items for Test User."} {"level":30,"time":1768077942772,"pid":12090,"hostname":"27443fa088eb","msg":"--- Seeding a Shopping List... ---"} {"level":30,"time":1768077942785,"pid":12090,"hostname":"27443fa088eb","msg":"Seeded shopping list \"Weekly Groceries\" with 3 items for Test User."} {"level":20,"time":1768077942789,"pid":12090,"hostname":"27443fa088eb","msg":"[SEED SCRIPT] Final state of users table after seeding:"} ┌─────────┬────────────────────────────────────────┬─────────────────────┬─────────┐ │ (index) │ user_id │ email │ role │ ├─────────┼────────────────────────────────────────┼─────────────────────┼─────────┤ │ 0 │ '34261825-38f4-4bf1-afc6-e5acd0a4cba4' │ 'admin@example.com' │ 'admin' │ │ 1 │ '63817122-6ba9-4d89-a88f-a90be10ab076' │ 'user@example.com' │ 'user' │ └─────────┴────────────────────────────────────────┴─────────────────────┴─────────┘ {"level":30,"time":1768077944208,"pid":12090,"hostname":"27443fa088eb","msg":"✅ Database seeding completed successfully!"} {"level":30,"time":1768077944213,"pid":12090,"hostname":"27443fa088eb","msg":"Database connection pool closed."} ✅ [PID:12017] Database seed script finished. [PID:12017] Initializing global database pool... {"level":30,"time":1768077944487,"pid":12017,"hostname":"27443fa088eb","msg":"[DB Connection] Creating new PostgreSQL connection pool..."} {"level":30,"time":1768077983129,"pid":12017,"hostname":"27443fa088eb","msg":"[Passport] JWT_SECRET loaded successfully (length: 35)."} {"level":30,"time":1768077998332,"pid":12017,"hostname":"27443fa088eb","msg":"Ensured multer storage directories exist."} Sourcemap for "/app/node_modules/node-cron/dist/esm/node-cron.js" points to missing source files {"level":30,"time":1768078028176,"pid":12017,"hostname":"27443fa088eb","msg":"---------------- [AIService] Constructor Start ----------------"} {"level":30,"time":1768078028177,"pid":12017,"hostname":"27443fa088eb","msg":"[AIService Constructor] Test environment detected. Using internal mock for AI client to prevent real API calls in INTEGRATION TESTS."} {"level":30,"time":1768078028177,"pid":12017,"hostname":"27443fa088eb","msg":"[AIService Constructor] Initializing production rate limiter to 5 RPM."} {"level":30,"time":1768078028178,"pid":12017,"hostname":"27443fa088eb","msg":"---------------- [AIService] Constructor End ----------------"} {"level":30,"time":1768078037911,"pid":12017,"hostname":"27443fa088eb","msg":"All workers started and listening for jobs."} {"level":30,"time":1768078066597,"pid":12017,"hostname":"27443fa088eb","msg":"--- [SERVER PROCESS LOG] DATABASE CONNECTION ---"} ✅ In-process test server started on port 3001 {"level":30,"time":1768078066597,"pid":12017,"hostname":"27443fa088eb","msg":" NODE_ENV: test"} {"level":30,"time":1768078066597,"pid":12017,"hostname":"27443fa088eb","msg":" Host: postgres"} {"level":30,"time":1768078066597,"pid":12017,"hostname":"27443fa088eb","msg":" Port: 5432"} {"level":30,"time":1768078066597,"pid":12017,"hostname":"27443fa088eb","msg":" User: postgres"} {"level":30,"time":1768078066597,"pid":12017,"hostname":"27443fa088eb","msg":" Database: flyer_crawler_dev"} {"level":30,"time":1768078066612,"pid":12017,"hostname":"27443fa088eb","msg":"-----------------------------------------------\n"} {"level":20,"time":1768078066839,"pid":12017,"hostname":"27443fa088eb","request_id":"e7d5e0bc-513c-4085-bcd5-d3f36cede90d","user_id":"00000000-0000-0000-0000-000000000001","ip_address":"::ffff:127.0.0.1","method":"GET","originalUrl":"/api/health/ping","msg":"[Request Logger] INCOMING"} {"level":30,"time":1768078066886,"pid":12017,"hostname":"27443fa088eb","request_id":"e7d5e0bc-513c-4085-bcd5-d3f36cede90d","user_id":"00000000-0000-0000-0000-000000000001","ip_address":"::ffff:127.0.0.1","user_id":"00000000-0000-0000-0000-000000000001","method":"GET","originalUrl":"/api/health/ping","statusCode":200,"statusMessage":"OK","duration":"48.54","msg":"Request completed successfully"} ✅ Backend server is running and responsive. {"level":20,"time":1768078067447,"pid":12017,"hostname":"27443fa088eb","request_id":"de78fcc2-a3a2-4a9f-b8df-673253af1faa","user_id":"00000000-0000-0000-0000-000000000002","ip_address":"::ffff:127.0.0.1","method":"GET","originalUrl":"/api/health","msg":"[Request Logger] INCOMING"} {"level":40,"time":1768078067466,"pid":12017,"hostname":"27443fa088eb","request_id":"de78fcc2-a3a2-4a9f-b8df-673253af1faa","user_id":"00000000-0000-0000-0000-000000000002","ip_address":"::ffff:127.0.0.1","user_id":"00000000-0000-0000-0000-000000000002","method":"GET","originalUrl":"/api/health","statusCode":404,"statusMessage":"Not Found","duration":"18.55","req":{"headers":{"host":"localhost:3001","user-agent":"curl/7.81.0","accept":"*/*"}},"msg":"Request completed with client error"} {"level":20,"time":1768078067544,"pid":12017,"hostname":"27443fa088eb","msg":"[SERVER PROCESS] Users found in DB on startup:"} ┌─────────┬────────────────────────────────────────┬─────────────────────┬─────────┐ │ (index) │ user_id │ email │ role │ ├─────────┼────────────────────────────────────────┼─────────────────────┼─────────┤ │ 0 │ '34261825-38f4-4bf1-afc6-e5acd0a4cba4' │ 'admin@example.com' │ 'admin' │ │ 1 │ '63817122-6ba9-4d89-a88f-a90be10ab076' │ 'user@example.com' │ 'user' │ └─────────┴────────────────────────────────────────┴─────────────────────┴─────────┘ {"level":20,"time":1768078101930,"pid":12017,"hostname":"27443fa088eb","request_id":"732dba63-0788-4f99-8eb5-d124d0750f09","user_id":"00000000-0000-0000-0000-000000000003","ip_address":"::ffff:127.0.0.1","method":"GET","originalUrl":"/api/health","msg":"[Request Logger] INCOMING"} {"level":40,"time":1768078101934,"pid":12017,"hostname":"27443fa088eb","request_id":"732dba63-0788-4f99-8eb5-d124d0750f09","user_id":"00000000-0000-0000-0000-000000000003","ip_address":"::ffff:127.0.0.1","user_id":"00000000-0000-0000-0000-000000000003","method":"GET","originalUrl":"/api/health","statusCode":404,"statusMessage":"Not Found","duration":"4.17","req":{"headers":{"host":"localhost:3001","user-agent":"curl/7.81.0","accept":"*/*"}},"msg":"Request completed with client error"} stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test [TEST SETUP] STORAGE_PATH: /app/flyer-images [TEST SETUP] FRONTEND_URL stubbed to: https://example.com [TEST SETUP] Starting in-process workers... {"level":20,"time":1768078137283,"pid":12017,"hostname":"27443fa088eb","request_id":"6c3841c5-5318-4ae1-b31c-b7890c2a6995","user_id":"00000000-0000-0000-0000-000000000004","ip_address":"::ffff:127.0.0.1","method":"GET","originalUrl":"/api/health","msg":"[Request Logger] INCOMING"} {"level":40,"time":1768078137298,"pid":12017,"hostname":"27443fa088eb","request_id":"6c3841c5-5318-4ae1-b31c-b7890c2a6995","user_id":"00000000-0000-0000-0000-000000000004","ip_address":"::ffff:127.0.0.1","user_id":"00000000-0000-0000-0000-000000000004","method":"GET","originalUrl":"/api/health","statusCode":404,"statusMessage":"Not Found","duration":"15.18","req":{"headers":{"host":"localhost:3001","user-agent":"curl/7.81.0","accept":"*/*"}},"msg":"Request completed with client error"} stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should successfully process a flyer for an AUTHENTICATED user via the background queue [TEST SETUP] Resetting mocks before test execution stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should successfully process a flyer for an AUTHENTICATED user via the background queue [DEBUG] FlyerPersistenceService._setWithTransaction called, replacing withTransaction function [TEST SETUP] withTransaction restored to real implementation via DI stdout | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should successfully process a flyer for an AUTHENTICATED user via the background queue ┌─────────┬────────────────────────────────────────┬─────────────────────┬─────────┐ │ (index) │ user_id │ email │ role │ ├─────────┼────────────────────────────────────────┼─────────────────────┼─────────┤ │ 0 │ '34261825-38f4-4bf1-afc6-e5acd0a4cba4' │ 'admin@example.com' │ 'admin' │ │ 1 │ '63817122-6ba9-4d89-a88f-a90be10ab076' │ 'user@example.com' │ 'user' │ └─────────┴────────────────────────────────────────┴─────────────────────┴─────────┘ {"level":20,"time":1768078170305,"pid":12017,"hostname":"27443fa088eb","request_id":"5352a9fe-39ea-417d-8631-66f94fc10ae6","user_id":"00000000-0000-0000-0000-000000000005","ip_address":"::ffff:127.0.0.1","method":"GET","originalUrl":"/api/health","msg":"[Request Logger] INCOMING"} {"level":40,"time":1768078170308,"pid":12017,"hostname":"27443fa088eb","request_id":"5352a9fe-39ea-417d-8631-66f94fc10ae6","user_id":"00000000-0000-0000-0000-000000000005","ip_address":"::ffff:127.0.0.1","user_id":"00000000-0000-0000-0000-000000000005","method":"GET","originalUrl":"/api/health","statusCode":404,"statusMessage":"Not Found","duration":"3.31","req":{"headers":{"host":"localhost:3001","user-agent":"curl/7.81.0","accept":"*/*"}},"msg":"Request completed with client error"} stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should successfully process a flyer for an AUTHENTICATED user via the background queue [TEST START] runBackgroundProcessingTest. User: auth-flyer-user-1768078169823@example.com [TEST] about to read test-flyer-image.jpg stdout | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should successfully process a flyer for an AUTHENTICATED user via the background queue [DEBUG] generateFileChecksum processing file: name="test-flyer-image-1768078170398.jpg", type="image/jpeg", size=193338 stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should successfully process a flyer for an AUTHENTICATED user via the background queue [TEST] mockImageFile created with uniqueFileName: test-flyer-image-1768078170398.jpg [TEST DATA] Generated checksum for test: 5be56021fc4f1b5f28bdefafee8be518c90d3b63b9ba0555c2c7e0fb9cbd4a64 [TEST] createdFilesPaths after 1st push: [ '/app/flyer-images/test-flyer-image-1768078170398.jpg' ] [TEST ACTION] Uploading file with baseUrl: https://example.com stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should successfully process a flyer for an AUTHENTICATED user via the background queue [DEBUG] aiService.enqueueFlyerProcessing resolved baseUrl: "https://example.com" stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should successfully process a flyer for an AUTHENTICATED user via the background queue [TEST RESPONSE] Upload status: 202 [TEST RESPONSE] Upload body: {"success":true,"data":{"message":"Flyer accepted for processing.","jobId":"1"}} stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should successfully process a flyer for an AUTHENTICATED user via the background queue [WORKER DEBUG] ProcessingService: Calling fileHandler.prepareImageInputs for /app/flyer-images/flyerFile-test-flyer-image.jpg [WORKER DEBUG] FlyerFileHandler: prepareImageInputs called for /app/flyer-images/flyerFile-test-flyer-image.jpg [WORKER DEBUG] FlyerFileHandler: Detected extension: .jpg stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should successfully process a flyer for an AUTHENTICATED user via the background queue [TEST POLL] Job 1 current state: active stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should successfully process a flyer for an AUTHENTICATED user via the background queue [WORKER DEBUG] ProcessingService: fileHandler returned 1 images. stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should successfully process a flyer for an AUTHENTICATED user via the background queue [WORKER DEBUG] ProcessingService: Calling aiProcessor.extractAndValidateData [WORKER DEBUG] FlyerAiProcessor: extractAndValidateData called with 1 images stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should successfully process a flyer for an AUTHENTICATED user via the background queue [WORKER DEBUG] FlyerAiProcessor: Merged AI Data: { "store_name": "Mock Store", "valid_from": "2025-01-01", "valid_to": "2025-01-07", "store_address": "123 Mock St", "items": [ { "item": "Mocked Integration Item", "price_display": "$1.99", "price_in_cents": 199, "quantity": "each", "category_name": "Mock Category" } ] } stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should successfully process a flyer for an AUTHENTICATED user via the background queue [WORKER DEBUG] ProcessingService: aiProcessor returned data for store: Mock Store stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should successfully process a flyer for an AUTHENTICATED user via the background queue [WORKER DEBUG] ProcessingService: Generating icon from /app/flyer-images/flyerFile-test-flyer-image-processed.jpeg to /app/flyer-images/icons stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should successfully process a flyer for an AUTHENTICATED user via the background queue [WORKER DEBUG] ProcessingService: Icon generated: mock-icon-safe.webp [DEBUG] FlyerProcessingService resolved baseUrl: "https://example.com" (job.data.baseUrl: "https://example.com", env.FRONTEND_URL: "https://example.com") [DEBUG] FlyerProcessingService calling transformer with: { originalFileName: 'test-flyer-image-1768078170398.jpg', imageFileName: 'flyerFile-test-flyer-image-processed.jpeg', iconFileName: 'mock-icon-safe.webp', checksum: '5be56021fc4f1b5f28bdefafee8be518c90d3b63b9ba0555c2c7e0fb9cbd4a64', baseUrl: 'https://example.com' } [DEBUG] FlyerDataTransformer.transform called with baseUrl: https://example.com [DEBUG] FlyerDataTransformer._buildUrls inputs: { imageFileName: 'flyerFile-test-flyer-image-processed.jpeg', iconFileName: 'mock-icon-safe.webp', baseUrl: 'https://example.com' } [DEBUG] FlyerDataTransformer._buildUrls finalBaseUrl resolved to: https://example.com [DEBUG] FlyerDataTransformer._buildUrls constructed: { imageUrl: 'https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg', iconUrl: 'https://example.com/flyer-images/icons/mock-icon-safe.webp' } stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should successfully process a flyer for an AUTHENTICATED user via the background queue [DEBUG] FlyerProcessingService transformer output URLs: { imageUrl: 'https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg', iconUrl: 'https://example.com/flyer-images/icons/mock-icon-safe.webp' } [DEBUG] Full Flyer Data to be saved: { "file_name": "test-flyer-image-1768078170398.jpg", "image_url": "https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg", "icon_url": "https://example.com/flyer-images/icons/mock-icon-safe.webp", "checksum": "5be56021fc4f1b5f28bdefafee8be518c90d3b63b9ba0555c2c7e0fb9cbd4a64", "store_name": "Mock Store", "valid_from": "2025-01-01", "valid_to": "2025-01-07", "store_address": "123 Mock St", "item_count": 1, "uploaded_by": "e94160ac-a2a2-4e1e-a05f-512ec544f81d", "status": "processed" } stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should successfully process a flyer for an AUTHENTICATED user via the background queue [DEBUG] FlyerPersistenceService.saveFlyer called, about to invoke withTransaction [DEBUG] withTransaction function name: withTransaction stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should successfully process a flyer for an AUTHENTICATED user via the background queue [DB DEBUG] FlyerRepository.insertFlyer called with: { "file_name": "test-flyer-image-1768078170398.jpg", "image_url": "https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg", "icon_url": "https://example.com/flyer-images/icons/mock-icon-safe.webp", "checksum": "5be56021fc4f1b5f28bdefafee8be518c90d3b63b9ba0555c2c7e0fb9cbd4a64", "store_name": "Mock Store", "valid_from": "2025-01-01", "valid_to": "2025-01-07", "store_address": "123 Mock St", "item_count": 1, "uploaded_by": "e94160ac-a2a2-4e1e-a05f-512ec544f81d", "status": "processed", "store_id": 6 } [DB DEBUG] Final URLs for insert: { imageUrl: 'https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg', iconUrl: 'https://example.com/flyer-images/icons/mock-icon-safe.webp' } stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should successfully process a flyer for an AUTHENTICATED user via the background queue [TEST POLL] Job 1 current state: completed stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should successfully process a flyer for an ANONYMOUS user via the background queue [TEST SETUP] Resetting mocks before test execution stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should successfully process a flyer for an ANONYMOUS user via the background queue [DEBUG] FlyerPersistenceService._setWithTransaction called, replacing withTransaction function [TEST SETUP] withTransaction restored to real implementation via DI stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should successfully process a flyer for an ANONYMOUS user via the background queue [TEST START] runBackgroundProcessingTest. User: ANONYMOUS [TEST] about to read test-flyer-image.jpg stdout | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should successfully process a flyer for an ANONYMOUS user via the background queue [DEBUG] generateFileChecksum processing file: name="test-flyer-image-1768078173583.jpg", type="image/jpeg", size=193338 stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should successfully process a flyer for an ANONYMOUS user via the background queue [TEST] mockImageFile created with uniqueFileName: test-flyer-image-1768078173583.jpg [TEST DATA] Generated checksum for test: 66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34 [TEST] createdFilesPaths after 1st push: [ '/app/flyer-images/test-flyer-image-1768078170398.jpg', '/app/flyer-images/icons/icon-test-flyer-image-1768078170398.webp', '/app/flyer-images/flyerFile-test-flyer-image-processed.jpeg', '/app/flyer-images/test-flyer-image-1768078173583.jpg' ] [TEST ACTION] Uploading file with baseUrl: https://example.com stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should successfully process a flyer for an ANONYMOUS user via the background queue [DEBUG] aiService.enqueueFlyerProcessing resolved baseUrl: "https://example.com" {"level":30,"time":1768078173637,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Picked up flyer processing job."} stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should successfully process a flyer for an ANONYMOUS user via the background queue [TEST RESPONSE] Upload status: 202 [TEST RESPONSE] Upload body: {"success":true,"data":{"message":"Flyer accepted for processing.","jobId":"2"}} [WORKER DEBUG] ProcessingService: Calling fileHandler.prepareImageInputs for /app/flyer-images/flyerFile-test-flyer-image.jpg [WORKER DEBUG] FlyerFileHandler: prepareImageInputs called for /app/flyer-images/flyerFile-test-flyer-image.jpg [WORKER DEBUG] FlyerFileHandler: Detected extension: .jpg {"level":30,"time":1768078173642,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","from":"/app/flyer-images/flyerFile-test-flyer-image.jpg","to":"/app/flyer-images/flyerFile-test-flyer-image-processed.jpeg","msg":"Processing JPEG to strip EXIF data."} stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should successfully process a flyer for an ANONYMOUS user via the background queue [TEST POLL] Job 2 current state: active [WORKER DEBUG] ProcessingService: fileHandler returned 1 images. {"level":30,"time":1768078173805,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Starting image optimization for 1 images."} {"level":30,"time":1768078174114,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Image optimization complete."} [WORKER DEBUG] ProcessingService: Calling aiProcessor.extractAndValidateData [WORKER DEBUG] FlyerAiProcessor: extractAndValidateData called with 1 images {"level":30,"time":1768078174117,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Starting AI data extraction for 1 pages."} {"level":20,"time":1768078174161,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Retrieved 143 master items for AI matching."} {"level":30,"time":1768078174161,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Processing 1 pages in 1 batches (Batch Size: 4)."} {"level":30,"time":1768078174161,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Processing batch 1/1 (1 pages)..."} {"level":30,"time":1768078174161,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[extractCoreDataFromFlyerImage] Entering method with 1 image(s)."} {"level":30,"time":1768078174169,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[aiService.server] Total base64 image data size for Gemini: 0.21 MB"} [WORKER DEBUG] FlyerAiProcessor: Merged AI Data: { "store_name": "Mock Store from AIService", "valid_from": "2025-01-01", "valid_to": "2025-01-07", "store_address": "123 Mock St", "items": [ { "item": "Mocked Integration Item", "price_display": "$1.99", "price_in_cents": 199, "quantity": "each", "category_name": "Mock Category", "master_item_id": null } ] } [WORKER DEBUG] ProcessingService: aiProcessor returned data for store: Mock Store from AIService {"level":20,"time":1768078174169,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[extractCoreDataFromFlyerImage] PRE-RATE-LIMITER: Preparing to call Gemini API."} {"level":20,"time":1768078174170,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[extractCoreDataFromFlyerImage] INSIDE-RATE-LIMITER: Executing generateContent call."} {"level":30,"time":1768078174171,"pid":12017,"hostname":"27443fa088eb","msg":"[AIService] Mock generateContent called in test environment."} {"level":20,"time":1768078174171,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[extractCoreDataFromFlyerImage] POST-RATE-LIMITER: AI call completed."} {"level":30,"time":1768078174171,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[aiService.server] Gemini API call for flyer processing completed in 1.60 ms."} {"level":20,"time":1768078174171,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[aiService.server] Raw Gemini response text (first 500 chars): {\"store_name\":\"Mock Store from AIService\",\"valid_from\":\"2025-01-01\",\"valid_to\":\"2025-01-07\",\"store_address\":\"123 Mock St\",\"items\":[{\"item\":\"Mocked Integration Item\",\"price_display\":\"$1.99\",\"price_in_cents\":199,\"quantity\":\"each\",\"category_name\":\"Mock Category\",\"master_item_id\":null}]}"} {"level":20,"time":1768078174172,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","responseText_type":"string","responseText_length":284,"responseText_preview":"{\"store_name\":\"Mock Store from AIService\",\"valid_from\":\"2025-01-01\",\"valid_to\":\"2025-01-07\",\"store_address\":\"123 Mock St\",\"items\":[{\"item\":\"Mocked Integration Item\",\"price_display\":\"$1.99\",\"price_in_c","msg":"[_parseJsonFromAiResponse] Starting JSON parsing."} {"level":20,"time":1768078174172,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[_parseJsonFromAiResponse] No markdown code block found. Using raw response text."} {"level":20,"time":1768078174172,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","firstBrace":0,"firstBracket":130,"msg":"[_parseJsonFromAiResponse] Searching for start of JSON."} {"level":20,"time":1768078174172,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","sliceLength":284,"msg":"[_parseJsonFromAiResponse] Extracted JSON slice for parsing."} {"level":30,"time":1768078174172,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[_parseJsonFromAiResponse] Successfully parsed JSON from AI response."} {"level":30,"time":1768078174172,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[extractCoreDataFromFlyerImage] Successfully processed flyer data for store: Mock Store from AIService. Exiting method."} {"level":30,"time":1768078174172,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Batch processing complete. Total items extracted: 1"} {"level":30,"time":1768078174183,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"AI extracted 1 items. Needs Review: false"} [WORKER DEBUG] ProcessingService: Generating icon from /app/flyer-images/flyerFile-test-flyer-image-processed.jpeg to /app/flyer-images/icons {"level":20,"time":1768078174190,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","sourcePath":"/app/flyer-images/flyerFile-test-flyer-image-processed.jpeg","outputPath":"/app/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp","msg":"Starting icon generation."} [WORKER DEBUG] ProcessingService: Icon generated: icon-flyerFile-test-flyer-image-processed.webp {"level":30,"time":1768078174304,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Successfully generated icon: /app/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp"} [DEBUG] generateFlyerIcon returning: icon-flyerFile-test-flyer-image-processed.webp [DEBUG] FlyerProcessingService resolved baseUrl: "https://example.com" (job.data.baseUrl: "https://example.com", env.FRONTEND_URL: "https://example.com") [DEBUG] FlyerProcessingService calling transformer with: { originalFileName: 'test-flyer-image-1768078173583.jpg', imageFileName: 'flyerFile-test-flyer-image-processed.jpeg', iconFileName: 'icon-flyerFile-test-flyer-image-processed.webp', checksum: '66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34', baseUrl: 'https://example.com' } [DEBUG] FlyerDataTransformer.transform called with baseUrl: https://example.com [DEBUG] FlyerDataTransformer._buildUrls inputs: { imageFileName: 'flyerFile-test-flyer-image-processed.jpeg', iconFileName: 'icon-flyerFile-test-flyer-image-processed.webp', baseUrl: 'https://example.com' } [DEBUG] FlyerDataTransformer._buildUrls finalBaseUrl resolved to: https://example.com [DEBUG] FlyerDataTransformer._buildUrls constructed: { imageUrl: 'https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg', iconUrl: 'https://example.com/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp' } [DEBUG] FlyerProcessingService transformer output URLs: { imageUrl: 'https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg', iconUrl: 'https://example.com/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp' } [DEBUG] Full Flyer Data to be saved: { "file_name": "test-flyer-image-1768078173583.jpg", "image_url": "https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg", "icon_url": "https://example.com/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp", "checksum": "66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34", "store_name": "Mock Store from AIService", "valid_from": "2025-01-01", "valid_to": "2025-01-07", "store_address": "123 Mock St", "item_count": 1, "uploaded_by": null, "status": "processed" } {"level":30,"time":1768078174309,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Starting data transformation from AI output to database format."} {"level":20,"time":1768078174309,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","imageFileName":"flyerFile-test-flyer-image-processed.jpeg","iconFileName":"icon-flyerFile-test-flyer-image-processed.webp","baseUrl":"https://example.com","msg":"Building URLs"} {"level":20,"time":1768078174310,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","imageUrl":"https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg","iconUrl":"https://example.com/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp","msg":"Constructed URLs"} {"level":30,"time":1768078174312,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","itemCount":1,"storeName":"Mock Store from AIService","msg":"Data transformation complete."} [DEBUG] FlyerPersistenceService.saveFlyer called, about to invoke withTransaction [DEBUG] withTransaction function name: withTransaction [DB DEBUG] FlyerRepository.insertFlyer called with: { "file_name": "test-flyer-image-1768078173583.jpg", "image_url": "https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg", "icon_url": "https://example.com/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp", "checksum": "66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34", "store_name": "Mock Store from AIService", "valid_from": "2025-01-01", "valid_to": "2025-01-07", "store_address": "123 Mock St", "item_count": 1, "uploaded_by": null, "status": "processed", "store_id": 7 } [DB DEBUG] Final URLs for insert: { imageUrl: 'https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg', iconUrl: 'https://example.com/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp' } {"level":20,"time":1768078174329,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","query":"\n INSERT INTO flyers (\n file_name, image_url, icon_url, checksum, store_id, valid_from, valid_to, store_address,\n status, item_count, uploaded_by\n )\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)\n RETURNING *;\n ","values":["test-flyer-image-1768078173583.jpg","https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg","https://example.com/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp","66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34",7,"2025-01-01","2025-01-07","123 Mock St","processed",1,null],"msg":"[DB insertFlyer] Executing insert with the following values."} {"level":20,"time":1768078174343,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","query":"\n INSERT INTO flyer_items (\n flyer_id, item, price_display, price_in_cents, quantity, category_name, view_count, click_count\n )\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8)\n RETURNING *;\n ","values":[3,"Mocked Integration Item","$1.99",199,"each","Mock Category",0,0],"msg":"[DB insertFlyerItems] Executing bulk insert with the following values."} {"level":30,"time":1768078174353,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Successfully processed flyer: test-flyer-image-1768078173583.jpg (ID: 3) with 1 items."} {"level":30,"time":1768078174359,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","pattern":"cache:flyers*","totalDeleted":0,"msg":"Cache invalidation completed"} {"level":30,"time":1768078174366,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","pattern":"cache:flyer*","totalDeleted":1,"msg":"Cache invalidation completed"} {"level":30,"time":1768078174367,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Successfully processed job and enqueued cleanup for flyer ID: 3"} {"level":30,"time":1768078174370,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"test-flyer-image-1768078173583.jpg","checksum":"66990675fd77518b9a52d6fc3b5f4fd3f5bd0ae0479c657392d8d3d4cabd7c34","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","pattern":"cache:flyer-items*","totalDeleted":0,"msg":"Cache invalidation completed"} {"level":30,"time":1768078174375,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"cleanup-flyer-files","flyerId":3,"paths":["/app/flyer-images/flyerFile-test-flyer-image.jpg","/app/flyer-images/flyerFile-test-flyer-image-processed.jpeg","/app/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp"],"msg":"Picked up file cleanup job."} {"level":30,"time":1768078174377,"pid":12017,"hostname":"27443fa088eb","returnValue":{"flyerId":3},"msg":"[flyer-processing] Job 2 completed successfully."} {"level":30,"time":1768078174378,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"cleanup-flyer-files","flyerId":3,"paths":["/app/flyer-images/flyerFile-test-flyer-image.jpg","/app/flyer-images/flyerFile-test-flyer-image-processed.jpeg","/app/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp"],"msg":"Successfully deleted temporary file: /app/flyer-images/flyerFile-test-flyer-image.jpg"} {"level":30,"time":1768078174378,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"cleanup-flyer-files","flyerId":3,"paths":["/app/flyer-images/flyerFile-test-flyer-image.jpg","/app/flyer-images/flyerFile-test-flyer-image-processed.jpeg","/app/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp"],"msg":"Successfully deleted temporary file: /app/flyer-images/flyerFile-test-flyer-image-processed.jpeg"} {"level":30,"time":1768078174383,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"cleanup-flyer-files","flyerId":3,"paths":["/app/flyer-images/flyerFile-test-flyer-image.jpg","/app/flyer-images/flyerFile-test-flyer-image-processed.jpeg","/app/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp"],"msg":"Successfully deleted temporary file: /app/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp"} {"level":30,"time":1768078174383,"pid":12017,"hostname":"27443fa088eb","jobId":"2","jobName":"cleanup-flyer-files","flyerId":3,"paths":["/app/flyer-images/flyerFile-test-flyer-image.jpg","/app/flyer-images/flyerFile-test-flyer-image-processed.jpeg","/app/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp"],"msg":"Successfully deleted all 3 temporary files."} {"level":30,"time":1768078174385,"pid":12017,"hostname":"27443fa088eb","returnValue":{"status":"success","deletedCount":3},"msg":"[file-cleanup] Job 2 completed successfully."} stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should successfully process a flyer for an ANONYMOUS user via the background queue [TEST POLL] Job 2 current state: completed stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should strip EXIF data from uploaded JPEG images during processing [TEST SETUP] Resetting mocks before test execution stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should strip EXIF data from uploaded JPEG images during processing [DEBUG] FlyerPersistenceService._setWithTransaction called, replacing withTransaction function [TEST SETUP] withTransaction restored to real implementation via DI stdout | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should strip EXIF data from uploaded JPEG images during processing [DEBUG] generateFileChecksum processing file: name="test-flyer-with-exif-1768078176978.jpg", type="image/jpeg", size=193255 stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should strip EXIF data from uploaded JPEG images during processing [DEBUG] aiService.enqueueFlyerProcessing resolved baseUrl: "https://example.com" stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should strip EXIF data from uploaded JPEG images during processing [WORKER DEBUG] ProcessingService: Calling fileHandler.prepareImageInputs for /app/flyer-images/flyerFile-test-flyer-image.jpg [WORKER DEBUG] FlyerFileHandler: prepareImageInputs called for /app/flyer-images/flyerFile-test-flyer-image.jpg [WORKER DEBUG] FlyerFileHandler: Detected extension: .jpg stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should strip EXIF data from uploaded JPEG images during processing [WORKER DEBUG] ProcessingService: fileHandler returned 1 images. stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should strip EXIF data from uploaded JPEG images during processing [WORKER DEBUG] ProcessingService: Calling aiProcessor.extractAndValidateData [WORKER DEBUG] FlyerAiProcessor: extractAndValidateData called with 1 images stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should strip EXIF data from uploaded JPEG images during processing [WORKER DEBUG] FlyerAiProcessor: Merged AI Data: { "store_name": "Mock Store", "valid_from": "2025-01-01", "valid_to": "2025-01-07", "store_address": "123 Mock St", "items": [ { "item": "Mocked Integration Item", "price_display": "$1.99", "price_in_cents": 199, "quantity": "each", "category_name": "Mock Category" } ] } stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should strip EXIF data from uploaded JPEG images during processing [WORKER DEBUG] ProcessingService: aiProcessor returned data for store: Mock Store stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should strip EXIF data from uploaded JPEG images during processing [WORKER DEBUG] ProcessingService: Generating icon from /app/flyer-images/flyerFile-test-flyer-image-processed.jpeg to /app/flyer-images/icons stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should strip EXIF data from uploaded JPEG images during processing [WORKER DEBUG] ProcessingService: Icon generated: mock-icon-safe.webp [DEBUG] FlyerProcessingService resolved baseUrl: "https://example.com" (job.data.baseUrl: "https://example.com", env.FRONTEND_URL: "https://example.com") [DEBUG] FlyerProcessingService calling transformer with: { originalFileName: 'test-flyer-with-exif-1768078176978.jpg', imageFileName: 'flyerFile-test-flyer-image-processed.jpeg', iconFileName: 'mock-icon-safe.webp', checksum: 'ab85d19a3fc6ac8483fabcb160c64b17b48301580804df1000dd3d0a3621577e', baseUrl: 'https://example.com' } [DEBUG] FlyerDataTransformer.transform called with baseUrl: https://example.com [DEBUG] FlyerDataTransformer._buildUrls inputs: { imageFileName: 'flyerFile-test-flyer-image-processed.jpeg', iconFileName: 'mock-icon-safe.webp', baseUrl: 'https://example.com' } [DEBUG] FlyerDataTransformer._buildUrls finalBaseUrl resolved to: https://example.com [DEBUG] FlyerDataTransformer._buildUrls constructed: { imageUrl: 'https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg', iconUrl: 'https://example.com/flyer-images/icons/mock-icon-safe.webp' } stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should strip EXIF data from uploaded JPEG images during processing [DEBUG] FlyerProcessingService transformer output URLs: { imageUrl: 'https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg', iconUrl: 'https://example.com/flyer-images/icons/mock-icon-safe.webp' } [DEBUG] Full Flyer Data to be saved: { "file_name": "test-flyer-with-exif-1768078176978.jpg", "image_url": "https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg", "icon_url": "https://example.com/flyer-images/icons/mock-icon-safe.webp", "checksum": "ab85d19a3fc6ac8483fabcb160c64b17b48301580804df1000dd3d0a3621577e", "store_name": "Mock Store", "valid_from": "2025-01-01", "valid_to": "2025-01-07", "store_address": "123 Mock St", "item_count": 1, "uploaded_by": "8fe11c84-1ee1-4b94-80e3-7ca434c64131", "status": "processed" } stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should strip EXIF data from uploaded JPEG images during processing [DEBUG] FlyerPersistenceService.saveFlyer called, about to invoke withTransaction [DEBUG] withTransaction function name: withTransaction stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should strip EXIF data from uploaded JPEG images during processing [DB DEBUG] FlyerRepository.insertFlyer called with: { "file_name": "test-flyer-with-exif-1768078176978.jpg", "image_url": "https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg", "icon_url": "https://example.com/flyer-images/icons/mock-icon-safe.webp", "checksum": "ab85d19a3fc6ac8483fabcb160c64b17b48301580804df1000dd3d0a3621577e", "store_name": "Mock Store", "valid_from": "2025-01-01", "valid_to": "2025-01-07", "store_address": "123 Mock St", "item_count": 1, "uploaded_by": "8fe11c84-1ee1-4b94-80e3-7ca434c64131", "status": "processed", "store_id": 6 } [DB DEBUG] Final URLs for insert: { imageUrl: 'https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg', iconUrl: 'https://example.com/flyer-images/icons/mock-icon-safe.webp' } stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should strip metadata from uploaded PNG images during processing [TEST SETUP] Resetting mocks before test execution stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should strip metadata from uploaded PNG images during processing [DEBUG] FlyerPersistenceService._setWithTransaction called, replacing withTransaction function [TEST SETUP] withTransaction restored to real implementation via DI stdout | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should strip metadata from uploaded PNG images during processing [DEBUG] generateFileChecksum processing file: name="test-flyer-with-metadata-1768078180609.png", type="image/png", size=1407322 stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should strip metadata from uploaded PNG images during processing [DEBUG] aiService.enqueueFlyerProcessing resolved baseUrl: "https://example.com" {"level":30,"time":1768078180683,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Picked up flyer processing job."} [WORKER DEBUG] ProcessingService: Calling fileHandler.prepareImageInputs for /app/flyer-images/flyerFile-test-flyer-image.png [WORKER DEBUG] FlyerFileHandler: prepareImageInputs called for /app/flyer-images/flyerFile-test-flyer-image.png [WORKER DEBUG] FlyerFileHandler: Detected extension: .png {"level":30,"time":1768078180685,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","from":"/app/flyer-images/flyerFile-test-flyer-image.png","to":"/app/flyer-images/flyerFile-test-flyer-image-processed.png","msg":"Processing PNG to strip metadata."} [WORKER DEBUG] ProcessingService: fileHandler returned 1 images. {"level":30,"time":1768078184183,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Starting image optimization for 1 images."} {"level":30,"time":1768078184545,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Image optimization complete."} [WORKER DEBUG] ProcessingService: Calling aiProcessor.extractAndValidateData {"level":30,"time":1768078184548,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Starting AI data extraction for 1 pages."} [WORKER DEBUG] FlyerAiProcessor: extractAndValidateData called with 1 images {"level":20,"time":1768078184558,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Retrieved 143 master items for AI matching."} {"level":30,"time":1768078184558,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Processing 1 pages in 1 batches (Batch Size: 4)."} {"level":30,"time":1768078184558,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Processing batch 1/1 (1 pages)..."} {"level":30,"time":1768078184558,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[extractCoreDataFromFlyerImage] Entering method with 1 image(s)."} {"level":30,"time":1768078184578,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[aiService.server] Total base64 image data size for Gemini: 0.21 MB"} [WORKER DEBUG] FlyerAiProcessor: Merged AI Data: { "store_name": "Mock Store from AIService", "valid_from": "2025-01-01", "valid_to": "2025-01-07", "store_address": "123 Mock St", "items": [ { "item": "Mocked Integration Item", "price_display": "$1.99", "price_in_cents": 199, "quantity": "each", "category_name": "Mock Category", "master_item_id": null } ] } [WORKER DEBUG] ProcessingService: aiProcessor returned data for store: Mock Store from AIService {"level":20,"time":1768078184578,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[extractCoreDataFromFlyerImage] PRE-RATE-LIMITER: Preparing to call Gemini API."} {"level":20,"time":1768078184578,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[extractCoreDataFromFlyerImage] INSIDE-RATE-LIMITER: Executing generateContent call."} {"level":30,"time":1768078184578,"pid":12017,"hostname":"27443fa088eb","msg":"[AIService] Mock generateContent called in test environment."} {"level":20,"time":1768078184578,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[extractCoreDataFromFlyerImage] POST-RATE-LIMITER: AI call completed."} {"level":30,"time":1768078184579,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[aiService.server] Gemini API call for flyer processing completed in 0.37 ms."} {"level":20,"time":1768078184579,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[aiService.server] Raw Gemini response text (first 500 chars): {\"store_name\":\"Mock Store from AIService\",\"valid_from\":\"2025-01-01\",\"valid_to\":\"2025-01-07\",\"store_address\":\"123 Mock St\",\"items\":[{\"item\":\"Mocked Integration Item\",\"price_display\":\"$1.99\",\"price_in_cents\":199,\"quantity\":\"each\",\"category_name\":\"Mock Category\",\"master_item_id\":null}]}"} {"level":20,"time":1768078184579,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","responseText_type":"string","responseText_length":284,"responseText_preview":"{\"store_name\":\"Mock Store from AIService\",\"valid_from\":\"2025-01-01\",\"valid_to\":\"2025-01-07\",\"store_address\":\"123 Mock St\",\"items\":[{\"item\":\"Mocked Integration Item\",\"price_display\":\"$1.99\",\"price_in_c","msg":"[_parseJsonFromAiResponse] Starting JSON parsing."} {"level":20,"time":1768078184579,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[_parseJsonFromAiResponse] No markdown code block found. Using raw response text."} {"level":20,"time":1768078184579,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","firstBrace":0,"firstBracket":130,"msg":"[_parseJsonFromAiResponse] Searching for start of JSON."} {"level":20,"time":1768078184579,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","sliceLength":284,"msg":"[_parseJsonFromAiResponse] Extracted JSON slice for parsing."} {"level":30,"time":1768078184579,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[_parseJsonFromAiResponse] Successfully parsed JSON from AI response."} {"level":30,"time":1768078184579,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[extractCoreDataFromFlyerImage] Successfully processed flyer data for store: Mock Store from AIService. Exiting method."} {"level":30,"time":1768078184579,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Batch processing complete. Total items extracted: 1"} {"level":30,"time":1768078184580,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"AI extracted 1 items. Needs Review: false"} [WORKER DEBUG] ProcessingService: Generating icon from /app/flyer-images/flyerFile-test-flyer-image-processed.png to /app/flyer-images/icons {"level":20,"time":1768078184589,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","sourcePath":"/app/flyer-images/flyerFile-test-flyer-image-processed.png","outputPath":"/app/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp","msg":"Starting icon generation."} [DEBUG] generateFlyerIcon returning: icon-flyerFile-test-flyer-image-processed.webp {"level":30,"time":1768078184721,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Successfully generated icon: /app/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp"} [WORKER DEBUG] ProcessingService: Icon generated: icon-flyerFile-test-flyer-image-processed.webp [DEBUG] FlyerProcessingService resolved baseUrl: "https://example.com" (job.data.baseUrl: "https://example.com", env.FRONTEND_URL: "https://example.com") [DEBUG] FlyerProcessingService calling transformer with: { originalFileName: 'test-flyer-with-metadata-1768078180609.png', imageFileName: 'flyerFile-test-flyer-image-processed.png', iconFileName: 'icon-flyerFile-test-flyer-image-processed.webp', checksum: 'ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319', baseUrl: 'https://example.com' } [DEBUG] FlyerDataTransformer.transform called with baseUrl: https://example.com [DEBUG] FlyerDataTransformer._buildUrls inputs: { imageFileName: 'flyerFile-test-flyer-image-processed.png', iconFileName: 'icon-flyerFile-test-flyer-image-processed.webp', baseUrl: 'https://example.com' } [DEBUG] FlyerDataTransformer._buildUrls finalBaseUrl resolved to: https://example.com [DEBUG] FlyerDataTransformer._buildUrls constructed: { imageUrl: 'https://example.com/flyer-images/flyerFile-test-flyer-image-processed.png', iconUrl: 'https://example.com/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp' } [DEBUG] FlyerProcessingService transformer output URLs: { imageUrl: 'https://example.com/flyer-images/flyerFile-test-flyer-image-processed.png', iconUrl: 'https://example.com/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp' } [DEBUG] Full Flyer Data to be saved: { "file_name": "test-flyer-with-metadata-1768078180609.png", "image_url": "https://example.com/flyer-images/flyerFile-test-flyer-image-processed.png", "icon_url": "https://example.com/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp", "checksum": "ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319", "store_name": "Mock Store from AIService", "valid_from": "2025-01-01", "valid_to": "2025-01-07", "store_address": "123 Mock St", "item_count": 1, "uploaded_by": "d5771c67-92f9-4411-acd0-fb17c6f36995", "status": "processed" } [DEBUG] FlyerPersistenceService.saveFlyer called, about to invoke withTransaction [DEBUG] withTransaction function name: withTransaction {"level":30,"time":1768078184722,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Starting data transformation from AI output to database format."} [DB DEBUG] FlyerRepository.insertFlyer called with: { "file_name": "test-flyer-with-metadata-1768078180609.png", "image_url": "https://example.com/flyer-images/flyerFile-test-flyer-image-processed.png", "icon_url": "https://example.com/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp", "checksum": "ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319", "store_name": "Mock Store from AIService", "valid_from": "2025-01-01", "valid_to": "2025-01-07", "store_address": "123 Mock St", "item_count": 1, "uploaded_by": "d5771c67-92f9-4411-acd0-fb17c6f36995", "status": "processed", "store_id": 7 } [DB DEBUG] Final URLs for insert: { imageUrl: 'https://example.com/flyer-images/flyerFile-test-flyer-image-processed.png', iconUrl: 'https://example.com/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp' } {"level":20,"time":1768078184722,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","imageFileName":"flyerFile-test-flyer-image-processed.png","iconFileName":"icon-flyerFile-test-flyer-image-processed.webp","baseUrl":"https://example.com","msg":"Building URLs"} {"level":20,"time":1768078184723,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","imageUrl":"https://example.com/flyer-images/flyerFile-test-flyer-image-processed.png","iconUrl":"https://example.com/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp","msg":"Constructed URLs"} {"level":30,"time":1768078184723,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","itemCount":1,"storeName":"Mock Store from AIService","msg":"Data transformation complete."} {"level":20,"time":1768078184729,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","query":"\n INSERT INTO flyers (\n file_name, image_url, icon_url, checksum, store_id, valid_from, valid_to, store_address,\n status, item_count, uploaded_by\n )\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)\n RETURNING *;\n ","values":["test-flyer-with-metadata-1768078180609.png","https://example.com/flyer-images/flyerFile-test-flyer-image-processed.png","https://example.com/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp","ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319",7,"2025-01-01","2025-01-07","123 Mock St","processed",1,"d5771c67-92f9-4411-acd0-fb17c6f36995"],"msg":"[DB insertFlyer] Executing insert with the following values."} {"level":20,"time":1768078184737,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","query":"\n INSERT INTO flyer_items (\n flyer_id, item, price_display, price_in_cents, quantity, category_name, view_count, click_count\n )\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8)\n RETURNING *;\n ","values":[5,"Mocked Integration Item","$1.99",199,"each","Mock Category",0,0],"msg":"[DB insertFlyerItems] Executing bulk insert with the following values."} {"level":30,"time":1768078184741,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Successfully processed flyer: test-flyer-with-metadata-1768078180609.png (ID: 5) with 1 items."} {"level":30,"time":1768078184750,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","pattern":"cache:flyers*","totalDeleted":0,"msg":"Cache invalidation completed"} {"level":30,"time":1768078184751,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","pattern":"cache:flyer*","totalDeleted":0,"msg":"Cache invalidation completed"} {"level":30,"time":1768078184752,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Successfully processed job and enqueued cleanup for flyer ID: 5"} {"level":30,"time":1768078184753,"pid":12017,"hostname":"27443fa088eb","jobId":"4","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.png","originalFileName":"test-flyer-with-metadata-1768078180609.png","checksum":"ee27049024f71fe94445da3ce8764e0bfdb1506b27c932a47b4513f0ee771319","userId":"d5771c67-92f9-4411-acd0-fb17c6f36995","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","pattern":"cache:flyer-items*","totalDeleted":0,"msg":"Cache invalidation completed"} {"level":30,"time":1768078184754,"pid":12017,"hostname":"27443fa088eb","returnValue":{"flyerId":5},"msg":"[flyer-processing] Job 4 completed successfully."} stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should strip metadata from uploaded PNG images during processing [TEST] savedImagePath during PNG metadata stripping: /app/flyer-images/flyerFile-test-flyer-image-processed.png stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should handle a failure from the AI service gracefully stdout | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should handle a failure from the AI service gracefully [DEBUG] generateFileChecksum processing file: name="ai-error-test-1768078186736.jpg", type="image/jpeg", size=193352 [TEST SETUP] Resetting mocks before test execution {"level":30,"time":1768078186758,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Picked up flyer processing job."} {"level":30,"time":1768078186759,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","from":"/app/flyer-images/flyerFile-test-flyer-image.jpg","to":"/app/flyer-images/flyerFile-test-flyer-image-processed.jpeg","msg":"Processing JPEG to strip EXIF data."} stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should handle a failure from the AI service gracefully [DEBUG] FlyerPersistenceService._setWithTransaction called, replacing withTransaction function [TEST SETUP] withTransaction restored to real implementation via DI stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should handle a failure from the AI service gracefully [DEBUG] aiService.enqueueFlyerProcessing resolved baseUrl: "https://example.com" [WORKER DEBUG] ProcessingService: Calling fileHandler.prepareImageInputs for /app/flyer-images/flyerFile-test-flyer-image.jpg [WORKER DEBUG] FlyerFileHandler: prepareImageInputs called for /app/flyer-images/flyerFile-test-flyer-image.jpg [WORKER DEBUG] FlyerFileHandler: Detected extension: .jpg [WORKER DEBUG] ProcessingService: fileHandler returned 1 images. {"level":30,"time":1768078186891,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Starting image optimization for 1 images."} {"level":30,"time":1768078187203,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Image optimization complete."} [WORKER DEBUG] ProcessingService: Calling aiProcessor.extractAndValidateData [WORKER DEBUG] FlyerAiProcessor: extractAndValidateData called with 1 images {"level":30,"time":1768078187206,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Starting AI data extraction for 1 pages."} {"level":20,"time":1768078187212,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Retrieved 143 master items for AI matching."} {"level":30,"time":1768078187212,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Processing 1 pages in 1 batches (Batch Size: 4)."} {"level":30,"time":1768078187212,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Processing batch 1/1 (1 pages)..."} {"level":30,"time":1768078187212,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[extractCoreDataFromFlyerImage] Entering method with 1 image(s)."} {"level":30,"time":1768078187229,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[aiService.server] Total base64 image data size for Gemini: 0.21 MB"} [WORKER DEBUG] FlyerAiProcessor: Merged AI Data: { "store_name": "Mock Store from AIService", "valid_from": "2025-01-01", "valid_to": "2025-01-07", "store_address": "123 Mock St", "items": [ { "item": "Mocked Integration Item", "price_display": "$1.99", "price_in_cents": 199, "quantity": "each", "category_name": "Mock Category", "master_item_id": null } ] } [WORKER DEBUG] ProcessingService: aiProcessor returned data for store: Mock Store from AIService {"level":20,"time":1768078187229,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[extractCoreDataFromFlyerImage] PRE-RATE-LIMITER: Preparing to call Gemini API."} {"level":20,"time":1768078187229,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[extractCoreDataFromFlyerImage] INSIDE-RATE-LIMITER: Executing generateContent call."} {"level":30,"time":1768078187229,"pid":12017,"hostname":"27443fa088eb","msg":"[AIService] Mock generateContent called in test environment."} {"level":20,"time":1768078187229,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[extractCoreDataFromFlyerImage] POST-RATE-LIMITER: AI call completed."} {"level":30,"time":1768078187229,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[aiService.server] Gemini API call for flyer processing completed in 0.21 ms."} {"level":20,"time":1768078187229,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[aiService.server] Raw Gemini response text (first 500 chars): {\"store_name\":\"Mock Store from AIService\",\"valid_from\":\"2025-01-01\",\"valid_to\":\"2025-01-07\",\"store_address\":\"123 Mock St\",\"items\":[{\"item\":\"Mocked Integration Item\",\"price_display\":\"$1.99\",\"price_in_cents\":199,\"quantity\":\"each\",\"category_name\":\"Mock Category\",\"master_item_id\":null}]}"} {"level":20,"time":1768078187229,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","responseText_type":"string","responseText_length":284,"responseText_preview":"{\"store_name\":\"Mock Store from AIService\",\"valid_from\":\"2025-01-01\",\"valid_to\":\"2025-01-07\",\"store_address\":\"123 Mock St\",\"items\":[{\"item\":\"Mocked Integration Item\",\"price_display\":\"$1.99\",\"price_in_c","msg":"[_parseJsonFromAiResponse] Starting JSON parsing."} {"level":20,"time":1768078187229,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[_parseJsonFromAiResponse] No markdown code block found. Using raw response text."} {"level":20,"time":1768078187229,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","firstBrace":0,"firstBracket":130,"msg":"[_parseJsonFromAiResponse] Searching for start of JSON."} {"level":20,"time":1768078187229,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","sliceLength":284,"msg":"[_parseJsonFromAiResponse] Extracted JSON slice for parsing."} {"level":30,"time":1768078187229,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[_parseJsonFromAiResponse] Successfully parsed JSON from AI response."} {"level":30,"time":1768078187229,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[extractCoreDataFromFlyerImage] Successfully processed flyer data for store: Mock Store from AIService. Exiting method."} {"level":30,"time":1768078187229,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Batch processing complete. Total items extracted: 1"} {"level":30,"time":1768078187230,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"AI extracted 1 items. Needs Review: false"} [WORKER DEBUG] ProcessingService: Generating icon from /app/flyer-images/flyerFile-test-flyer-image-processed.jpeg to /app/flyer-images/icons {"level":20,"time":1768078187236,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","sourcePath":"/app/flyer-images/flyerFile-test-flyer-image-processed.jpeg","outputPath":"/app/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp","msg":"Starting icon generation."} {"level":30,"time":1768078187343,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Successfully generated icon: /app/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp"} [WORKER DEBUG] ProcessingService: Icon generated: icon-flyerFile-test-flyer-image-processed.webp [DEBUG] generateFlyerIcon returning: icon-flyerFile-test-flyer-image-processed.webp [DEBUG] FlyerProcessingService resolved baseUrl: "https://example.com" (job.data.baseUrl: "https://example.com", env.FRONTEND_URL: "https://example.com") [DEBUG] FlyerProcessingService calling transformer with: { originalFileName: 'ai-error-test-1768078186736.jpg', imageFileName: 'flyerFile-test-flyer-image-processed.jpeg', iconFileName: 'icon-flyerFile-test-flyer-image-processed.webp', checksum: 'b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659', baseUrl: 'https://example.com' } [DEBUG] FlyerDataTransformer.transform called with baseUrl: https://example.com [DEBUG] FlyerDataTransformer._buildUrls inputs: { imageFileName: 'flyerFile-test-flyer-image-processed.jpeg', iconFileName: 'icon-flyerFile-test-flyer-image-processed.webp', baseUrl: 'https://example.com' } [DEBUG] FlyerDataTransformer._buildUrls finalBaseUrl resolved to: https://example.com [DEBUG] FlyerDataTransformer._buildUrls constructed: { imageUrl: 'https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg', iconUrl: 'https://example.com/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp' } [DEBUG] FlyerProcessingService transformer output URLs: { imageUrl: 'https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg', iconUrl: 'https://example.com/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp' } [DEBUG] Full Flyer Data to be saved: { "file_name": "ai-error-test-1768078186736.jpg", "image_url": "https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg", "icon_url": "https://example.com/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp", "checksum": "b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659", "store_name": "Mock Store from AIService", "valid_from": "2025-01-01", "valid_to": "2025-01-07", "store_address": "123 Mock St", "item_count": 1, "uploaded_by": null, "status": "processed" } {"level":30,"time":1768078187344,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Starting data transformation from AI output to database format."} {"level":20,"time":1768078187345,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","imageFileName":"flyerFile-test-flyer-image-processed.jpeg","iconFileName":"icon-flyerFile-test-flyer-image-processed.webp","baseUrl":"https://example.com","msg":"Building URLs"} {"level":20,"time":1768078187345,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","imageUrl":"https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg","iconUrl":"https://example.com/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp","msg":"Constructed URLs"} {"level":30,"time":1768078187345,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","itemCount":1,"storeName":"Mock Store from AIService","msg":"Data transformation complete."} [DEBUG] FlyerPersistenceService.saveFlyer called, about to invoke withTransaction [DEBUG] withTransaction function name: withTransaction [DB DEBUG] FlyerRepository.insertFlyer called with: { "file_name": "ai-error-test-1768078186736.jpg", "image_url": "https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg", "icon_url": "https://example.com/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp", "checksum": "b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659", "store_name": "Mock Store from AIService", "valid_from": "2025-01-01", "valid_to": "2025-01-07", "store_address": "123 Mock St", "item_count": 1, "uploaded_by": null, "status": "processed", "store_id": 7 } [DB DEBUG] Final URLs for insert: { imageUrl: 'https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg', iconUrl: 'https://example.com/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp' } {"level":20,"time":1768078187352,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","query":"\n INSERT INTO flyers (\n file_name, image_url, icon_url, checksum, store_id, valid_from, valid_to, store_address,\n status, item_count, uploaded_by\n )\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)\n RETURNING *;\n ","values":["ai-error-test-1768078186736.jpg","https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg","https://example.com/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp","b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659",7,"2025-01-01","2025-01-07","123 Mock St","processed",1,null],"msg":"[DB insertFlyer] Executing insert with the following values."} {"level":20,"time":1768078187354,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","query":"\n INSERT INTO flyer_items (\n flyer_id, item, price_display, price_in_cents, quantity, category_name, view_count, click_count\n )\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8)\n RETURNING *;\n ","values":[6,"Mocked Integration Item","$1.99",199,"each","Mock Category",0,0],"msg":"[DB insertFlyerItems] Executing bulk insert with the following values."} {"level":30,"time":1768078187358,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Successfully processed flyer: ai-error-test-1768078186736.jpg (ID: 6) with 1 items."} {"level":30,"time":1768078187365,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","pattern":"cache:flyers*","totalDeleted":0,"msg":"Cache invalidation completed"} {"level":30,"time":1768078187367,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","pattern":"cache:flyer*","totalDeleted":0,"msg":"Cache invalidation completed"} {"level":30,"time":1768078187368,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Successfully processed job and enqueued cleanup for flyer ID: 6"} {"level":30,"time":1768078187370,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"ai-error-test-1768078186736.jpg","checksum":"b779851e8226d193116f19ee82abb74950b3b0c9759651c76a71131023a34659","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","pattern":"cache:flyer-items*","totalDeleted":0,"msg":"Cache invalidation completed"} {"level":30,"time":1768078187370,"pid":12017,"hostname":"27443fa088eb","returnValue":{"flyerId":6},"msg":"[flyer-processing] Job 5 completed successfully."} {"level":30,"time":1768078187377,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"cleanup-flyer-files","flyerId":6,"paths":["/app/flyer-images/flyerFile-test-flyer-image.jpg","/app/flyer-images/flyerFile-test-flyer-image-processed.jpeg","/app/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp"],"msg":"Picked up file cleanup job."} {"level":30,"time":1768078187380,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"cleanup-flyer-files","flyerId":6,"paths":["/app/flyer-images/flyerFile-test-flyer-image.jpg","/app/flyer-images/flyerFile-test-flyer-image-processed.jpeg","/app/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp"],"msg":"Successfully deleted temporary file: /app/flyer-images/flyerFile-test-flyer-image.jpg"} {"level":30,"time":1768078187381,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"cleanup-flyer-files","flyerId":6,"paths":["/app/flyer-images/flyerFile-test-flyer-image.jpg","/app/flyer-images/flyerFile-test-flyer-image-processed.jpeg","/app/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp"],"msg":"Successfully deleted temporary file: /app/flyer-images/flyerFile-test-flyer-image-processed.jpeg"} {"level":30,"time":1768078187384,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"cleanup-flyer-files","flyerId":6,"paths":["/app/flyer-images/flyerFile-test-flyer-image.jpg","/app/flyer-images/flyerFile-test-flyer-image-processed.jpeg","/app/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp"],"msg":"Successfully deleted temporary file: /app/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp"} {"level":30,"time":1768078187385,"pid":12017,"hostname":"27443fa088eb","jobId":"5","jobName":"cleanup-flyer-files","flyerId":6,"paths":["/app/flyer-images/flyerFile-test-flyer-image.jpg","/app/flyer-images/flyerFile-test-flyer-image-processed.jpeg","/app/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp"],"msg":"Successfully deleted all 3 temporary files."} {"level":30,"time":1768078187387,"pid":12017,"hostname":"27443fa088eb","returnValue":{"status":"success","deletedCount":3},"msg":"[file-cleanup] Job 5 completed successfully."} stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should handle a database failure during flyer creation [TEST SETUP] Resetting mocks before test execution stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should handle a database failure during flyer creation [DEBUG] FlyerPersistenceService._setWithTransaction called, replacing withTransaction function [TEST SETUP] withTransaction restored to real implementation via DI stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should handle a database failure during flyer creation [DB FAILURE TEST] About to inject failingWithTransaction mock [DEBUG] FlyerPersistenceService._setWithTransaction called, replacing withTransaction function [DB FAILURE TEST] failingWithTransaction mock injected successfully stdout | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should handle a database failure during flyer creation [DEBUG] generateFileChecksum processing file: name="db-error-test-1768078189801.jpg", type="image/jpeg", size=193352 stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should handle a database failure during flyer creation [DEBUG] aiService.enqueueFlyerProcessing resolved baseUrl: "https://example.com" stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should handle a database failure during flyer creation [WORKER DEBUG] ProcessingService: Calling fileHandler.prepareImageInputs for /app/flyer-images/flyerFile-test-flyer-image.jpg [WORKER DEBUG] FlyerFileHandler: prepareImageInputs called for /app/flyer-images/flyerFile-test-flyer-image.jpg [WORKER DEBUG] FlyerFileHandler: Detected extension: .jpg stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should handle a database failure during flyer creation [WORKER DEBUG] ProcessingService: fileHandler returned 1 images. stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should handle a database failure during flyer creation [WORKER DEBUG] ProcessingService: Calling aiProcessor.extractAndValidateData [WORKER DEBUG] FlyerAiProcessor: extractAndValidateData called with 1 images stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should handle a database failure during flyer creation [WORKER DEBUG] FlyerAiProcessor: Merged AI Data: { "store_name": "Mock Store", "valid_from": "2025-01-01", "valid_to": "2025-01-07", "store_address": "123 Mock St", "items": [ { "item": "Mocked Integration Item", "price_display": "$1.99", "price_in_cents": 199, "quantity": "each", "category_name": "Mock Category" } ] } stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should handle a database failure during flyer creation [WORKER DEBUG] ProcessingService: aiProcessor returned data for store: Mock Store stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should handle a database failure during flyer creation [WORKER DEBUG] ProcessingService: Generating icon from /app/flyer-images/flyerFile-test-flyer-image-processed.jpeg to /app/flyer-images/icons stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should handle a database failure during flyer creation [WORKER DEBUG] ProcessingService: Icon generated: mock-icon-safe.webp [DEBUG] FlyerProcessingService resolved baseUrl: "https://example.com" (job.data.baseUrl: "https://example.com", env.FRONTEND_URL: "https://example.com") [DEBUG] FlyerProcessingService calling transformer with: { originalFileName: 'db-error-test-1768078189801.jpg', imageFileName: 'flyerFile-test-flyer-image-processed.jpeg', iconFileName: 'mock-icon-safe.webp', checksum: '55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a', baseUrl: 'https://example.com' } [DEBUG] FlyerDataTransformer.transform called with baseUrl: https://example.com [DEBUG] FlyerDataTransformer._buildUrls inputs: { imageFileName: 'flyerFile-test-flyer-image-processed.jpeg', iconFileName: 'mock-icon-safe.webp', baseUrl: 'https://example.com' } [DEBUG] FlyerDataTransformer._buildUrls finalBaseUrl resolved to: https://example.com [DEBUG] FlyerDataTransformer._buildUrls constructed: { imageUrl: 'https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg', iconUrl: 'https://example.com/flyer-images/icons/mock-icon-safe.webp' } stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should handle a database failure during flyer creation [DEBUG] FlyerProcessingService transformer output URLs: { imageUrl: 'https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg', iconUrl: 'https://example.com/flyer-images/icons/mock-icon-safe.webp' } [DEBUG] Full Flyer Data to be saved: { "file_name": "db-error-test-1768078189801.jpg", "image_url": "https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg", "icon_url": "https://example.com/flyer-images/icons/mock-icon-safe.webp", "checksum": "55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a", "store_name": "Mock Store", "valid_from": "2025-01-01", "valid_to": "2025-01-07", "store_address": "123 Mock St", "item_count": 1, "uploaded_by": null, "status": "processed" } stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should handle a database failure during flyer creation [DEBUG] FlyerPersistenceService.saveFlyer called, about to invoke withTransaction [DEBUG] withTransaction function name: Mock {"level":30,"time":1768078195436,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Picked up flyer processing job."} [WORKER DEBUG] ProcessingService: Calling fileHandler.prepareImageInputs for /app/flyer-images/flyerFile-test-flyer-image.jpg [WORKER DEBUG] FlyerFileHandler: prepareImageInputs called for /app/flyer-images/flyerFile-test-flyer-image.jpg [WORKER DEBUG] FlyerFileHandler: Detected extension: .jpg {"level":30,"time":1768078195438,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","from":"/app/flyer-images/flyerFile-test-flyer-image.jpg","to":"/app/flyer-images/flyerFile-test-flyer-image-processed.jpeg","msg":"Processing JPEG to strip EXIF data."} [WORKER DEBUG] ProcessingService: fileHandler returned 1 images. {"level":30,"time":1768078195537,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Starting image optimization for 1 images."} {"level":30,"time":1768078195859,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Image optimization complete."} [WORKER DEBUG] ProcessingService: Calling aiProcessor.extractAndValidateData [WORKER DEBUG] FlyerAiProcessor: extractAndValidateData called with 1 images {"level":30,"time":1768078195861,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Starting AI data extraction for 1 pages."} {"level":20,"time":1768078195865,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Retrieved 143 master items for AI matching."} {"level":30,"time":1768078195865,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Processing 1 pages in 1 batches (Batch Size: 4)."} {"level":30,"time":1768078195865,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Processing batch 1/1 (1 pages)..."} {"level":30,"time":1768078195866,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[extractCoreDataFromFlyerImage] Entering method with 1 image(s)."} {"level":30,"time":1768078195884,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[aiService.server] Total base64 image data size for Gemini: 0.21 MB"} [WORKER DEBUG] FlyerAiProcessor: Merged AI Data: { "store_name": "Mock Store from AIService", "valid_from": "2025-01-01", "valid_to": "2025-01-07", "store_address": "123 Mock St", "items": [ { "item": "Mocked Integration Item", "price_display": "$1.99", "price_in_cents": 199, "quantity": "each", "category_name": "Mock Category", "master_item_id": null } ] } [WORKER DEBUG] ProcessingService: aiProcessor returned data for store: Mock Store from AIService {"level":20,"time":1768078195884,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[extractCoreDataFromFlyerImage] PRE-RATE-LIMITER: Preparing to call Gemini API."} {"level":20,"time":1768078195884,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[extractCoreDataFromFlyerImage] INSIDE-RATE-LIMITER: Executing generateContent call."} {"level":30,"time":1768078195884,"pid":12017,"hostname":"27443fa088eb","msg":"[AIService] Mock generateContent called in test environment."} {"level":20,"time":1768078195884,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[extractCoreDataFromFlyerImage] POST-RATE-LIMITER: AI call completed."} {"level":30,"time":1768078195884,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[aiService.server] Gemini API call for flyer processing completed in 0.24 ms."} {"level":20,"time":1768078195884,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[aiService.server] Raw Gemini response text (first 500 chars): {\"store_name\":\"Mock Store from AIService\",\"valid_from\":\"2025-01-01\",\"valid_to\":\"2025-01-07\",\"store_address\":\"123 Mock St\",\"items\":[{\"item\":\"Mocked Integration Item\",\"price_display\":\"$1.99\",\"price_in_cents\":199,\"quantity\":\"each\",\"category_name\":\"Mock Category\",\"master_item_id\":null}]}"} {"level":20,"time":1768078195884,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","responseText_type":"string","responseText_length":284,"responseText_preview":"{\"store_name\":\"Mock Store from AIService\",\"valid_from\":\"2025-01-01\",\"valid_to\":\"2025-01-07\",\"store_address\":\"123 Mock St\",\"items\":[{\"item\":\"Mocked Integration Item\",\"price_display\":\"$1.99\",\"price_in_c","msg":"[_parseJsonFromAiResponse] Starting JSON parsing."} {"level":20,"time":1768078195884,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[_parseJsonFromAiResponse] No markdown code block found. Using raw response text."} [WORKER DEBUG] ProcessingService: Generating icon from /app/flyer-images/flyerFile-test-flyer-image-processed.jpeg to /app/flyer-images/icons {"level":20,"time":1768078195884,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","firstBrace":0,"firstBracket":130,"msg":"[_parseJsonFromAiResponse] Searching for start of JSON."} {"level":20,"time":1768078195884,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","sliceLength":284,"msg":"[_parseJsonFromAiResponse] Extracted JSON slice for parsing."} {"level":30,"time":1768078195884,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[_parseJsonFromAiResponse] Successfully parsed JSON from AI response."} {"level":30,"time":1768078195884,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[extractCoreDataFromFlyerImage] Successfully processed flyer data for store: Mock Store from AIService. Exiting method."} {"level":30,"time":1768078195884,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Batch processing complete. Total items extracted: 1"} {"level":30,"time":1768078195885,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"AI extracted 1 items. Needs Review: false"} {"level":20,"time":1768078195895,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","sourcePath":"/app/flyer-images/flyerFile-test-flyer-image-processed.jpeg","outputPath":"/app/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp","msg":"Starting icon generation."} [WORKER DEBUG] ProcessingService: Icon generated: icon-flyerFile-test-flyer-image-processed.webp {"level":30,"time":1768078196007,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Successfully generated icon: /app/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp"} [DEBUG] generateFlyerIcon returning: icon-flyerFile-test-flyer-image-processed.webp [DEBUG] FlyerProcessingService resolved baseUrl: "https://example.com" (job.data.baseUrl: "https://example.com", env.FRONTEND_URL: "https://example.com") [DEBUG] FlyerProcessingService calling transformer with: { originalFileName: 'db-error-test-1768078189801.jpg', imageFileName: 'flyerFile-test-flyer-image-processed.jpeg', iconFileName: 'icon-flyerFile-test-flyer-image-processed.webp', checksum: '55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a', baseUrl: 'https://example.com' } [DEBUG] FlyerDataTransformer.transform called with baseUrl: https://example.com [DEBUG] FlyerDataTransformer._buildUrls inputs: { imageFileName: 'flyerFile-test-flyer-image-processed.jpeg', iconFileName: 'icon-flyerFile-test-flyer-image-processed.webp', baseUrl: 'https://example.com' } [DEBUG] FlyerDataTransformer._buildUrls finalBaseUrl resolved to: https://example.com [DEBUG] FlyerDataTransformer._buildUrls constructed: { imageUrl: 'https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg', iconUrl: 'https://example.com/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp' } [DEBUG] FlyerProcessingService transformer output URLs: { imageUrl: 'https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg', iconUrl: 'https://example.com/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp' } [DEBUG] Full Flyer Data to be saved: { "file_name": "db-error-test-1768078189801.jpg", "image_url": "https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg", "icon_url": "https://example.com/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp", "checksum": "55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a", "store_name": "Mock Store from AIService", "valid_from": "2025-01-01", "valid_to": "2025-01-07", "store_address": "123 Mock St", "item_count": 1, "uploaded_by": null, "status": "processed" } {"level":30,"time":1768078196008,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Starting data transformation from AI output to database format."} {"level":20,"time":1768078196008,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","imageFileName":"flyerFile-test-flyer-image-processed.jpeg","iconFileName":"icon-flyerFile-test-flyer-image-processed.webp","baseUrl":"https://example.com","msg":"Building URLs"} {"level":20,"time":1768078196008,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","imageUrl":"https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg","iconUrl":"https://example.com/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp","msg":"Constructed URLs"} {"level":30,"time":1768078196009,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","itemCount":1,"storeName":"Mock Store from AIService","msg":"Data transformation complete."} [DEBUG] FlyerPersistenceService.saveFlyer called, about to invoke withTransaction [DEBUG] withTransaction function name: withTransaction [DB DEBUG] FlyerRepository.insertFlyer called with: { "file_name": "db-error-test-1768078189801.jpg", "image_url": "https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg", "icon_url": "https://example.com/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp", "checksum": "55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a", "store_name": "Mock Store from AIService", "valid_from": "2025-01-01", "valid_to": "2025-01-07", "store_address": "123 Mock St", "item_count": 1, "uploaded_by": null, "status": "processed", "store_id": 7 } [DB DEBUG] Final URLs for insert: { imageUrl: 'https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg', iconUrl: 'https://example.com/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp' } {"level":20,"time":1768078196015,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","query":"\n INSERT INTO flyers (\n file_name, image_url, icon_url, checksum, store_id, valid_from, valid_to, store_address,\n status, item_count, uploaded_by\n )\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)\n RETURNING *;\n ","values":["db-error-test-1768078189801.jpg","https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg","https://example.com/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp","55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a",7,"2025-01-01","2025-01-07","123 Mock St","processed",1,null],"msg":"[DB insertFlyer] Executing insert with the following values."} {"level":20,"time":1768078196018,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","query":"\n INSERT INTO flyer_items (\n flyer_id, item, price_display, price_in_cents, quantity, category_name, view_count, click_count\n )\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8)\n RETURNING *;\n ","values":[7,"Mocked Integration Item","$1.99",199,"each","Mock Category",0,0],"msg":"[DB insertFlyerItems] Executing bulk insert with the following values."} {"level":30,"time":1768078196021,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Successfully processed flyer: db-error-test-1768078189801.jpg (ID: 7) with 1 items."} {"level":30,"time":1768078196025,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","pattern":"cache:flyers*","totalDeleted":0,"msg":"Cache invalidation completed"} {"level":30,"time":1768078196027,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","pattern":"cache:flyer*","totalDeleted":0,"msg":"Cache invalidation completed"} {"level":30,"time":1768078196029,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","pattern":"cache:flyer-items*","totalDeleted":0,"msg":"Cache invalidation completed"} {"level":30,"time":1768078196029,"pid":12017,"hostname":"27443fa088eb","jobId":"6","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"db-error-test-1768078189801.jpg","checksum":"55505ac11b6e89625e7c002bc2817a5232e17a1ba243633870390fec5155d95a","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Successfully processed job and enqueued cleanup for flyer ID: 7"} {"level":30,"time":1768078196031,"pid":12017,"hostname":"27443fa088eb","returnValue":{"flyerId":7},"msg":"[flyer-processing] Job 6 completed successfully."} stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should NOT clean up temporary files when a job fails, to allow for manual inspection [TEST SETUP] Resetting mocks before test execution stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should NOT clean up temporary files when a job fails, to allow for manual inspection [DEBUG] FlyerPersistenceService._setWithTransaction called, replacing withTransaction function [TEST SETUP] withTransaction restored to real implementation via DI stdout | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should NOT clean up temporary files when a job fails, to allow for manual inspection [DEBUG] generateFileChecksum processing file: name="cleanup-test-1768078198911.jpg", type="image/jpeg", size=193351 stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should NOT clean up temporary files when a job fails, to allow for manual inspection [DEBUG] aiService.enqueueFlyerProcessing resolved baseUrl: "https://example.com" stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should NOT clean up temporary files when a job fails, to allow for manual inspection [WORKER DEBUG] ProcessingService: Calling fileHandler.prepareImageInputs for /app/flyer-images/flyerFile-test-flyer-image.jpg [WORKER DEBUG] FlyerFileHandler: prepareImageInputs called for /app/flyer-images/flyerFile-test-flyer-image.jpg [WORKER DEBUG] FlyerFileHandler: Detected extension: .jpg stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should NOT clean up temporary files when a job fails, to allow for manual inspection [WORKER DEBUG] ProcessingService: fileHandler returned 1 images. stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should NOT clean up temporary files when a job fails, to allow for manual inspection [WORKER DEBUG] ProcessingService: Calling aiProcessor.extractAndValidateData [WORKER DEBUG] FlyerAiProcessor: extractAndValidateData called with 1 images {"level":20,"time":1768078203195,"pid":12017,"hostname":"27443fa088eb","request_id":"964b1654-b927-4140-a58a-65c038039183","user_id":"00000000-0000-0000-0000-000000000006","ip_address":"::ffff:127.0.0.1","method":"GET","originalUrl":"/api/health","msg":"[Request Logger] INCOMING"} {"level":40,"time":1768078203196,"pid":12017,"hostname":"27443fa088eb","request_id":"964b1654-b927-4140-a58a-65c038039183","user_id":"00000000-0000-0000-0000-000000000006","ip_address":"::ffff:127.0.0.1","user_id":"00000000-0000-0000-0000-000000000006","method":"GET","originalUrl":"/api/health","statusCode":404,"statusMessage":"Not Found","duration":"1.73","req":{"headers":{"host":"localhost:3001","user-agent":"curl/7.81.0","accept":"*/*"}},"msg":"Request completed with client error"} stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should NOT clean up temporary files when a job fails, to allow for manual inspection [WORKER DEBUG] ProcessingService: Calling fileHandler.prepareImageInputs for /app/flyer-images/flyerFile-test-flyer-image.jpg [WORKER DEBUG] FlyerFileHandler: prepareImageInputs called for /app/flyer-images/flyerFile-test-flyer-image.jpg [WORKER DEBUG] FlyerFileHandler: Detected extension: .jpg stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should NOT clean up temporary files when a job fails, to allow for manual inspection [WORKER DEBUG] ProcessingService: fileHandler returned 1 images. stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test > should NOT clean up temporary files when a job fails, to allow for manual inspection [WORKER DEBUG] ProcessingService: Calling aiProcessor.extractAndValidateData [WORKER DEBUG] FlyerAiProcessor: extractAndValidateData called with 1 images {"level":30,"time":1768078215049,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Picked up flyer processing job."} [WORKER DEBUG] ProcessingService: Calling fileHandler.prepareImageInputs for /app/flyer-images/flyerFile-test-flyer-image.jpg [WORKER DEBUG] FlyerFileHandler: prepareImageInputs called for /app/flyer-images/flyerFile-test-flyer-image.jpg [WORKER DEBUG] FlyerFileHandler: Detected extension: .jpg {"level":30,"time":1768078215050,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","from":"/app/flyer-images/flyerFile-test-flyer-image.jpg","to":"/app/flyer-images/flyerFile-test-flyer-image-processed.jpeg","msg":"Processing JPEG to strip EXIF data."} [WORKER DEBUG] ProcessingService: fileHandler returned 1 images. {"level":30,"time":1768078215147,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Starting image optimization for 1 images."} {"level":30,"time":1768078215421,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Image optimization complete."} [WORKER DEBUG] ProcessingService: Calling aiProcessor.extractAndValidateData [WORKER DEBUG] FlyerAiProcessor: extractAndValidateData called with 1 images {"level":30,"time":1768078215424,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Starting AI data extraction for 1 pages."} {"level":20,"time":1768078215431,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Retrieved 143 master items for AI matching."} {"level":30,"time":1768078215431,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Processing 1 pages in 1 batches (Batch Size: 4)."} {"level":30,"time":1768078215431,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Processing batch 1/1 (1 pages)..."} {"level":30,"time":1768078215432,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[extractCoreDataFromFlyerImage] Entering method with 1 image(s)."} {"level":30,"time":1768078215441,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[aiService.server] Total base64 image data size for Gemini: 0.21 MB"} [WORKER DEBUG] FlyerAiProcessor: Merged AI Data: { "store_name": "Mock Store from AIService", "valid_from": "2025-01-01", "valid_to": "2025-01-07", "store_address": "123 Mock St", "items": [ { "item": "Mocked Integration Item", "price_display": "$1.99", "price_in_cents": 199, "quantity": "each", "category_name": "Mock Category", "master_item_id": null } ] } [WORKER DEBUG] ProcessingService: aiProcessor returned data for store: Mock Store from AIService {"level":20,"time":1768078215441,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[extractCoreDataFromFlyerImage] PRE-RATE-LIMITER: Preparing to call Gemini API."} {"level":20,"time":1768078215441,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[extractCoreDataFromFlyerImage] INSIDE-RATE-LIMITER: Executing generateContent call."} {"level":30,"time":1768078215441,"pid":12017,"hostname":"27443fa088eb","msg":"[AIService] Mock generateContent called in test environment."} {"level":20,"time":1768078215441,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[extractCoreDataFromFlyerImage] POST-RATE-LIMITER: AI call completed."} {"level":30,"time":1768078215442,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[aiService.server] Gemini API call for flyer processing completed in 0.50 ms."} {"level":20,"time":1768078215442,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[aiService.server] Raw Gemini response text (first 500 chars): {\"store_name\":\"Mock Store from AIService\",\"valid_from\":\"2025-01-01\",\"valid_to\":\"2025-01-07\",\"store_address\":\"123 Mock St\",\"items\":[{\"item\":\"Mocked Integration Item\",\"price_display\":\"$1.99\",\"price_in_cents\":199,\"quantity\":\"each\",\"category_name\":\"Mock Category\",\"master_item_id\":null}]}"} {"level":20,"time":1768078215442,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","responseText_type":"string","responseText_length":284,"responseText_preview":"{\"store_name\":\"Mock Store from AIService\",\"valid_from\":\"2025-01-01\",\"valid_to\":\"2025-01-07\",\"store_address\":\"123 Mock St\",\"items\":[{\"item\":\"Mocked Integration Item\",\"price_display\":\"$1.99\",\"price_in_c","msg":"[_parseJsonFromAiResponse] Starting JSON parsing."} {"level":20,"time":1768078215442,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[_parseJsonFromAiResponse] No markdown code block found. Using raw response text."} {"level":20,"time":1768078215442,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","firstBrace":0,"firstBracket":130,"msg":"[_parseJsonFromAiResponse] Searching for start of JSON."} {"level":20,"time":1768078215446,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","sliceLength":284,"msg":"[_parseJsonFromAiResponse] Extracted JSON slice for parsing."} {"level":30,"time":1768078215446,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[_parseJsonFromAiResponse] Successfully parsed JSON from AI response."} {"level":30,"time":1768078215446,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"[extractCoreDataFromFlyerImage] Successfully processed flyer data for store: Mock Store from AIService. Exiting method."} {"level":30,"time":1768078215446,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Batch processing complete. Total items extracted: 1"} {"level":30,"time":1768078215447,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"AI extracted 1 items. Needs Review: false"} [WORKER DEBUG] ProcessingService: Generating icon from /app/flyer-images/flyerFile-test-flyer-image-processed.jpeg to /app/flyer-images/icons {"level":20,"time":1768078215458,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","sourcePath":"/app/flyer-images/flyerFile-test-flyer-image-processed.jpeg","outputPath":"/app/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp","msg":"Starting icon generation."} {"level":30,"time":1768078215551,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Successfully generated icon: /app/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp"} [WORKER DEBUG] ProcessingService: Icon generated: icon-flyerFile-test-flyer-image-processed.webp [DEBUG] generateFlyerIcon returning: icon-flyerFile-test-flyer-image-processed.webp [DEBUG] FlyerProcessingService resolved baseUrl: "https://example.com" (job.data.baseUrl: "https://example.com", env.FRONTEND_URL: "https://example.com") [DEBUG] FlyerProcessingService calling transformer with: { originalFileName: 'cleanup-test-1768078198911.jpg', imageFileName: 'flyerFile-test-flyer-image-processed.jpeg', iconFileName: 'icon-flyerFile-test-flyer-image-processed.webp', checksum: '356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942', baseUrl: 'https://example.com' } [DEBUG] FlyerDataTransformer.transform called with baseUrl: https://example.com [DEBUG] FlyerDataTransformer._buildUrls inputs: { imageFileName: 'flyerFile-test-flyer-image-processed.jpeg', iconFileName: 'icon-flyerFile-test-flyer-image-processed.webp', baseUrl: 'https://example.com' } [DEBUG] FlyerDataTransformer._buildUrls finalBaseUrl resolved to: https://example.com [DEBUG] FlyerDataTransformer._buildUrls constructed: { imageUrl: 'https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg', iconUrl: 'https://example.com/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp' } [DEBUG] FlyerProcessingService transformer output URLs: { imageUrl: 'https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg', iconUrl: 'https://example.com/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp' } [DEBUG] Full Flyer Data to be saved: { "file_name": "cleanup-test-1768078198911.jpg", "image_url": "https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg", "icon_url": "https://example.com/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp", "checksum": "356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942", "store_name": "Mock Store from AIService", "valid_from": "2025-01-01", "valid_to": "2025-01-07", "store_address": "123 Mock St", "item_count": 1, "uploaded_by": null, "status": "processed" } {"level":30,"time":1768078215552,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Starting data transformation from AI output to database format."} {"level":20,"time":1768078215552,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","imageFileName":"flyerFile-test-flyer-image-processed.jpeg","iconFileName":"icon-flyerFile-test-flyer-image-processed.webp","baseUrl":"https://example.com","msg":"Building URLs"} {"level":20,"time":1768078215553,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","imageUrl":"https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg","iconUrl":"https://example.com/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp","msg":"Constructed URLs"} {"level":30,"time":1768078215553,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","itemCount":1,"storeName":"Mock Store from AIService","msg":"Data transformation complete."} [DEBUG] FlyerPersistenceService.saveFlyer called, about to invoke withTransaction [DEBUG] withTransaction function name: withTransaction [DB DEBUG] FlyerRepository.insertFlyer called with: { "file_name": "cleanup-test-1768078198911.jpg", "image_url": "https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg", "icon_url": "https://example.com/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp", "checksum": "356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942", "store_name": "Mock Store from AIService", "valid_from": "2025-01-01", "valid_to": "2025-01-07", "store_address": "123 Mock St", "item_count": 1, "uploaded_by": null, "status": "processed", "store_id": 7 } [DB DEBUG] Final URLs for insert: { imageUrl: 'https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg', iconUrl: 'https://example.com/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp' } {"level":20,"time":1768078215559,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","query":"\n INSERT INTO flyers (\n file_name, image_url, icon_url, checksum, store_id, valid_from, valid_to, store_address,\n status, item_count, uploaded_by\n )\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)\n RETURNING *;\n ","values":["cleanup-test-1768078198911.jpg","https://example.com/flyer-images/flyerFile-test-flyer-image-processed.jpeg","https://example.com/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp","356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942",7,"2025-01-01","2025-01-07","123 Mock St","processed",1,null],"msg":"[DB insertFlyer] Executing insert with the following values."} {"level":20,"time":1768078215562,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","query":"\n INSERT INTO flyer_items (\n flyer_id, item, price_display, price_in_cents, quantity, category_name, view_count, click_count\n )\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8)\n RETURNING *;\n ","values":[8,"Mocked Integration Item","$1.99",199,"each","Mock Category",0,0],"msg":"[DB insertFlyerItems] Executing bulk insert with the following values."} {"level":30,"time":1768078215566,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Successfully processed flyer: cleanup-test-1768078198911.jpg (ID: 8) with 1 items."} {"level":30,"time":1768078215576,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","pattern":"cache:flyers*","totalDeleted":0,"msg":"Cache invalidation completed"} {"level":30,"time":1768078215579,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","pattern":"cache:flyer*","totalDeleted":0,"msg":"Cache invalidation completed"} {"level":30,"time":1768078215580,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Successfully processed job and enqueued cleanup for flyer ID: 8"} {"level":30,"time":1768078215581,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"cleanup-test-1768078198911.jpg","checksum":"356efedc25b4717cf9a802cd5467fd91b9bfa900da3a3cdea8d6cd99dab8c942","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","pattern":"cache:flyer-items*","totalDeleted":0,"msg":"Cache invalidation completed"} {"level":30,"time":1768078215582,"pid":12017,"hostname":"27443fa088eb","returnValue":{"flyerId":8},"msg":"[flyer-processing] Job 7 completed successfully."} {"level":30,"time":1768078215588,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"cleanup-flyer-files","flyerId":8,"paths":["/app/flyer-images/flyerFile-test-flyer-image.jpg","/app/flyer-images/flyerFile-test-flyer-image-processed.jpeg","/app/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp"],"msg":"Picked up file cleanup job."} {"level":30,"time":1768078215592,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"cleanup-flyer-files","flyerId":8,"paths":["/app/flyer-images/flyerFile-test-flyer-image.jpg","/app/flyer-images/flyerFile-test-flyer-image-processed.jpeg","/app/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp"],"msg":"Successfully deleted temporary file: /app/flyer-images/flyerFile-test-flyer-image-processed.jpeg"} {"level":30,"time":1768078215592,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"cleanup-flyer-files","flyerId":8,"paths":["/app/flyer-images/flyerFile-test-flyer-image.jpg","/app/flyer-images/flyerFile-test-flyer-image-processed.jpeg","/app/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp"],"msg":"Successfully deleted temporary file: /app/flyer-images/flyerFile-test-flyer-image.jpg"} {"level":30,"time":1768078215595,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"cleanup-flyer-files","flyerId":8,"paths":["/app/flyer-images/flyerFile-test-flyer-image.jpg","/app/flyer-images/flyerFile-test-flyer-image-processed.jpeg","/app/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp"],"msg":"Successfully deleted temporary file: /app/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp"} {"level":30,"time":1768078215595,"pid":12017,"hostname":"27443fa088eb","jobId":"7","jobName":"cleanup-flyer-files","flyerId":8,"paths":["/app/flyer-images/flyerFile-test-flyer-image.jpg","/app/flyer-images/flyerFile-test-flyer-image-processed.jpeg","/app/flyer-images/icons/icon-flyerFile-test-flyer-image-processed.webp"],"msg":"Successfully deleted all 3 temporary files."} {"level":30,"time":1768078215597,"pid":12017,"hostname":"27443fa088eb","returnValue":{"status":"success","deletedCount":3},"msg":"[file-cleanup] Job 7 completed successfully."} {"level":20,"time":1768078236205,"pid":12017,"hostname":"27443fa088eb","request_id":"80d93e6e-a528-4eda-93e0-ba96f7afa32b","user_id":"00000000-0000-0000-0000-000000000007","ip_address":"::ffff:127.0.0.1","method":"GET","originalUrl":"/api/health","msg":"[Request Logger] INCOMING"} {"level":40,"time":1768078236207,"pid":12017,"hostname":"27443fa088eb","request_id":"80d93e6e-a528-4eda-93e0-ba96f7afa32b","user_id":"00000000-0000-0000-0000-000000000007","ip_address":"::ffff:127.0.0.1","user_id":"00000000-0000-0000-0000-000000000007","method":"GET","originalUrl":"/api/health","statusCode":404,"statusMessage":"Not Found","duration":"2.42","req":{"headers":{"host":"localhost:3001","user-agent":"curl/7.81.0","accept":"*/*"}},"msg":"Request completed with client error"} {"level":20,"time":1768078269181,"pid":12017,"hostname":"27443fa088eb","request_id":"231d39dc-0668-45e8-8cc4-6bef960c0949","user_id":"00000000-0000-0000-0000-000000000008","ip_address":"::ffff:127.0.0.1","method":"GET","originalUrl":"/api/health","msg":"[Request Logger] INCOMING"} {"level":40,"time":1768078269183,"pid":12017,"hostname":"27443fa088eb","request_id":"231d39dc-0668-45e8-8cc4-6bef960c0949","user_id":"00000000-0000-0000-0000-000000000008","ip_address":"::ffff:127.0.0.1","user_id":"00000000-0000-0000-0000-000000000008","method":"GET","originalUrl":"/api/health","statusCode":404,"statusMessage":"Not Found","duration":"1.46","req":{"headers":{"host":"localhost:3001","user-agent":"curl/7.81.0","accept":"*/*"}},"msg":"Request completed with client error"} {"level":20,"time":1768078302167,"pid":12017,"hostname":"27443fa088eb","request_id":"61445a51-4b7a-4d03-8330-8c596a2ec73e","user_id":"00000000-0000-0000-0000-000000000009","ip_address":"::ffff:127.0.0.1","method":"GET","originalUrl":"/api/health","msg":"[Request Logger] INCOMING"} {"level":40,"time":1768078302170,"pid":12017,"hostname":"27443fa088eb","request_id":"61445a51-4b7a-4d03-8330-8c596a2ec73e","user_id":"00000000-0000-0000-0000-000000000009","ip_address":"::ffff:127.0.0.1","user_id":"00000000-0000-0000-0000-000000000009","method":"GET","originalUrl":"/api/health","statusCode":404,"statusMessage":"Not Found","duration":"2.20","req":{"headers":{"host":"localhost:3001","user-agent":"curl/7.81.0","accept":"*/*"}},"msg":"Request completed with client error"} {"level":20,"time":1768078335264,"pid":12017,"hostname":"27443fa088eb","request_id":"b5fa9b86-aea7-4fd4-8f52-5d0685d7fd01","user_id":"00000000-0000-0000-0000-000000000010","ip_address":"::ffff:127.0.0.1","method":"GET","originalUrl":"/api/health","msg":"[Request Logger] INCOMING"} {"level":40,"time":1768078335268,"pid":12017,"hostname":"27443fa088eb","request_id":"b5fa9b86-aea7-4fd4-8f52-5d0685d7fd01","user_id":"00000000-0000-0000-0000-000000000010","ip_address":"::ffff:127.0.0.1","user_id":"00000000-0000-0000-0000-000000000010","method":"GET","originalUrl":"/api/health","statusCode":404,"statusMessage":"Not Found","duration":"4.20","req":{"headers":{"host":"localhost:3001","user-agent":"curl/7.81.0","accept":"*/*"}},"msg":"Request completed with client error"} {"level":20,"time":1768078368189,"pid":12017,"hostname":"27443fa088eb","request_id":"33fbaef8-4da1-49b5-80e2-cf2467e12573","user_id":"00000000-0000-0000-0000-000000000011","ip_address":"::ffff:127.0.0.1","method":"GET","originalUrl":"/api/health","msg":"[Request Logger] INCOMING"} {"level":40,"time":1768078368191,"pid":12017,"hostname":"27443fa088eb","request_id":"33fbaef8-4da1-49b5-80e2-cf2467e12573","user_id":"00000000-0000-0000-0000-000000000011","ip_address":"::ffff:127.0.0.1","user_id":"00000000-0000-0000-0000-000000000011","method":"GET","originalUrl":"/api/health","statusCode":404,"statusMessage":"Not Found","duration":"1.80","req":{"headers":{"host":"localhost:3001","user-agent":"curl/7.81.0","accept":"*/*"}},"msg":"Request completed with client error"} stderr | src/tests/integration/flyer-processing.integration.test.ts > Flyer Processing Background Job Integration Test [TEST TEARDOWN] Closing in-process workers... ❯  integration  src/tests/integration/flyer-processing.integration.test.ts (7 tests | 5 failed) 265052ms ✓ should successfully process a flyer for an AUTHENTICATED user via the background queue  3747ms ✓ should successfully process a flyer for an ANONYMOUS user via the background queue  3122ms  × should strip EXIF data from uploaded JPEG images during processing 3371ms  × should strip metadata from uploaded PNG images during processing 6670ms  × should handle a failure from the AI service gracefully 3064ms  × should handle a database failure during flyer creation 9112ms  × should NOT clean up temporary files when a job fails, to allow for manual inspection 180634ms stdout | src/tests/integration/gamification.integration.test.ts > Gamification Flow Integration Test ┌─────────┬────────────────────────────────────────┬─────────────────────┬─────────┐ │ (index) │ user_id │ email │ role │ ├─────────┼────────────────────────────────────────┼─────────────────────┼─────────┤ │ 0 │ '34261825-38f4-4bf1-afc6-e5acd0a4cba4' │ 'admin@example.com' │ 'admin' │ │ 1 │ '63817122-6ba9-4d89-a88f-a90be10ab076' │ 'user@example.com' │ 'user' │ └─────────┴────────────────────────────────────────┴─────────────────────┴─────────┘ stdout | src/tests/integration/gamification.integration.test.ts > Gamification Flow Integration Test > should award the "First Upload" achievement after a user successfully uploads and processes their first flyer [DEBUG] generateFileChecksum processing file: name="gamification-test-flyer-1768078383219.jpg", type="image/jpeg", size=193338 stderr | src/tests/integration/gamification.integration.test.ts > Gamification Flow Integration Test > should award the "First Upload" achievement after a user successfully uploads and processes their first flyer -------------------------------------------------------------------------------- [TEST DEBUG] STARTING UPLOAD STEP [TEST DEBUG] Env FRONTEND_URL: "https://example.com" [TEST DEBUG] Sending baseUrl field: "https://example.com" -------------------------------------------------------------------------------- stderr | src/tests/integration/gamification.integration.test.ts > Gamification Flow Integration Test > should award the "First Upload" achievement after a user successfully uploads and processes their first flyer [DEBUG] aiService.enqueueFlyerProcessing resolved baseUrl: "https://example.com" {"level":30,"time":1768078383279,"pid":12017,"hostname":"27443fa088eb","jobId":"8","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"gamification-test-flyer-1768078383219.jpg","checksum":"03ba21201b8109d493ea76f8eb5a596f07b9b8043588174dbdd9b39acd048268","userId":"eccecb2b-2df4-4685-b519-c443a78f6ad6","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","msg":"Picked up flyer processing job."} [WORKER DEBUG] ProcessingService: Calling fileHandler.prepareImageInputs for /app/flyer-images/flyerFile-test-flyer-image.jpg [WORKER DEBUG] FlyerFileHandler: prepareImageInputs called for /app/flyer-images/flyerFile-test-flyer-image.jpg [WORKER DEBUG] FlyerFileHandler: Detected extension: .jpg {"level":30,"time":1768078383281,"pid":12017,"hostname":"27443fa088eb","jobId":"8","jobName":"process-flyer","filePath":"/app/flyer-images/flyerFile-test-flyer-image.jpg","originalFileName":"gamification-test-flyer-1768078383219.jpg","checksum":"03ba21201b8109d493ea76f8eb5a596f07b9b8043588174dbdd9b39acd048268","userId":"eccecb2b-2df4-4685-b519-c443a78f6ad6","submitterIp":"::ffff:127.0.0.1","baseUrl":"https://example.com","from":"/app/flyer-images/flyerFile-test-flyer-image.jpg","to":"/app/flyer-images/flyerFile-test-flyer-image-processed.jpeg","msg":"Processing JPEG to strip EXIF data."} stderr | src/tests/integration/gamification.integration.test.ts > Gamification Flow Integration Test > should award the "First Upload" achievement after a user successfully uploads and processes their first flyer -------------------------------------------------------------------------------- [TEST DEBUG] Upload Response Status: 202 [TEST DEBUG] Upload Response Body: { "success": true, "data": { "message": "Flyer accepted for processing.", "jobId": "8" } } -------------------------------------------------------------------------------- stdout | src/tests/integration/gamification.integration.test.ts > Gamification Flow Integration Test > Legacy Flyer Upload > should process a legacy upload and save fully qualified URLs to the database [DEBUG] generateFileChecksum processing file: name="legacy-upload-test-1768078383316.jpg", type="image/jpeg", size=193325