
> 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] ----------------------------------


[1m[46m RUN [49m[22m [36mv4.0.16 [39m[90m/app[39m

--- [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

[90mstdout[2m | src/tests/integration/flyer-processing.integration.test.ts[2m > [22m[2mFlyer Processing Background Job Integration Test[2m > [22m[2mshould successfully process a flyer for an AUTHENTICATED user via the background queue
[22m[39mΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé (index) Γöé user_id                                Γöé email               Γöé role    Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé 0       Γöé [32m'34261825-38f4-4bf1-afc6-e5acd0a4cba4'[39m Γöé [32m'admin@example.com'[39m Γöé [32m'admin'[39m Γöé
Γöé 1       Γöé [32m'63817122-6ba9-4d89-a88f-a90be10ab076'[39m Γöé [32m'user@example.com'[39m  Γöé [32m'user'[39m  Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ

{"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

[90mstdout[2m | src/tests/integration/flyer-processing.integration.test.ts[2m > [22m[2mFlyer Processing Background Job Integration Test[2m > [22m[2mshould successfully process a flyer for an AUTHENTICATED user via the background queue
[22m[39m[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

[90mstdout[2m | src/tests/integration/flyer-processing.integration.test.ts[2m > [22m[2mFlyer Processing Background Job Integration Test[2m > [22m[2mshould successfully process a flyer for an ANONYMOUS user via the background queue
[22m[39m[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

[90mstdout[2m | src/tests/integration/flyer-processing.integration.test.ts[2m > [22m[2mFlyer Processing Background Job Integration Test[2m > [22m[2mshould strip EXIF data from uploaded JPEG images during processing
[22m[39m[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

[90mstdout[2m | src/tests/integration/flyer-processing.integration.test.ts[2m > [22m[2mFlyer Processing Background Job Integration Test[2m > [22m[2mshould strip metadata from uploaded PNG images during processing
[22m[39m[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
[90mstdout[2m | src/tests/integration/flyer-processing.integration.test.ts[2m > [22m[2mFlyer Processing Background Job Integration Test[2m > [22m[2mshould handle a failure from the AI service gracefully
[22m[39m[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

[90mstdout[2m | src/tests/integration/flyer-processing.integration.test.ts[2m > [22m[2mFlyer Processing Background Job Integration Test[2m > [22m[2mshould handle a database failure during flyer creation
[22m[39m[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

[90mstdout[2m | src/tests/integration/flyer-processing.integration.test.ts[2m > [22m[2mFlyer Processing Background Job Integration Test[2m > [22m[2mshould NOT clean up temporary files when a job fails, to allow for manual inspection
[22m[39m[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...

 [31mΓ¥»[39m [30m[45m integration [49m[39m src/tests/integration/flyer-processing.integration.test.ts [2m([22m[2m7 tests[22m[2m | [22m[31m5 failed[39m[2m)[22m[33m 265052[2mms[22m[39m
     [33m[2mΓ£ô[22m[39m should successfully process a flyer for an AUTHENTICATED user via the background queue [33m 3747[2mms[22m[39m
     [33m[2mΓ£ô[22m[39m should successfully process a flyer for an ANONYMOUS user via the background queue [33m 3122[2mms[22m[39m
[31m     [31m├ù[31m should strip EXIF data from uploaded JPEG images during processing[39m[33m 3371[2mms[22m[39m
[31m     [31m├ù[31m should strip metadata from uploaded PNG images during processing[39m[33m 6670[2mms[22m[39m
[31m     [31m├ù[31m should handle a failure from the AI service gracefully[39m[33m 3064[2mms[22m[39m
[31m     [31m├ù[31m should handle a database failure during flyer creation[39m[33m 9112[2mms[22m[39m
[31m     [31m├ù[31m should NOT clean up temporary files when a job fails, to allow for manual inspection[39m[33m 180634[2mms[22m[39m
[90mstdout[2m | src/tests/integration/gamification.integration.test.ts[2m > [22m[2mGamification Flow Integration Test
[22m[39mΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé (index) Γöé user_id                                Γöé email               Γöé role    Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé 0       Γöé [32m'34261825-38f4-4bf1-afc6-e5acd0a4cba4'[39m Γöé [32m'admin@example.com'[39m Γöé [32m'admin'[39m Γöé
Γöé 1       Γöé [32m'63817122-6ba9-4d89-a88f-a90be10ab076'[39m Γöé [32m'user@example.com'[39m  Γöé [32m'user'[39m  Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ

[90mstdout[2m | src/tests/integration/gamification.integration.test.ts[2m > [22m[2mGamification Flow Integration Test[2m > [22m[2mshould award the "First Upload" achievement after a user successfully uploads and processes their first flyer
[22m[39m[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"
  }
}
--------------------------------------------------------------------------------

[90mstdout[2m | src/tests/integration/gamification.integration.test.ts[2m > [22m[2mGamification Flow Integration Test[2m > [22m[2mLegacy Flyer Upload[2m > [22m[2mshould process a legacy upload and save fully qualified URLs to the database
[22m[39m[DEBUG] generateFileChecksum processing file: name="legacy-upload-test-1768078383316.jpg", type="image/jpeg", size=193325

