recipe-api  | Prisma schema loaded from prisma/schema.prisma
recipe-api  | Datasource "db": MySQL database "recipe_app" at "recipe-db:3306"
recipe-api  | 
recipe-api  | 25 migrations found in prisma/migrations
recipe-api  | 
recipe-api  | 
recipe-api  | No pending migrations to apply.
recipe-api  | npm notice
recipe-api  | npm notice New major version of npm available! 10.9.7 -> 11.13.0
recipe-api  | npm notice Changelog: https://github.com/npm/cli/releases/tag/v11.13.0
recipe-api  | npm notice To update run: npm install -g npm@11.13.0
recipe-api  | npm notice
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[NestFactory] [39m[32mStarting Nest application...[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[InstanceLoader] [39m[32mPrismaModule dependencies initialized[39m[38;5;3m +34ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[InstanceLoader] [39m[32mPassportModule dependencies initialized[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[InstanceLoader] [39m[32mThrottlerModule dependencies initialized[39m[38;5;3m +1ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[InstanceLoader] [39m[32mJwtModule dependencies initialized[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[InstanceLoader] [39m[32mAiModule dependencies initialized[39m[38;5;3m +1ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[InstanceLoader] [39m[32mCategoriesModule dependencies initialized[39m[38;5;3m +2ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[InstanceLoader] [39m[32mMealPlanModule dependencies initialized[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[InstanceLoader] [39m[32mHealthModule dependencies initialized[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[InstanceLoader] [39m[32mQuickImportModule dependencies initialized[39m[38;5;3m +1ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[InstanceLoader] [39m[32mAppModule dependencies initialized[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[InstanceLoader] [39m[32mAuthModule dependencies initialized[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[InstanceLoader] [39m[32mInventoryModule dependencies initialized[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[InstanceLoader] [39m[32mRecipesModule dependencies initialized[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[InstanceLoader] [39m[32mPantryModule dependencies initialized[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[InstanceLoader] [39m[32mReceiptAliasModule dependencies initialized[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[InstanceLoader] [39m[32mUsersModule dependencies initialized[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[InstanceLoader] [39m[32mUserProductsModule dependencies initialized[39m[38;5;3m +1ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[InstanceLoader] [39m[32mReceiptImportModule dependencies initialized[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[InstanceLoader] [39m[32mProductsModule dependencies initialized[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RoutesResolver] [39m[32mHealthController {/api/health}:[39m[38;5;3m +9ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/health, GET} route[39m[38;5;3m +4ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/health/db, GET} route[39m[38;5;3m +1ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RoutesResolver] [39m[32mProductsController {/api/products}:[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/products, GET} route[39m[38;5;3m +1ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/products/tags, GET} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/products/duplicates, GET} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/products/merge-preview, GET} route[39m[38;5;3m +1ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/products/backfill-canonical, POST} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/products/pending, GET} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/products/ai-categorize-bulk, POST} route[39m[38;5;3m +1ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/products/deleted, GET} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/products/mine, GET} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/products/:id, GET} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/products/private, POST} route[39m[38;5;3m +1ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/products/:id/suggest-category, GET} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/products, POST} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/products/pending, POST} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/products/merge, POST} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/products/:id/canonical-name, PATCH} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/products/:id/tags, PUT} route[39m[38;5;3m +1ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/products/:id/nutrition, PUT} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/products/:id, PATCH} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/products/:id/permanent, DELETE} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/products/:id, DELETE} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/products/:id/status, PATCH} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/products/:id/restore, POST} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/products/reset-all, POST} route[39m[38;5;3m +1ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/products/bulk-update, POST} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RoutesResolver] [39m[32mAiController {/api/ai}:[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/ai/models, GET} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RoutesResolver] [39m[32mCategoriesController {/api/categories}:[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/categories, GET} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/categories/tree, GET} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RoutesResolver] [39m[32mInventoryController {/api/inventory}:[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/inventory/:id/consume, POST} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/inventory/:id/consumption-history, GET} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/inventory, GET} route[39m[38;5;3m +1ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/inventory/expiring, GET} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/inventory, POST} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/inventory/:id, PATCH} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/inventory/:id, DELETE} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RoutesResolver] [39m[32mRecipesController {/api/recipes}:[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/recipes/parse-markdown, POST} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/recipes, GET} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/recipes/:id/inventory-preview, GET} route[39m[38;5;3m +1ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/recipes/:id, GET} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/recipes, POST} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/recipes/:id, PATCH} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/recipes/:id, DELETE} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/recipes/:id/image, POST} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/recipes/:id/visibility, PATCH} route[39m[38;5;3m +1ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/recipes/:id/share, POST} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/recipes/:id/share/:username, DELETE} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RoutesResolver] [39m[32mQuickImportController {/api/quick-import}:[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/quick-import, POST} route[39m[38;5;3m +1ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RoutesResolver] [39m[32mPantryController {/api/pantry}:[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/pantry, GET} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/pantry, POST} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/pantry/:id, DELETE} route[39m[38;5;3m +1ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RoutesResolver] [39m[32mMealPlanController {/api/meal-plan}:[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/meal-plan, GET} route[39m[38;5;3m +1ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/meal-plan/shopping-list, GET} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/meal-plan/inventory-compare, GET} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/meal-plan, POST} route[39m[38;5;3m +2ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/meal-plan/:date, DELETE} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RoutesResolver] [39m[32mReceiptImportController {/api/receipt-import}:[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/receipt-import, POST} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RoutesResolver] [39m[32mReceiptAliasController {/api/receipt-aliases}:[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/receipt-aliases, GET} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/receipt-aliases, POST} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/receipt-aliases/:id, DELETE} route[39m[38;5;3m +1ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RoutesResolver] [39m[32mAuthController {/api/auth}:[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/auth/register, POST} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/auth/login, POST} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RoutesResolver] [39m[32mUsersController {/api/users}:[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/users/me, GET} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/users/me, PATCH} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/users, GET} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/users/:id/role, PATCH} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/users/:id/premium, PATCH} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/users/:id/recipe-sharing, PATCH} route[39m[38;5;3m +1ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/users, POST} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/users/:id, DELETE} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/users/:id/reset-password, POST} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/users/:id/email, PATCH} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RoutesResolver] [39m[32mUserProductsController {/api/user-products}:[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/user-products, GET} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/user-products, POST} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[RouterExplorer] [39m[32mMapped {/api/user-products/:productId, DELETE} route[39m[38;5;3m +0ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[PrismaService] [39m[32mFörsöker ansluta till databasen (försök 1/10)...[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[PrismaService] [39m[32mDatabasanslutning etablerad.[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:14 PM [32m    LOG[39m [38;5;3m[NestApplication] [39m[32mNest application successfully started[39m[38;5;3m +13ms[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:24 PM [32m    LOG[39m [38;5;3m[JwtStrategy] [39m[32mValidating token for user ID: 2, Username: Nadmin[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:24 PM [32m    LOG[39m [38;5;3m[JwtAuthGuard] [39m[32mAuthenticated user ID: 2[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:28 PM [32m    LOG[39m [38;5;3m[JwtStrategy] [39m[32mValidating token for user ID: 2, Username: Nadmin[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:28 PM [32m    LOG[39m [38;5;3m[JwtAuthGuard] [39m[32mAuthenticated user ID: 2[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:35 PM [32m    LOG[39m [38;5;3m[JwtStrategy] [39m[32mValidating token for user ID: 2, Username: Nadmin[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:35 PM [32m    LOG[39m [38;5;3m[JwtAuthGuard] [39m[32mAuthenticated user ID: 2[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:40 PM [32m    LOG[39m [38;5;3m[ReceiptImportService] [39m[32m[ReceiptDecision] start raw="BRIOCHE SESAM" signal="BRIOCHE SESAM Brioche Sesam" | match matchedProductId=null suggestedProductId=31 | incoming category="Kaffebröd" confidence=medium fallback=false | rule miss | ai skipped, current -> "Kaffebröd" | final -> "Kaffebröd" (medium)[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:40 PM [32m    LOG[39m [38;5;3m[ReceiptImportService] [39m[32m[ReceiptDecision] start raw="GURKA SVERIGE ST" signal="GURKA SVERIGE ST Gurka Sverige St" | match matchedProductId=null suggestedProductId=32 | incoming category="Övriga grönsaker" confidence=medium fallback=false | rule miss | ai skipped, current -> "Övriga grönsaker" | final -> "Övriga grönsaker" (medium)[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:40 PM [32m    LOG[39m [38;5;3m[ReceiptImportService] [39m[32m[ReceiptDecision] start raw="ROAST`N TOAST 800G" signal="ROAST`N TOAST 800G Roast`n Toast 800g" | match matchedProductId=null suggestedProductId=33 | incoming category="Rostbröd" confidence=medium fallback=false | rule miss | ai skipped, current -> "Rostbröd" | final -> "Rostbröd" (medium)[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:40 PM [32m    LOG[39m [38;5;3m[ReceiptImportService] [39m[32m[ReceiptDecision] start raw="POTATIS FAST" signal="POTATIS FAST Potatis Fast" | match matchedProductId=null suggestedProductId=34 | incoming category="Rotsaker" confidence=medium fallback=false | rule miss | ai skipped, current -> "Rotsaker" | final -> "Rotsaker" (medium)[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:40 PM [32m    LOG[39m [38;5;3m[ReceiptImportService] [39m[32m[ReceiptDecision] start raw="TOMATER" signal="TOMATER Tomater" | match matchedProductId=null suggestedProductId=35 | incoming category="Tomater" confidence=medium fallback=false | rule miss | ai skipped, current -> "Tomater" | final -> "Tomater" (medium)[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:40 PM [32m    LOG[39m [38;5;3m[ReceiptImportService] [39m[32m[ReceiptDecision] start raw="LÖK RÖD" signal="LÖK RÖD Lök Röd" | match matchedProductId=null suggestedProductId=36 | incoming category="Lök" confidence=medium fallback=false | rule miss | ai skipped, current -> "Lök" | final -> "Lök" (medium)[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:40 PM [32m    LOG[39m [38;5;3m[ReceiptImportService] [39m[32m[ReceiptDecision] start raw="SALAMI PEPPAR 150G" signal="SALAMI PEPPAR 150G Salami Peppar 150g" | match matchedProductId=null suggestedProductId=37 | incoming category="Skivat pålägg" confidence=medium fallback=false | rule miss | ai skipped, current -> "Skivat pålägg" | final -> "Skivat pålägg" (medium)[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:40 PM [32m    LOG[39m [38;5;3m[ReceiptImportService] [39m[32m[ReceiptDecision] start raw="BLANDFÄRS 20% IMP" signal="BLANDFÄRS 20% IMP Blandfärs 20% Imp" | match matchedProductId=null suggestedProductId=38 | incoming category="Köttfärs" confidence=medium fallback=false | rule miss | ai skipped, current -> "Köttfärs" | final -> "Köttfärs" (medium)[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:40 PM [32m    LOG[39m [38;5;3m[ReceiptImportService] [39m[32m[ReceiptDecision] start raw="DONUT BELG CHOKLAD" signal="DONUT BELG CHOKLAD Donut Belg Choklad" | match matchedProductId=null suggestedProductId=39 | incoming category="Kaffebröd" confidence=medium fallback=false | rule hit -> "Kondis & fika > Kaffebröd" (high) | ai skipped, current -> "Kaffebröd" | final -> "Kaffebröd" (medium)[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:40 PM [32m    LOG[39m [38;5;3m[ReceiptImportService] [39m[32m[ReceiptDecision] start raw="DONUT GOLDENFRY" signal="DONUT GOLDENFRY Donut Goldenfry" | match matchedProductId=null suggestedProductId=40 | incoming category="Kaffebröd" confidence=medium fallback=false | rule hit -> "Kondis & fika > Kaffebröd" (high) | ai skipped, current -> "Kaffebröd" | final -> "Kaffebröd" (medium)[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:40 PM [32m    LOG[39m [38;5;3m[ReceiptImportService] [39m[32m[ReceiptDecision] start raw="WIENERBRÖD80G VANILJ" signal="WIENERBRÖD80G VANILJ Wienerbröd80g Vanilj" | match matchedProductId=null suggestedProductId=41 | incoming category="Kaffebröd" confidence=medium fallback=false | rule miss | ai skipped, current -> "Kaffebröd" | final -> "Kaffebröd" (medium)[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:41 PM [32m    LOG[39m [38;5;3m[ReceiptImportService] [39m[32m[ReceiptDecision] start raw="BACON 3X120G" signal="BACON 3X120G" | match matchedProductId=null suggestedProductId=null | rule miss | ai invoked | ai result -> "Chark > Köttbullar & färsprodukter" (high) | final -> "Chark > Köttbullar & färsprodukter" (high)[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:41 PM [32m    LOG[39m [38;5;3m[ReceiptImportService] [39m[32m[ReceiptDecision] start raw="VISPGRÄDDE 5DL" signal="VISPGRÄDDE 5DL" | match matchedProductId=null suggestedProductId=null | rule hit -> "Mejeri, ost & ägg > Matlagning" (high) | rule applied -> "Mejeri, ost & ägg > Matlagning" | ai skipped, current -> "Mejeri, ost & ägg > Matlagning" | final -> "Mejeri, ost & ägg > Matlagning" (high)[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:41 PM [32m    LOG[39m [38;5;3m[ReceiptImportService] [39m[32m[ReceiptDecision] start raw="STANDMJÖLK ESL 1,5L" signal="STANDMJÖLK ESL 1,5L" | match matchedProductId=null suggestedProductId=null | rule hit -> "Mejeri, ost & ägg > Mjölk" (high) | rule applied -> "Mejeri, ost & ägg > Mjölk" | ai skipped, current -> "Mejeri, ost & ägg > Mjölk" | final -> "Mejeri, ost & ägg > Mjölk" (high)[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:42 PM [32m    LOG[39m [38;5;3m[ReceiptImportService] [39m[32m[ReceiptDecision] start raw="FILMJÖLK 3%" signal="FILMJÖLK 3%" | match matchedProductId=null suggestedProductId=null | rule miss | ai invoked | ai result -> "Mejeri, ost & ägg > Filmjölk & Yoghurt" (high) | final -> "Mejeri, ost & ägg > Filmjölk & Yoghurt" (high)[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:42 PM [32m    LOG[39m [38;5;3m[ReceiptImportService] [39m[32m[ReceiptDecision] start raw="ÄGG 24P INNE M" signal="ÄGG 24P INNE M" | match matchedProductId=null suggestedProductId=null | rule hit -> "Mejeri, ost & ägg" (high) | rule applied -> "Mejeri, ost & ägg" | ai skipped, current -> "Mejeri, ost & ägg" | final -> "Mejeri, ost & ägg" (high)[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:42 PM [32m    LOG[39m [38;5;3m[AiService] [39m[32mAI-guardrail: low konfidenspoäng → remappar "Dryck > Te & choklad" → L1 "Dryck"[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:42 PM [32m    LOG[39m [38;5;3m[ReceiptImportService] [39m[32m[ReceiptDecision] start raw="DRYCK MULTIVITAMIN" signal="DRYCK MULTIVITAMIN" | match matchedProductId=null suggestedProductId=null | rule miss | ai invoked | ai result -> "Dryck" (low) | final -> "Dryck" (low)[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:42 PM [32m    LOG[39m [38;5;3m[ReceiptImportService] [39m[32m[ReceiptDecision] start raw="SUPER CRUNCH 750G" signal="SUPER CRUNCH 750G" | match matchedProductId=null suggestedProductId=null | rule miss | ai invoked | ai result -> "Chips, snacks & dip > Chips" (high) | final -> "Chips, snacks & dip > Chips" (high)[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:43 PM [32m    LOG[39m [38;5;3m[ReceiptImportService] [39m[32m[ReceiptDecision] start raw="MEZZE MANICHE 500G" signal="MEZZE MANICHE 500G" | match matchedProductId=null suggestedProductId=null | rule miss | ai invoked | ai result -> "Vegetariskt" (high) | final -> "Vegetariskt" (high)[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:43 PM [32m    LOG[39m [38;5;3m[ReceiptImportService] [39m[32m[ReceiptDecision] start raw="CORNFLAKES 500G" signal="CORNFLAKES 500G" | match matchedProductId=null suggestedProductId=null | rule miss | ai invoked | ai result -> "Skafferi > Flingor, gryner & musli" (high) | final -> "Skafferi > Flingor, gryner & musli" (high)[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:43 PM [32m    LOG[39m [38;5;3m[ReceiptImportService] [39m[32m[ReceiptDecision] start raw="VANILLA CHAI 20P" signal="VANILLA CHAI 20P" | match matchedProductId=null suggestedProductId=null | rule hit -> "Te & choklad > Te" (high) | rule applied -> "Te & choklad > Te" | ai skipped, current -> "Te & choklad > Te" | final -> "Te & choklad > Te" (high)[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:44 PM [32m    LOG[39m [38;5;3m[ReceiptImportService] [39m[32m[ReceiptDecision] start raw="NAPPAR COLA 80G" signal="NAPPAR COLA 80G" | match matchedProductId=null suggestedProductId=null | rule miss | ai invoked | ai result -> "Dryck > Läsk och Energidryck" (high) | final -> "Dryck > Läsk och Energidryck" (high)[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:44 PM [32m    LOG[39m [38;5;3m[ReceiptImportService] [39m[32m[ReceiptDecision] start raw="NAPPAR SOUR 80G" signal="NAPPAR SOUR 80G" | match matchedProductId=null suggestedProductId=null | rule miss | ai invoked | ai result -> "Chips, snacks & dip > Chips" (high) | final -> "Chips, snacks & dip > Chips" (high)[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:44 PM [32m    LOG[39m [38;5;3m[ReceiptImportService] [39m[32m[ReceiptDecision] start raw="SNICKERS" signal="SNICKERS" | match matchedProductId=null suggestedProductId=null | rule miss | ai invoked | ai result -> "Choklad > Chokladkakor & rullar" (high) | final -> "Choklad > Chokladkakor & rullar" (high)[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:45 PM [32m    LOG[39m [38;5;3m[ReceiptImportService] [39m[32m[ReceiptDecision] start raw="NÖTMIX KLASSISK" signal="NÖTMIX KLASSISK" | match matchedProductId=null suggestedProductId=null | rule miss | ai invoked | ai result -> "Skafferi > Flingor, gryner & musli" (high) | final -> "Skafferi > Flingor, gryner & musli" (high)[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:46 PM [32m    LOG[39m [38;5;3m[ReceiptImportService] [39m[32m[ReceiptDecision] start raw="PEPSI MAX 50CL" signal="PEPSI MAX 50CL" | match matchedProductId=null suggestedProductId=null | rule miss | ai invoked | ai result -> "Dryck > Läsk och Energidryck" (high) | final -> "Dryck > Läsk och Energidryck" (high)[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:46 PM [32m    LOG[39m [38;5;3m[JwtStrategy] [39m[32mValidating token for user ID: 2, Username: Nadmin[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:46 PM [32m    LOG[39m [38;5;3m[JwtAuthGuard] [39m[32mAuthenticated user ID: 2[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:46 PM [32m    LOG[39m [38;5;3m[JwtStrategy] [39m[32mValidating token for user ID: 2, Username: Nadmin[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:06:46 PM [32m    LOG[39m [38;5;3m[JwtAuthGuard] [39m[32mAuthenticated user ID: 2[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:07:15 PM [32m    LOG[39m [38;5;3m[JwtStrategy] [39m[32mValidating token for user ID: 2, Username: Nadmin[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:07:15 PM [32m    LOG[39m [38;5;3m[JwtAuthGuard] [39m[32mAuthenticated user ID: 2[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:07:38 PM [32m    LOG[39m [38;5;3m[JwtStrategy] [39m[32mValidating token for user ID: 2, Username: Nadmin[39m
recipe-api  | [32m[Nest] 1  - [39m05/02/2026, 9:07:38 PM [32m    LOG[39m [38;5;3m[JwtAuthGuard] [39m[32mAuthenticated user ID: 2[39m
