* Extended functionalities

* Added different UIs
This commit is contained in:
2026-06-24 21:43:40 +02:00
parent 282f4864c4
commit f15bb7a916
348 changed files with 59057 additions and 498 deletions

View File

@@ -0,0 +1,157 @@
-- DailyMeals diet tracking module
-- Apply manually on PostgreSQL (database-first; EF does not run migrations).
-- Schema: diet (same as existing recipe tables)
--
-- Inspired by patterns from MyFitnessPal / Lifesum (meal + macro logging),
-- WaterMinder / Hydro Coach (hydration goals + quick-add volumes), and
-- generic reminder schedules stored server-side for client push/local alarms.
BEGIN;
-- ---------------------------------------------------------------------------
-- Daily nutrition & hydration targets (one row per user)
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS diet."UserDailyGoals" (
"UserId" uuid PRIMARY KEY
REFERENCES diet."AspNetUsers"("Id") ON DELETE CASCADE,
"CalorieGoal" int NULL CHECK ("CalorieGoal" IS NULL OR "CalorieGoal" >= 0),
"ProteinGoalG" numeric(6,2) NULL CHECK ("ProteinGoalG" IS NULL OR "ProteinGoalG" >= 0),
"FatGoalG" numeric(6,2) NULL CHECK ("FatGoalG" IS NULL OR "FatGoalG" >= 0),
"CarbsGoalG" numeric(6,2) NULL CHECK ("CarbsGoalG" IS NULL OR "CarbsGoalG" >= 0),
"WaterGoalMl" int NULL CHECK ("WaterGoalMl" IS NULL OR "WaterGoalMl" > 0),
"CreatedAt" timestamptz NOT NULL DEFAULT now(),
"UpdatedAt" timestamptz NULL
);
COMMENT ON TABLE diet."UserDailyGoals" IS 'Per-user daily calorie, macro, and hydration targets (Lifesum-style goals).';
-- ---------------------------------------------------------------------------
-- Drink catalog (reference data; quick-add presets like WaterMinder)
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS diet."DrinkCatalog" (
"Id" serial PRIMARY KEY,
"Code" varchar(32) NOT NULL UNIQUE,
"Name" varchar(100) NOT NULL,
"DefaultVolumeMl" int NOT NULL CHECK ("DefaultVolumeMl" > 0),
"CaloriesPer100Ml" numeric(6,2) NULL CHECK ("CaloriesPer100Ml" IS NULL OR "CaloriesPer100Ml" >= 0),
"IconEmoji" varchar(16) NULL,
"SortOrder" int NOT NULL DEFAULT 0,
"IsActive" boolean NOT NULL DEFAULT true
);
COMMENT ON TABLE diet."DrinkCatalog" IS 'Preset drinks for one-tap logging (water, tea, coffee, etc.).';
INSERT INTO diet."DrinkCatalog" ("Code", "Name", "DefaultVolumeMl", "CaloriesPer100Ml", "IconEmoji", "SortOrder")
VALUES
('water', 'Water', 250, 0, '💧', 1),
('tea', 'Tea', 200, 1, '🍵', 2),
('coffee', 'Coffee', 150, 2, '', 3),
('juice', 'Juice', 200, 45, '🧃', 4),
('milk', 'Milk', 250, 42, '🥛', 5),
('soda', 'Soft drink', 330, 42, '🥤', 6),
('other', 'Other drink', 250, NULL, '🍶', 99)
ON CONFLICT ("Code") DO NOTHING;
-- ---------------------------------------------------------------------------
-- Logged meals (MyFitnessPal-style diary entries; optional recipe link)
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS diet."MealConsumptions" (
"Id" serial PRIMARY KEY,
"UserId" uuid NOT NULL
REFERENCES diet."AspNetUsers"("Id") ON DELETE CASCADE,
"RecipeId" int NULL
REFERENCES diet."Recipes"("Id") ON DELETE SET NULL,
"MealCategory" int NOT NULL CHECK ("MealCategory" BETWEEN 0 AND 4),
"LogDate" date NOT NULL,
"ConsumedAt" timestamptz NOT NULL,
"Name" varchar(255) NOT NULL,
"Portions" numeric(4,2) NOT NULL DEFAULT 1 CHECK ("Portions" > 0),
"Calories" int NULL CHECK ("Calories" IS NULL OR "Calories" >= 0),
"ProteinG" numeric(6,2) NULL CHECK ("ProteinG" IS NULL OR "ProteinG" >= 0),
"FatG" numeric(6,2) NULL CHECK ("FatG" IS NULL OR "FatG" >= 0),
"CarbsG" numeric(6,2) NULL CHECK ("CarbsG" IS NULL OR "CarbsG" >= 0),
"Notes" text NULL,
"CreatedAt" timestamptz NOT NULL DEFAULT now()
);
COMMENT ON TABLE diet."MealConsumptions" IS 'Meals the user ate; macros snapshotted at log time.';
COMMENT ON COLUMN diet."MealConsumptions"."MealCategory" IS '0=Breakfast, 1=SecondBreakfast, 2=Lunch, 3=Dinner, 4=Snack';
CREATE INDEX IF NOT EXISTS "IX_MealConsumptions_UserId_LogDate"
ON diet."MealConsumptions" ("UserId", "LogDate" DESC);
CREATE INDEX IF NOT EXISTS "IX_MealConsumptions_UserId_ConsumedAt"
ON diet."MealConsumptions" ("UserId", "ConsumedAt" DESC);
-- ---------------------------------------------------------------------------
-- Logged drinks (water tracker entries)
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS diet."DrinkConsumptions" (
"Id" serial PRIMARY KEY,
"UserId" uuid NOT NULL
REFERENCES diet."AspNetUsers"("Id") ON DELETE CASCADE,
"DrinkCatalogId" int NULL
REFERENCES diet."DrinkCatalog"("Id") ON DELETE SET NULL,
"LogDate" date NOT NULL,
"ConsumedAt" timestamptz NOT NULL,
"Name" varchar(255) NOT NULL,
"VolumeMl" int NOT NULL CHECK ("VolumeMl" > 0),
"Calories" int NULL CHECK ("Calories" IS NULL OR "Calories" >= 0),
"CreatedAt" timestamptz NOT NULL DEFAULT now()
);
COMMENT ON TABLE diet."DrinkConsumptions" IS 'Hydration and beverage intake log.';
CREATE INDEX IF NOT EXISTS "IX_DrinkConsumptions_UserId_LogDate"
ON diet."DrinkConsumptions" ("UserId", "LogDate" DESC);
-- ---------------------------------------------------------------------------
-- Reminders (server-stored schedules; clients handle local notifications)
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS diet."DietReminders" (
"Id" serial PRIMARY KEY,
"UserId" uuid NOT NULL
REFERENCES diet."AspNetUsers"("Id") ON DELETE CASCADE,
"ReminderType" int NOT NULL CHECK ("ReminderType" BETWEEN 0 AND 3),
"Title" varchar(120) NOT NULL,
"Message" varchar(500) NULL,
"TimeOfDay" time NOT NULL,
"DaysOfWeekMask" int NOT NULL DEFAULT 127 CHECK ("DaysOfWeekMask" BETWEEN 1 AND 127),
"MealCategory" int NULL CHECK ("MealCategory" IS NULL OR "MealCategory" BETWEEN 0 AND 4),
"IsEnabled" boolean NOT NULL DEFAULT true,
"CreatedAt" timestamptz NOT NULL DEFAULT now(),
"UpdatedAt" timestamptz NULL
);
COMMENT ON TABLE diet."DietReminders" IS 'Meal/water/custom reminder schedules (bitmask: Sun=1, Mon=2, Tue=4, Wed=8, Thu=16, Fri=32, Sat=64).';
COMMENT ON COLUMN diet."DietReminders"."ReminderType" IS '0=Water, 1=Meal, 2=Snack, 3=Custom';
CREATE INDEX IF NOT EXISTS "IX_DietReminders_UserId_IsEnabled"
ON diet."DietReminders" ("UserId", "IsEnabled");
-- ---------------------------------------------------------------------------
-- Optional views for reporting (API computes the same in LINQ)
-- ---------------------------------------------------------------------------
CREATE OR REPLACE VIEW diet."v_DailyMealTotals" AS
SELECT
"UserId",
"LogDate",
COALESCE(SUM("Calories"), 0)::int AS "TotalCalories",
COALESCE(SUM("ProteinG"), 0) AS "TotalProteinG",
COALESCE(SUM("FatG"), 0) AS "TotalFatG",
COALESCE(SUM("CarbsG"), 0) AS "TotalCarbsG",
COUNT(*)::int AS "MealCount"
FROM diet."MealConsumptions"
GROUP BY "UserId", "LogDate";
CREATE OR REPLACE VIEW diet."v_DailyDrinkTotals" AS
SELECT
"UserId",
"LogDate",
COALESCE(SUM("VolumeMl"), 0)::int AS "TotalWaterMl",
COALESCE(SUM("Calories"), 0)::int AS "TotalDrinkCalories",
COUNT(*)::int AS "DrinkCount"
FROM diet."DrinkConsumptions"
GROUP BY "UserId", "LogDate";
COMMIT;

View File

@@ -0,0 +1,144 @@
-- DailyMeals ingredient nutrition catalog
-- Reference data: macros per 100 g, grouped by food category (meat, vegetables, etc.)
-- Apply manually: psql "$DATABASE_URL" -f database/scripts/002_ingredient_nutrition_catalog.sql
BEGIN;
CREATE TABLE IF NOT EXISTS diet."IngredientCategories" (
"Id" serial PRIMARY KEY,
"Code" varchar(32) NOT NULL UNIQUE,
"Name" varchar(100) NOT NULL,
"SortOrder" int NOT NULL DEFAULT 0,
"IsActive" boolean NOT NULL DEFAULT true
);
COMMENT ON TABLE diet."IngredientCategories" IS 'Food groups for the nutrition catalog (meat, vegetables, etc.).';
CREATE TABLE IF NOT EXISTS diet."IngredientNutritionCatalog" (
"Id" serial PRIMARY KEY,
"CategoryId" int NOT NULL
REFERENCES diet."IngredientCategories"("Id") ON DELETE RESTRICT,
"Name" varchar(255) NOT NULL,
"CaloriesPer100G" int NOT NULL CHECK ("CaloriesPer100G" >= 0),
"ProteinGPer100G" numeric(6,2) NOT NULL DEFAULT 0 CHECK ("ProteinGPer100G" >= 0),
"FatGPer100G" numeric(6,2) NOT NULL DEFAULT 0 CHECK ("FatGPer100G" >= 0),
"CarbsGPer100G" numeric(6,2) NOT NULL DEFAULT 0 CHECK ("CarbsGPer100G" >= 0),
"FiberGPer100G" numeric(6,2) NULL CHECK ("FiberGPer100G" IS NULL OR "FiberGPer100G" >= 0),
"SortOrder" int NOT NULL DEFAULT 0,
"IsActive" boolean NOT NULL DEFAULT true,
CONSTRAINT "UQ_IngredientNutritionCatalog_Category_Name" UNIQUE ("CategoryId", "Name")
);
COMMENT ON TABLE diet."IngredientNutritionCatalog" IS 'Ingredient nutrition values per 100 g (calories, protein, fat, carbs).';
CREATE INDEX IF NOT EXISTS "IX_IngredientNutritionCatalog_CategoryId"
ON diet."IngredientNutritionCatalog" ("CategoryId", "SortOrder", "Name");
CREATE INDEX IF NOT EXISTS "IX_IngredientNutritionCatalog_Name"
ON diet."IngredientNutritionCatalog" (lower("Name"));
INSERT INTO diet."IngredientCategories" ("Code", "Name", "SortOrder")
VALUES
('meat', 'Meat', 1),
('poultry', 'Poultry', 2),
('fish', 'Fish', 3),
('seafood', 'Seafood', 4),
('vegetables', 'Vegetables', 5),
('fruits', 'Fruits', 6),
('dairy', 'Dairy', 7),
('eggs', 'Eggs', 8),
('grains', 'Grains', 9),
('legumes', 'Legumes', 10),
('nuts', 'Nuts & seeds', 11),
('oils', 'Oils & fats', 12)
ON CONFLICT ("Code") DO NOTHING;
-- Helper: insert items per category code
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", v."Name", v."Calories", v."Protein", v."Fat", v."Carbs", v."Fiber", v."SortOrder"
FROM (VALUES
-- meat
('meat', 'Beef sirloin', 271, 25.80, 18.00, 0.00, NULL, 1),
('meat', 'Pork loin', 242, 27.30, 14.00, 0.00, NULL, 2),
('meat', 'Lamb leg', 258, 25.60, 16.50, 0.00, NULL, 3),
('meat', 'Ground beef (15% fat)', 250, 26.00, 15.00, 0.00, NULL, 4),
('meat', 'Ham (cooked)', 145, 21.00, 6.00, 1.50, NULL, 5),
-- poultry
('poultry', 'Chicken breast', 165, 31.00, 3.60, 0.00, NULL, 1),
('poultry', 'Chicken thigh', 209, 26.00, 10.90, 0.00, NULL, 2),
('poultry', 'Turkey breast', 135, 30.00, 1.00, 0.00, NULL, 3),
('poultry', 'Duck breast', 202, 23.50, 11.20, 0.00, NULL, 4),
-- fish
('fish', 'Salmon', 208, 20.40, 13.40, 0.00, NULL, 1),
('fish', 'Cod', 82, 17.80, 0.70, 0.00, NULL, 2),
('fish', 'Tuna (canned in water)', 116, 25.50, 0.80, 0.00, NULL, 3),
('fish', 'Trout', 148, 20.80, 6.60, 0.00, NULL, 4),
('fish', 'Mackerel', 205, 18.60, 13.90, 0.00, NULL, 5),
-- seafood
('seafood', 'Shrimp', 99, 24.00, 0.30, 0.20, NULL, 1),
('seafood', 'Mussels', 172, 23.80, 4.50, 7.40, NULL, 2),
('seafood', 'Squid', 92, 15.60, 1.40, 3.10, NULL, 3),
('seafood', 'Crab', 97, 19.40, 1.50, 0.00, NULL, 4),
-- vegetables
('vegetables', 'Tomato', 18, 0.90, 0.20, 3.90, 1.20, 1),
('vegetables', 'Carrot', 41, 0.90, 0.20, 9.60, 2.80, 2),
('vegetables', 'Broccoli', 34, 2.80, 0.40, 6.60, 2.60, 3),
('vegetables', 'Spinach', 23, 2.90, 0.40, 3.60, 2.20, 4),
('vegetables', 'Potato', 77, 2.00, 0.10, 17.50, 2.20, 5),
('vegetables', 'Cucumber', 15, 0.70, 0.10, 3.60, 0.50, 6),
('vegetables', 'Bell pepper', 31, 1.00, 0.30, 6.00, 2.10, 7),
('vegetables', 'Onion', 40, 1.10, 0.10, 9.30, 1.70, 8),
('vegetables', 'Zucchini', 17, 1.20, 0.30, 3.10, 1.00, 9),
('vegetables', 'Mushrooms', 22, 3.10, 0.30, 3.30, 1.00, 10),
-- fruits
('fruits', 'Apple', 52, 0.30, 0.20, 13.80, 2.40, 1),
('fruits', 'Banana', 89, 1.10, 0.30, 22.80, 2.60, 2),
('fruits', 'Orange', 47, 0.90, 0.10, 11.80, 2.40, 3),
('fruits', 'Strawberries', 32, 0.70, 0.30, 7.70, 2.00, 4),
('fruits', 'Blueberries', 57, 0.70, 0.30, 14.50, 2.40, 5),
('fruits', 'Grapes', 69, 0.70, 0.20, 18.10, 0.90, 6),
('fruits', 'Avocado', 160, 2.00, 14.70, 8.50, 6.70, 7),
-- dairy
('dairy', 'Whole milk', 61, 3.20, 3.30, 4.80, NULL, 1),
('dairy', 'Skim milk', 34, 3.40, 0.10, 5.00, NULL, 2),
('dairy', 'Greek yogurt (plain)', 59, 10.00, 0.40, 3.60, NULL, 3),
('dairy', 'Cheddar cheese', 403, 25.00, 33.00, 1.30, NULL, 4),
('dairy', 'Mozzarella', 280, 28.00, 17.00, 3.10, NULL, 5),
('dairy', 'Cottage cheese', 98, 11.10, 4.30, 3.40, NULL, 6),
-- eggs
('eggs', 'Chicken egg (whole)', 155, 12.60, 10.60, 1.10, NULL, 1),
('eggs', 'Egg white', 52, 10.90, 0.20, 0.70, NULL, 2),
('eggs', 'Egg yolk', 322, 15.90, 26.50, 3.60, NULL, 3),
-- grains
('grains', 'White rice (cooked)', 130, 2.70, 0.30, 28.20, 0.40, 1),
('grains', 'Brown rice (cooked)', 123, 2.70, 1.00, 25.60, 1.60, 2),
('grains', 'Pasta (cooked)', 131, 5.00, 1.10, 25.00, 1.80, 3),
('grains', 'Oats (dry)', 389, 16.90, 6.90, 66.30, 10.60, 4),
('grains', 'Whole wheat bread', 247, 13.00, 3.40, 41.00, 6.00, 5),
('grains', 'White bread', 265, 9.00, 3.20, 49.00, 2.70, 6),
('grains', 'Quinoa (cooked)', 120, 4.40, 1.90, 21.30, 2.80, 7),
-- legumes
('legumes', 'Lentils (cooked)', 116, 9.00, 0.40, 20.10, 7.90, 1),
('legumes', 'Chickpeas (cooked)', 164, 8.90, 2.60, 27.40, 7.60, 2),
('legumes', 'Black beans (cooked)', 132, 8.90, 0.50, 23.70, 8.70, 3),
('legumes', 'Kidney beans (cooked)', 127, 8.70, 0.50, 22.80, 6.40, 4),
('legumes', 'Green peas (cooked)', 84, 5.40, 0.20, 15.60, 5.50, 5),
('legumes', 'Tofu (firm)', 76, 8.10, 4.80, 1.90, 0.30, 6),
-- nuts
('nuts', 'Almonds', 579, 21.20, 49.90, 21.60, 12.50, 1),
('nuts', 'Walnuts', 654, 15.20, 65.20, 13.70, 6.70, 2),
('nuts', 'Peanuts', 567, 25.80, 49.20, 16.10, 8.50, 3),
('nuts', 'Cashews', 553, 18.20, 43.80, 30.20, 3.30, 4),
('nuts', 'Sunflower seeds', 584, 20.80, 51.50, 20.00, 8.60, 5),
('nuts', 'Chia seeds', 486, 16.50, 30.70, 42.10, 34.40, 6),
-- oils
('oils', 'Olive oil', 884, 0.00, 100.00, 0.00, NULL, 1),
('oils', 'Butter', 717, 0.90, 81.00, 0.10, NULL, 2),
('oils', 'Coconut oil', 862, 0.00, 100.00, 0.00, NULL, 3),
('oils', 'Rapeseed oil', 884, 0.00, 100.00, 0.00, NULL, 4)
) AS v("CategoryCode", "Name", "Calories", "Protein", "Fat", "Carbs", "Fiber", "SortOrder")
JOIN diet."IngredientCategories" c ON c."Code" = v."CategoryCode"
ON CONFLICT ("CategoryId", "Name") DO NOTHING;
COMMIT;

View File

@@ -0,0 +1,83 @@
-- Add Polish display names to the ingredient nutrition catalog.
-- Safe to re-run. Apply after 002_ingredient_nutrition_catalog.sql:
-- psql "$DATABASE_URL" -f database/scripts/003_ingredient_catalog_polish_names.sql
BEGIN;
ALTER TABLE diet."IngredientNutritionCatalog"
ADD COLUMN IF NOT EXISTS "NamePl" varchar(255) NULL;
COMMENT ON COLUMN diet."IngredientNutritionCatalog"."NamePl" IS 'Polish display name for the ingredient.';
CREATE INDEX IF NOT EXISTS "IX_IngredientNutritionCatalog_NamePl"
ON diet."IngredientNutritionCatalog" (lower("NamePl"));
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Polędwica wołowa' WHERE "Name" = 'Beef sirloin';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Schab wieprzowy' WHERE "Name" = 'Pork loin';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Udziec jagnięcy' WHERE "Name" = 'Lamb leg';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Mięso mielone wołowe (15% tł.)' WHERE "Name" = 'Ground beef (15% fat)';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Szynka (gotowana)' WHERE "Name" = 'Ham (cooked)';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Pierś z kurczaka' WHERE "Name" = 'Chicken breast';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Udo z kurczaka' WHERE "Name" = 'Chicken thigh';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Pierś z indyka' WHERE "Name" = 'Turkey breast';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Pierś z kaczki' WHERE "Name" = 'Duck breast';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Łosoś' WHERE "Name" = 'Salmon';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Dorsz' WHERE "Name" = 'Cod';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Tuńczyk (w wodzie)' WHERE "Name" = 'Tuna (canned in water)';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Pstrąg' WHERE "Name" = 'Trout';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Makrela' WHERE "Name" = 'Mackerel';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Krewetki' WHERE "Name" = 'Shrimp';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Małże' WHERE "Name" = 'Mussels';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Kałamarnica' WHERE "Name" = 'Squid';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Krab' WHERE "Name" = 'Crab';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Pomidor' WHERE "Name" = 'Tomato';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Marchew' WHERE "Name" = 'Carrot';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Brokuły' WHERE "Name" = 'Broccoli';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Szpinak' WHERE "Name" = 'Spinach';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Ziemniak' WHERE "Name" = 'Potato';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Ogórek' WHERE "Name" = 'Cucumber';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Papryka' WHERE "Name" = 'Bell pepper';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Cebula' WHERE "Name" = 'Onion';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Cukinia' WHERE "Name" = 'Zucchini';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Pieczarki' WHERE "Name" = 'Mushrooms';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Jabłko' WHERE "Name" = 'Apple';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Banan' WHERE "Name" = 'Banana';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Pomarańcza' WHERE "Name" = 'Orange';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Truskawki' WHERE "Name" = 'Strawberries';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Borówki' WHERE "Name" = 'Blueberries';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Winogrona' WHERE "Name" = 'Grapes';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Awokado' WHERE "Name" = 'Avocado';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Mleko pełne' WHERE "Name" = 'Whole milk';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Mleko odtłuszczone' WHERE "Name" = 'Skim milk';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Jogurt grecki (naturalny)' WHERE "Name" = 'Greek yogurt (plain)';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Ser cheddar' WHERE "Name" = 'Cheddar cheese';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Mozzarella' WHERE "Name" = 'Mozzarella';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Twaróg' WHERE "Name" = 'Cottage cheese';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Jajko kurze (całe)' WHERE "Name" = 'Chicken egg (whole)';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Białko jaja' WHERE "Name" = 'Egg white';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Żółtko jaja' WHERE "Name" = 'Egg yolk';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Ryż biały (gotowany)' WHERE "Name" = 'White rice (cooked)';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Ryż brązowy (gotowany)' WHERE "Name" = 'Brown rice (cooked)';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Makaron (gotowany)' WHERE "Name" = 'Pasta (cooked)';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Płatki owsiane (suche)' WHERE "Name" = 'Oats (dry)';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Chleb pełnoziarnisty' WHERE "Name" = 'Whole wheat bread';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Chleb biały' WHERE "Name" = 'White bread';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Komosa ryżowa (gotowana)' WHERE "Name" = 'Quinoa (cooked)';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Soczewica (gotowana)' WHERE "Name" = 'Lentils (cooked)';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Ciecierzyca (gotowana)' WHERE "Name" = 'Chickpeas (cooked)';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Czarna fasola (gotowana)' WHERE "Name" = 'Black beans (cooked)';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Fasola czerwona (gotowana)' WHERE "Name" = 'Kidney beans (cooked)';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Groszek (gotowany)' WHERE "Name" = 'Green peas (cooked)';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Tofu (twarde)' WHERE "Name" = 'Tofu (firm)';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Migdały' WHERE "Name" = 'Almonds';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Orzechy włoskie' WHERE "Name" = 'Walnuts';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Orzeszki ziemne' WHERE "Name" = 'Peanuts';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Orzechy nerkowca' WHERE "Name" = 'Cashews';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Nasiona słonecznika' WHERE "Name" = 'Sunflower seeds';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Nasiona chia' WHERE "Name" = 'Chia seeds';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Oliwa z oliwek' WHERE "Name" = 'Olive oil';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Masło' WHERE "Name" = 'Butter';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Olej kokosowy' WHERE "Name" = 'Coconut oil';
UPDATE diet."IngredientNutritionCatalog" SET "NamePl" = 'Olej rzepakowy' WHERE "Name" = 'Rapeseed oil';
COMMIT;

View File

@@ -0,0 +1,62 @@
-- Extended features: refresh tokens, meal planner, favorites, recipe-catalog link
-- Apply after 001003. Schema: diet
BEGIN;
-- ---------------------------------------------------------------------------
-- Refresh tokens (persist sessions across API restarts)
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS diet."RefreshTokens" (
"Token" varchar(128) PRIMARY KEY,
"UserId" uuid NOT NULL REFERENCES diet."AspNetUsers"("Id") ON DELETE CASCADE,
"ExpiresAtUtc" timestamptz NOT NULL,
"CreatedAtUtc" timestamptz NOT NULL DEFAULT now(),
"IsRevoked" boolean NOT NULL DEFAULT false
);
CREATE INDEX IF NOT EXISTS "IX_RefreshTokens_UserId" ON diet."RefreshTokens" ("UserId");
CREATE INDEX IF NOT EXISTS "IX_RefreshTokens_ExpiresAtUtc" ON diet."RefreshTokens" ("ExpiresAtUtc");
-- ---------------------------------------------------------------------------
-- Weekly meal plan (one recipe per meal slot per day)
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS diet."MealPlanEntries" (
"Id" serial PRIMARY KEY,
"UserId" uuid NOT NULL REFERENCES diet."AspNetUsers"("Id") ON DELETE CASCADE,
"PlanDate" date NOT NULL,
"MealCategory" int NOT NULL CHECK ("MealCategory" BETWEEN 0 AND 4),
"RecipeId" int NOT NULL REFERENCES diet."Recipes"("Id") ON DELETE CASCADE,
"Portions" numeric(4,2) NOT NULL DEFAULT 1 CHECK ("Portions" > 0),
"CreatedAt" timestamptz NOT NULL DEFAULT now(),
"UpdatedAt" timestamptz NULL,
UNIQUE ("UserId", "PlanDate", "MealCategory")
);
CREATE INDEX IF NOT EXISTS "IX_MealPlanEntries_UserId_PlanDate"
ON diet."MealPlanEntries" ("UserId", "PlanDate");
-- ---------------------------------------------------------------------------
-- Favorites (quick logging)
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS diet."UserFavoriteRecipes" (
"UserId" uuid NOT NULL REFERENCES diet."AspNetUsers"("Id") ON DELETE CASCADE,
"RecipeId" int NOT NULL REFERENCES diet."Recipes"("Id") ON DELETE CASCADE,
"CreatedAt" timestamptz NOT NULL DEFAULT now(),
PRIMARY KEY ("UserId", "RecipeId")
);
CREATE TABLE IF NOT EXISTS diet."UserFavoriteCatalogItems" (
"UserId" uuid NOT NULL REFERENCES diet."AspNetUsers"("Id") ON DELETE CASCADE,
"CatalogItemId" int NOT NULL REFERENCES diet."IngredientNutritionCatalog"("Id") ON DELETE CASCADE,
"CreatedAt" timestamptz NOT NULL DEFAULT now(),
PRIMARY KEY ("UserId", "CatalogItemId")
);
-- ---------------------------------------------------------------------------
-- Link recipe ingredients to nutrition catalog (auto macros)
-- ---------------------------------------------------------------------------
ALTER TABLE diet."Ingredients"
ADD COLUMN IF NOT EXISTS "CatalogItemId" int NULL
REFERENCES diet."IngredientNutritionCatalog"("Id") ON DELETE SET NULL;
COMMIT;

View File

@@ -0,0 +1,928 @@
-- 005_catalog_expansion_and_ingredient_linking.sql
-- Expands nutrition catalog, links recipe ingredients, recalculates recipe macros.
-- Coverage estimate: ~1160/1360 ingredient rows linkable; spice-skip 58; unmapped names 26 (mostly spice mixes)
-- Apply after scripts 001-004.
BEGIN;
-- 1. Add missing catalog items
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Milk 2%', 'Mleko 2%', 50, 3.4, 2.0, 4.8, NULL, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'dairy'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Feta cheese', 'Ser feta', 264, 14.0, 21.0, 4.0, NULL, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'dairy'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Ricotta', 'Ricotta', 174, 11.0, 13.0, 3.0, NULL, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'dairy'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Parmesan', 'Parmezan', 431, 38.0, 29.0, 4.1, NULL, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'dairy'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Sour cream 12%', 'Śmietana 12%', 130, 2.7, 12.0, 3.0, NULL, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'dairy'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Rye bread whole grain', 'Chleb żytni razowy', 217, 8.5, 1.8, 42.0, 5.5, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'grains'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Pasta whole grain dry', 'Makaron pełnoziarnisty (suchy)', 348, 12.0, 2.0, 72.0, 3.0, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'grains'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'White rice dry', 'Ryż biały (suchy)', 360, 7.0, 0.6, 79.0, 1.3, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'grains'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Brown rice dry', 'Ryż brązowy (suchy)', 362, 7.5, 2.7, 76.0, 3.4, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'grains'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Buckwheat groats dry', 'Kasza gryczana (sucha)', 343, 13.0, 3.4, 72.0, 10.0, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'grains'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Bulgur dry', 'Kasza bulgur (sucha)', 342, 12.0, 1.3, 76.0, 12.5, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'grains'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Couscous dry', 'Kuskus (suchy)', 376, 13.0, 0.6, 77.0, 5.0, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'grains'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Whole wheat tortilla', 'Tortilla pełnoziarnista', 298, 9.0, 7.0, 48.0, 6.0, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'grains'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Wheat flour type 1850', 'Mąka pszenna typ 1850', 340, 10.0, 1.0, 72.0, 2.7, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'grains'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Breadcrumbs whole grain', 'Bułka tarta pełnoziarnista', 395, 13.0, 5.0, 72.0, 4.0, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'grains'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Green beans', 'Fasolka szparagowa', 31, 1.8, 0.2, 7.0, 2.7, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'vegetables'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Eggplant', 'Bakłażan', 25, 1.0, 0.2, 6.0, 3.0, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'vegetables'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Radish', 'Rzodkiewka', 16, 0.7, 0.1, 3.4, 1.6, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'vegetables'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Lettuce mix', 'Sałata / mix sałat', 15, 1.4, 0.2, 2.9, 1.3, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'vegetables'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Leek', 'Por', 61, 1.5, 0.3, 14.0, 1.8, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'vegetables'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Celery root', 'Seler korzeniowy', 42, 1.5, 0.3, 9.0, 1.8, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'vegetables'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Celery stalk', 'Seler naciowy', 16, 0.7, 0.2, 3.0, 1.6, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'vegetables'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Cauliflower', 'Kalafior', 25, 1.9, 0.3, 5.0, 2.0, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'vegetables'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Parsley fresh', 'Pietruszka / natka', 36, 3.0, 0.8, 6.3, 3.3, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'vegetables'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Chives', 'Szczypiorek', 30, 3.3, 0.7, 4.4, 2.5, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'vegetables'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Dill fresh', 'Koper ogrodowy', 43, 3.5, 1.1, 7.0, 2.1, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'vegetables'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Capers', 'Kapary', 23, 2.4, 0.9, 4.9, 3.0, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'vegetables'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Olives black', 'Oliwki czarne', 115, 0.8, 10.7, 6.0, 3.2, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'vegetables'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Olives green', 'Oliwki zielone', 145, 1.0, 15.0, 3.8, 3.3, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'vegetables'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Garlic', 'Czosnek', 149, 6.4, 0.5, 33.0, 2.1, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'vegetables'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Sweet corn canned', 'Kukurydza konserwowa', 86, 2.5, 1.0, 19.0, 2.0, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'vegetables'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Raspberries', 'Maliny', 52, 1.2, 0.7, 12.0, 6.5, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'fruits'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Kiwi', 'Kiwi', 61, 1.1, 0.5, 15.0, 3.0, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'fruits'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Mango', 'Mango', 60, 0.8, 0.4, 15.0, 1.6, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'fruits'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Peach nectarine', 'Brzoskwinia / nektarynka', 44, 0.9, 0.3, 11.0, 1.5, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'fruits'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Lemon juice', 'Sok cytrynowy / cytryna', 22, 0.4, 0.2, 6.9, 0.3, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'fruits'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Pomegranate seeds', 'Pestki granatu', 83, 1.7, 1.2, 19.0, 4.0, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'fruits'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Dried apricots', 'Suszone morele', 241, 3.4, 0.5, 63.0, 7.3, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'fruits'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Dried figs', 'Suszone figi', 249, 3.3, 0.9, 63.9, 9.8, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'fruits'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Dried cranberries', 'Żurawina suszona', 308, 0.1, 1.4, 82.0, 5.0, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'fruits'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Honey', 'Miód', 304, 0.3, 0.0, 82.0, 0.2, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'nuts'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Tahini', 'Tahini', 595, 17.0, 54.0, 21.0, 9.0, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'nuts'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Hummus', 'Hummus', 166, 8.0, 9.6, 14.0, 6.0, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'legumes'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Pesto basil', 'Pesto bazyliowe', 420, 5.0, 40.0, 6.0, 2.0, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'oils'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Tomato passata', 'Passata / pomidory z puszki', 32, 1.5, 0.2, 5.0, 1.5, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'vegetables'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Sun-dried tomatoes in oil', 'Suszone pomidory w oliwie', 258, 14.0, 3.0, 55.0, 12.0, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'vegetables'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Jam strawberry low sugar', 'Dżem truskawkowy niskosłodzony', 180, 0.5, 0.1, 45.0, 1.0, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'fruits'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Ketchup', 'Keczup', 100, 1.0, 0.2, 25.0, 0.5, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'vegetables'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Mustard dijon', 'Musztarda dijonska', 66, 4.0, 3.7, 5.0, 3.0, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'vegetables'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Soy sauce', 'Sos sojowy', 53, 8.0, 0.0, 4.9, 0.8, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'vegetables'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Carrot juice', 'Sok marchwiowy', 40, 0.9, 0.2, 9.6, 0.0, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'fruits'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Flaxseed oil', 'Olej lniany', 884, 0.0, 100.0, 0.0, NULL, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'oils'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Flax seeds ground', 'Siemię lniane', 534, 18.0, 42.0, 29.0, 27.0, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'nuts'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Pumpkin seeds', 'Pestki dyni', 559, 30.0, 49.0, 11.0, 6.0, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'nuts'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Pistachios', 'Pistacje', 562, 20.0, 45.0, 28.0, 10.0, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'nuts'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Pine nuts', 'Piniole', 673, 14.0, 68.0, 13.0, 3.7, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'nuts'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Coconut flakes', 'Wiórki kokosowe', 660, 7.0, 65.0, 24.0, 16.0, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'nuts'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Smoked salmon', 'Łosoś wędzony', 117, 18.0, 4.3, 0.0, NULL, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'fish'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Chicken liver', 'Wątróbka kurczaka', 167, 26.0, 6.5, 1.0, NULL, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'poultry'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Pork tenderloin', 'Polędwica wieprzowa', 143, 26.0, 3.5, 0.0, NULL, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'meat'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Beef stew meat', 'Wołowina gulaszowa', 250, 26.0, 15.0, 0.0, NULL, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'meat'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Beef strips', 'Wołowina (rostbef)', 271, 25.8, 18.0, 0.0, NULL, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'meat'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
-- Herbs, spices, and zero-calorie liquids (for remaining unmapped ingredient rows with grams)
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Water', 'Woda', 0, 0, 0, 0, NULL, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'vegetables'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Basil fresh', 'Bazylia świeża', 23, 3.2, 0.6, 2.7, 1.6, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'vegetables'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Basil dried', 'Bazylia suszona', 251, 14.4, 4.1, 47.8, 37.7, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'vegetables'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Oregano dried', 'Oregano suszone', 265, 9.0, 4.3, 68.9, 42.5, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'vegetables'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Thyme dried', 'Tymianek suszony', 276, 9.1, 7.4, 63.9, 37.0, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'vegetables'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Rosemary dried', 'Rozmaryn suszony', 331, 4.9, 15.2, 64.1, 42.6, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'vegetables'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Cinnamon ground', 'Cynamon mielony', 247, 4.0, 1.2, 80.6, 53.1, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'vegetables'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Ginger ground', 'Imbir mielony', 335, 9.0, 4.2, 71.6, 14.1, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'vegetables'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Coriander dried', 'Kolendra suszona', 298, 12.4, 17.8, 54.9, 41.9, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'vegetables'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Marjoram dried', 'Majeranek suszony', 271, 12.7, 7.0, 60.6, 40.3, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'vegetables'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Black pepper ground', 'Pieprz czarny mielony', 251, 10.4, 3.3, 63.9, 25.3, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'vegetables'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
INSERT INTO diet."IngredientNutritionCatalog"
("CategoryId", "Name", "NamePl", "CaloriesPer100G", "ProteinGPer100G", "FatGPer100G", "CarbsGPer100G", "FiberGPer100G", "SortOrder")
SELECT c."Id", 'Cocoa powder 16% fat', 'Kakao 16% proszek', 228, 19.6, 13.7, 57.9, 33.2, 100
FROM diet."IngredientCategories" c WHERE c."Code" = 'grains'
ON CONFLICT ("CategoryId", "Name") DO UPDATE SET
"NamePl" = EXCLUDED."NamePl", "CaloriesPer100G" = EXCLUDED."CaloriesPer100G",
"ProteinGPer100G" = EXCLUDED."ProteinGPer100G", "FatGPer100G" = EXCLUDED."FatGPer100G",
"CarbsGPer100G" = EXCLUDED."CarbsGPer100G", "FiberGPer100G" = EXCLUDED."FiberGPer100G", "IsActive" = true;
CREATE TEMP TABLE _ingredient_name_map (pattern text PRIMARY KEY, catalog_name text NOT NULL);
INSERT INTO _ingredient_name_map VALUES ('Awokado', 'Avocado') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Bakłażan', 'Eggplant') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Bazylia suszona', 'Basil dried') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Bazylia świeża', 'Basil fresh') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Banan', 'Banana') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Bataty', 'Potato') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Borówki amerykańskie', 'Blueberries') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Brokuł', 'Broccoli') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Brokuły', 'Broccoli') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Brzoskwinia', 'Peach nectarine') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Brzoskwinia (świeża lub mrożona)', 'Peach nectarine') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Bułka tarta pełnoziarnista', 'Breadcrumbs whole grain') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Cebula', 'Onion') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Cebula czerwona', 'Onion') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Chleb pita pełnoziarnisty', 'Whole wheat bread') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Chleb żytni razowy', 'Rye bread whole grain') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Ciecierzyca z puszki', 'Chickpeas (cooked)') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Ciecierzyca z puszki (odsączona)', 'Chickpeas (cooked)') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Cukinia', 'Zucchini') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Cynamon', 'Cinnamon ground') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Cytryna', 'Lemon juice') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Cytryna (sok)', 'Lemon juice') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Czosnek', 'Garlic') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Czosnek granulowany', 'Garlic') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Czosnek, sól, pieprz', 'Garlic') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Czosnek, sół, pieprz', 'Garlic') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Czosnek, tymianek, sól, pieprz', 'Garlic') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Dorsz świeży filety bez skóry', 'Cod') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Dynia pestki łuskane', 'Pumpkin seeds') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Dżem truskawkowy niskosłodzony', 'Strawberries') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Fasola czerwona w zalewie (konserwowa)', 'Kidney beans (cooked)') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Fasola szparagowa', 'Green beans') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Fasolka szparagowa', 'Green beans') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Fasolka szparagowa mrożona', 'Green beans') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Filet z dorsza lub dorada', 'Cod') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Filet z piersi indyka', 'Turkey breast') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Filet z piersi indyka (rozbite plastry)', 'Turkey breast') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Filet z łososia', 'Salmon') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Gruszka', 'Peach nectarine') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Hummus', 'Hummus') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Imbir mielony', 'Ginger ground') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Jabłko', 'Apple') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Jaja kurze całe', 'Chicken egg (whole)') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Jaja kurze całe (na twardo)', 'Chicken egg (whole)') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Jajko', 'Chicken egg (whole)') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Jajko (do klopsików)', 'Chicken egg (whole)') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Jajko (do panierki)', 'Chicken egg (whole)') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Jajko ugotowane na twardo', 'Chicken egg (whole)') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Jogurt grecki 2%', 'Greek yogurt (plain)') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Jogurt naturalny', 'Greek yogurt (plain)') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Kakao 16% proszek', 'Cocoa powder 16% fat') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Kabanosy z kurczaka', 'Chicken breast') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Kalafior', 'Cauliflower') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Kapary', 'Capers') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Kasza bulgur', 'Bulgur dry') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Kasza gryczana', 'Buckwheat groats dry') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Kasza jaglana', 'Buckwheat groats dry') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Keczup', 'Ketchup') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Kiełbasa chorizo', 'Ham (cooked)') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Kiełki brokuła', 'Broccoli') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Kiwi', 'Kiwi') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Koncentrat pomidorowy 30%', 'Tomato passata') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Kolendra suszone liście', 'Coriander dried') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Koper ogrodowy', 'Dill fresh') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Kukurydza konserwowa', 'Sweet corn canned') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Kuskus pełnoziarnisty', 'Couscous dry') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Len mielony', 'Flax seeds ground') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Len nasiona', 'Flax seeds ground') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Len, nasiona', 'Flax seeds ground') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Makaron fusilli pełnoziarnisty', 'Pasta whole grain dry') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Makaron penne pełnoziarnisty', 'Pasta whole grain dry') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Makaron pełnoziarnisty', 'Pasta whole grain dry') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Makaron pełnoziarnisty (fusilli)', 'Pasta whole grain dry') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Makaron pełnoziarnisty (penne lub spaghetti)', 'Pasta whole grain dry') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Makaron pełnoziarnisty (tagliatelle lub penne)', 'Pasta whole grain dry') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Makaron rigatoni pełnoziarnisty', 'Pasta whole grain dry') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Makaron spaghetti pełnoziarnisty', 'Pasta whole grain dry') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Makaron tagliatelle pełnoziarnisty', 'Pasta whole grain dry') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Majeranek', 'Marjoram dried') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Maliny', 'Raspberries') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Maliny (świeże lub mrożone)', 'Raspberries') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Maliny świeże lub mrożone', 'Raspberries') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Mango (świeże lub mrożone)', 'Mango') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Marchew', 'Carrot') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Marchewka', 'Carrot') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Masło', 'Butter') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Masło ekstra', 'Butter') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Masło orzechowe', 'Butter') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Migdały', 'Almonds') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Migdały w płatkach', 'Almonds') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Mix sałat', 'Lettuce mix') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Miód', 'Honey') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Miód pszczeli', 'Honey') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Mięso wołowe (świeżo mielone z rostbefu)', 'Ground beef (15% fat)') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Mięso wołowe mielone', 'Ground beef (15% fat)') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Mięso z piersi kurczaka bez skóry', 'Chicken breast') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Mięso z podudzia indyka bez skóry', 'Turkey breast') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Mleko 2%', 'Milk 2%') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Mleko spożywcze 2%', 'Milk 2%') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Morszczuk świeży', 'Cod') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Musztarda dijonska', 'Mustard dijon') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Mąka pszenna (do obtoczenia)', 'Wheat flour type 1850') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Mąka pszenna typ 1850', 'Wheat flour type 1850') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Nasiona chia', 'Chia seeds') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Natka pietruszki', 'Parsley fresh') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Nektarynka', 'Peach nectarine') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Noga (udo) kurczaka', 'Chicken breast') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Ocet jabłkowy z dojrzałych jabłek', 'Apple') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Olej lniany tłoczony na zimno', 'Flaxseed oil') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Oliwa z oliwek', 'Olive oil') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Oliwki czarne', 'Olives black') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Oliwki czarne i zielone (mix)', 'Olives black') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Oliwki zielone', 'Olives green') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Oliwki zielone marynowane', 'Olives green') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Oregano suszone', 'Oregano dried') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Oregano, sok cytryny, sól, pieprz', 'Lemon juice') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Oregano, tymianek, czosnek granulowany, sól', 'Garlic') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Orzechy nerkowca', 'Cashews') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Orzechy nerkowca (bez soli)', 'Cashews') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Orzechy włoskie', 'Walnuts') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Papryka czerwona', 'Bell pepper') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Parmezan tarty', 'Parmesan') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Parmezan w płatkach', 'Parmesan') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Passata pomidorowa', 'Tomato passata') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Passata pomidorowa (przecier)', 'Tomato passata') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Passata pomidorowa przecier', 'Tomato passata') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Pestki granatu', 'Pomegranate seeds') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Pesto bazyliowe', 'Pesto basil') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Pieczarka uprawna świeża', 'Mushrooms') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Pieczarki świeże', 'Mushrooms') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Pieprz czarny mielony', 'Black pepper ground') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Pierś z indyka', 'Turkey breast') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Pierś z kurczaka', 'Chicken breast') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Pierś z kurczaka (rozbita cienko)', 'Chicken breast') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Pierś z kurczaka (ugotowana lub z poprzedniego dnia)', 'Chicken breast') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Pierś z kurczaka (z poprzedniego dnia lub świeża)', 'Chicken breast') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Pietruszka korzeń', 'Celery root') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Pietruszka liście', 'Parsley fresh') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Pietruszka, liście', 'Parsley fresh') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Piniole', 'Pine nuts') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Pistacje (łuskane)', 'Pistachios') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Pistacje łuskane', 'Pistachios') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Polędwica sopocka', 'Ham (cooked)') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Polędwica wieprzowa', 'Pork tenderloin') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Polędwica wieprzowa surowa', 'Pork tenderloin') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Pomarańcza', 'Orange') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Pomidor', 'Tomato') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Pomidory cherry', 'Tomato') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Pomidory koktajlowe', 'Tomato') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Pomidory z puszki', 'Tomato passata') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Pomidory z puszki (krojone)', 'Tomato passata') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Por', 'Leek') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Płatki owsiane', 'Oats (dry)') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Ricotta', 'Ricotta') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Rozmaryn', 'Rosemary dried') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Rukola', 'Lettuce mix') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Ryż basmati', 'White rice dry') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Ryż brązowy', 'Brown rice dry') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Ryż jaśminowy', 'White rice dry') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Rzodkiewka', 'Radish') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Salami', 'Ham (cooked)') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Salami (cienkie plastry)', 'Ham (cooked)') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Sałata', 'Lettuce mix') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Sałata lub mix sałat', 'Lettuce mix') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Seler korzeniowy', 'Celery root') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Seler naciowy', 'Celery stalk') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Ser feta', 'Feta cheese') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Ser gouda tłusty', 'Parmesan') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Ser mozzarella', 'Mozzarella') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Ser parmezan (tarty)', 'Parmesan') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Ser parmezan tarty', 'Parmesan') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Ser twarogowy półtłusty', 'Cottage cheese') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Ser typu feta', 'Feta cheese') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Serek wiejski naturalny', 'Greek yogurt (plain)') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Siemię lniane mielone', 'Flax seeds ground') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Siemię lniane świeżo mielone', 'Flax seeds ground') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Soczewica zielona', 'Lentils (cooked)') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Soczewica zielona (ugotowana)', 'Lentils (cooked)') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Sok cytrynowy', 'Lemon juice') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Sok marchwiowy', 'Carrot juice') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Sos sojowy', 'Soy sauce') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Sos sojowy ciemny', 'Soy sauce') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Suszone figi', 'Dried figs') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Suszone morele', 'Dried apricots') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Suszone pomidory (odsączone)', 'Sun-dried tomatoes in oil') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Suszone pomidory (w oleju z ziołami, odsączone)', 'Sun-dried tomatoes in oil') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Suszone pomidory w oliwie (odsączone)', 'Sun-dried tomatoes in oil') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Szczypiorek', 'Chives') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Szpinak', 'Spinach') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Szpinak świeży', 'Spinach') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Szynka parmeńska', 'Ham (cooked)') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Szynka parmeńska (Prosciutto)', 'Ham (cooked)') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Szynka parmeńska (prosciutto)', 'Ham (cooked)') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Szynka z indyka', 'Turkey breast') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Szynka z indyka (bez konserwantów)', 'Turkey breast') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Słonecznik nasiona łuskane', 'Pumpkin seeds') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Tahini', 'Tahini') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Tortilla pełnoziarnista', 'Whole wheat tortilla') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Truskawki', 'Strawberries') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Truskawki (świeże lub mrożone)', 'Strawberries') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Tuńczyk w wodzie (odsączony)', 'Tuna (canned in water)') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Twaróg półtłusty', 'Cottage cheese') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Tymianek', 'Thyme dried') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Tymianek, czosnek granulowany, sól', 'Garlic') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Tymianek, czosnek granulowany, sól, pieprz', 'Garlic') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Udka kurczaka (bez skóry)', 'Chicken breast') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Udka kurczaka bez skóry', 'Chicken breast') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Wiórki kokosowe', 'Coconut flakes') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Woda', 'Water') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Wołowina (rostbef lub ligawa, cienkie paski)', 'Beef stew meat') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Wołowina gulaszowa', 'Beef stew meat') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Wołowina gulaszowa (karkówka/łopatka)', 'Beef stew meat') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Wołowina mielona', 'Ground beef (15% fat)') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Wątróbka kurczaka', 'Chicken breast') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Ziemniaki', 'Potato') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Łosoś wędzony', 'Smoked salmon') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Śmietana 12%', 'Sour cream 12%') ON CONFLICT DO NOTHING;
INSERT INTO _ingredient_name_map VALUES ('Żurawina suszona', 'Dried cranberries') ON CONFLICT DO NOTHING;
UPDATE diet."Ingredients" i
SET "CatalogItemId" = c."Id"
FROM _ingredient_name_map m
JOIN diet."IngredientNutritionCatalog" c ON c."Name" = m.catalog_name AND c."IsActive" = true
WHERE i."Name" = m.pattern AND i."AmountGrams" IS NOT NULL AND i."AmountGrams" > 0;
WITH totals AS (
SELECT i."RecipeId",
ROUND(SUM(c."CaloriesPer100G" * i."AmountGrams" / 100.0))::int AS calories,
ROUND(SUM(c."ProteinGPer100G" * i."AmountGrams" / 100.0), 2) AS protein,
ROUND(SUM(c."FatGPer100G" * i."AmountGrams" / 100.0), 2) AS fat,
ROUND(SUM(c."CarbsGPer100G" * i."AmountGrams" / 100.0), 2) AS carbs
FROM diet."Ingredients" i
JOIN diet."IngredientNutritionCatalog" c ON c."Id" = i."CatalogItemId"
WHERE i."AmountGrams" IS NOT NULL AND i."AmountGrams" > 0
GROUP BY i."RecipeId"
)
UPDATE diet."Recipes" r SET
"Calories" = t.calories, "Protein" = t.protein, "Fat" = t.fat, "Carbs" = t.carbs, "UpdatedAt" = now()
FROM totals t WHERE r."Id" = t."RecipeId" AND r."IsActive" = true;
DO $$
DECLARE unlinked int; no_macros int;
BEGIN
SELECT COUNT(*) INTO unlinked FROM diet."Ingredients"
WHERE "AmountGrams" > 0 AND "CatalogItemId" IS NULL AND COALESCE("Unit", '') <> 'do smaku';
SELECT COUNT(*) INTO no_macros FROM diet."Recipes" WHERE "IsActive" AND ("Protein" IS NULL OR "Calories" IS NULL);
RAISE NOTICE 'Unlinked ingredient rows (grams, non-spice): %', unlinked;
RAISE NOTICE 'Recipes still missing macros: %', no_macros;
END $$;
COMMIT;
-- Reference mapping: database/scripts/005_ingredient_name_mapping.csv

View File

@@ -0,0 +1,279 @@
IngredientName,CatalogName,Status
Awokado,Avocado,mapped
Bakłażan,Eggplant,mapped
Banan,Banana,mapped
Bataty,Potato,mapped
Bazylia suszona,Basil dried,mapped
"Bazylia suszona, oregano, płatki chili, sół, pieprz",,skip_spice
Bazylia świeża,Basil fresh,mapped
"Bazylia świeża lub suszona, sól, pieprz",UNMAPPED,unmapped
"Bazylia świeża, pieprz",UNMAPPED,unmapped
"Bazylia świeża, pieprz czarny",UNMAPPED,unmapped
"Bazylia, oregano, pieprz",UNMAPPED,unmapped
"Bazylia, oregano, sól, pieprz",UNMAPPED,unmapped
"Bazylia, rozmaryn, sól, pieprz",UNMAPPED,unmapped
"Bazylia, sól, pieprz",UNMAPPED,unmapped
Borówki amerykańskie,Blueberries,mapped
Brokuł,Broccoli,mapped
Brokuły,Broccoli,mapped
Brzoskwinia,Peach nectarine,mapped
Brzoskwinia (świeża lub mrożona),Peach nectarine,mapped
Bułka tarta pełnoziarnista,Breadcrumbs whole grain,mapped
Cebula,Onion,mapped
Cebula czerwona,Onion,mapped
Chleb pita pełnoziarnisty,Whole wheat bread,mapped
Chleb żytni razowy,Rye bread whole grain,mapped
Ciecierzyca z puszki,Chickpeas (cooked),mapped
Ciecierzyca z puszki (odsączona),Chickpeas (cooked),mapped
Cukinia,Zucchini,mapped
Cynamon,Cinnamon ground,mapped
Cytryna,Lemon juice,mapped
Cytryna (sok),Lemon juice,mapped
Czosnek,Garlic,mapped
Czosnek granulowany,Garlic,mapped
"Czosnek, sól, pieprz",Garlic,mapped
"Czosnek, sół, pieprz",Garlic,mapped
"Czosnek, tymianek, sól, pieprz",Garlic,mapped
Dorsz świeży filety bez skóry,Cod,mapped
Dynia pestki łuskane,Pumpkin seeds,mapped
Dżem truskawkowy niskosłodzony,Strawberries,mapped
Erytrol/Erytrytol,,skip_spice
Fasola czerwona w zalewie (konserwowa),Kidney beans (cooked),mapped
Fasola szparagowa,Green beans,mapped
Fasolka szparagowa,Green beans,mapped
Fasolka szparagowa mrożona,Green beans,mapped
Filet z dorsza lub dorada,Cod,mapped
Filet z piersi indyka,Turkey breast,mapped
Filet z piersi indyka (rozbite plastry),Turkey breast,mapped
Filet z łososia,Salmon,mapped
"Gałka muszkatołowa, sól, pieprz",,skip_spice
"Gałka muszkatołowa, sół, pieprz",,skip_spice
Gruszka,Peach nectarine,mapped
Hummus,Hummus,mapped
Imbir mielony,Ginger ground,mapped
Jabłko,Apple,mapped
Jaja kurze całe,Chicken egg (whole),mapped
Jaja kurze całe (na twardo),Chicken egg (whole),mapped
Jajko,Chicken egg (whole),mapped
Jajko (do klopsików),Chicken egg (whole),mapped
Jajko (do panierki),Chicken egg (whole),mapped
Jajko ugotowane na twardo,Chicken egg (whole),mapped
Jogurt grecki 2%,Greek yogurt (plain),mapped
Jogurt naturalny,Greek yogurt (plain),mapped
Kabanosy z kurczaka,Chicken breast,mapped
Kakao 16% proszek,Cocoa powder 16% fat,mapped
Kalafior,Cauliflower,mapped
Kapary,Capers,mapped
Kasza bulgur,Bulgur dry,mapped
Kasza gryczana,Buckwheat groats dry,mapped
Kasza jaglana,Buckwheat groats dry,mapped
Keczup,Ketchup,mapped
Kiełbasa chorizo,Ham (cooked),mapped
Kiełki brokuła,Broccoli,mapped
Kiwi,Kiwi,mapped
"Kminek mielony, papryka słodka, sól, pieprz",,skip_spice
"Kminek mielony, płatki chili, sól, pieprz",,skip_spice
"Kminek, papryka słodka, chili, sól",,skip_spice
Kolendra suszone liście,Coriander dried,mapped
Koncentrat pomidorowy 30%,Tomato passata,mapped
Koper ogrodowy,Dill fresh,mapped
Ksylitol,,skip_spice
Kukurydza konserwowa,Sweet corn canned,mapped
"Kurkuma, kminek, bazylia, sól, pieprz",UNMAPPED,unmapped
"Kurkuma, kminek, cynamon, kolendra suszona, imbir mielony, sól, pieprz",UNMAPPED,unmapped
"Kurkuma, kminek, cynamon, kolendra suszona, sól, pieprz",UNMAPPED,unmapped
"Kurkuma, kminek, kolendra suszona, sól",UNMAPPED,unmapped
Kuskus pełnoziarnisty,Couscous dry,mapped
Len mielony,Flax seeds ground,mapped
Len nasiona,Flax seeds ground,mapped
"Len, nasiona",Flax seeds ground,mapped
Liść laurowy,,skip_spice
Majeranek,Marjoram dried,mapped
Makaron fusilli pełnoziarnisty,Pasta whole grain dry,mapped
Makaron penne pełnoziarnisty,Pasta whole grain dry,mapped
Makaron pełnoziarnisty,Pasta whole grain dry,mapped
Makaron pełnoziarnisty (fusilli),Pasta whole grain dry,mapped
Makaron pełnoziarnisty (penne lub spaghetti),Pasta whole grain dry,mapped
Makaron pełnoziarnisty (tagliatelle lub penne),Pasta whole grain dry,mapped
Makaron rigatoni pełnoziarnisty,Pasta whole grain dry,mapped
Makaron spaghetti pełnoziarnisty,Pasta whole grain dry,mapped
Makaron tagliatelle pełnoziarnisty,Pasta whole grain dry,mapped
Maliny,Raspberries,mapped
Maliny (świeże lub mrożone),Raspberries,mapped
Maliny świeże lub mrożone,Raspberries,mapped
Mango (świeże lub mrożone),Mango,mapped
Marchew,Carrot,mapped
Marchewka,Carrot,mapped
Masło,Butter,mapped
Masło ekstra,Butter,mapped
Masło orzechowe,Butter,mapped
Mielona gałka muszkatołowa,,skip_spice
Mielona papryka chili,,skip_spice
Mielona słodka papryka,,skip_spice
Mielony filet z indyka,,skip_spice
Mielony filet z piersi indyka (bez skóry),,skip_spice
Migdały,Almonds,mapped
Migdały w płatkach,Almonds,mapped
Mix sałat,Lettuce mix,mapped
Miód,Honey,mapped
Miód pszczeli,Honey,mapped
Mięso wołowe (świeżo mielone z rostbefu),Ground beef (15% fat),mapped
Mięso wołowe mielone,Ground beef (15% fat),mapped
Mięso z piersi kurczaka bez skóry,Chicken breast,mapped
Mięso z podudzia indyka bez skóry,Turkey breast,mapped
Mleko 2%,Milk 2%,mapped
Mleko spożywcze 2%,Milk 2%,mapped
Morszczuk świeży,Cod,mapped
Musztarda dijonska,Mustard dijon,mapped
Mąka pszenna (do obtoczenia),Wheat flour type 1850,mapped
Mąka pszenna typ 1850,Wheat flour type 1850,mapped
Nasiona chia,Chia seeds,mapped
Natka pietruszki,Parsley fresh,mapped
Nektarynka,Peach nectarine,mapped
Noga (udo) kurczaka,Chicken breast,mapped
Ocet jabłkowy z dojrzałych jabłek,Apple,mapped
"Ocet winny biały, sól, pieprz",UNMAPPED,unmapped
Olej lniany tłoczony na zimno,Flaxseed oil,mapped
Oliwa z oliwek,Olive oil,mapped
Oliwki czarne,Olives black,mapped
Oliwki czarne i zielone (mix),Olives black,mapped
Oliwki zielone,Olives green,mapped
Oliwki zielone marynowane,Olives green,mapped
Oregano suszone,Oregano dried,mapped
"Oregano, bazylia suszona, płatki chili, sól, pieprz",,skip_spice
"Oregano, bazylia, sól",UNMAPPED,unmapped
"Oregano, bazylia, sól, pieprz",UNMAPPED,unmapped
"Oregano, pieprz",UNMAPPED,unmapped
"Oregano, płatki chili, sól, pieprz",,skip_spice
"Oregano, sok cytryny, sól, pieprz",Lemon juice,mapped
"Oregano, sól, pieprz",UNMAPPED,unmapped
"Oregano, tymianek, czosnek granulowany, sól",Garlic,mapped
"Oregano, tymianek, sól, pieprz",UNMAPPED,unmapped
Orzechy nerkowca,Cashews,mapped
Orzechy nerkowca (bez soli),Cashews,mapped
Orzechy włoskie,Walnuts,mapped
Papryka czerwona,Bell pepper,mapped
"Papryka słodka, chili, oregano, sól, pieprz",,skip_spice
Parmezan tarty,Parmesan,mapped
Parmezan w płatkach,Parmesan,mapped
Passata pomidorowa,Tomato passata,mapped
Passata pomidorowa (przecier),Tomato passata,mapped
Passata pomidorowa przecier,Tomato passata,mapped
Pestki granatu,Pomegranate seeds,mapped
Pesto bazyliowe,Pesto basil,mapped
Pieczarka uprawna świeża,Mushrooms,mapped
Pieczarki świeże,Mushrooms,mapped
Pieprz czarny mielony,Black pepper ground,mapped
Pierś z indyka,Turkey breast,mapped
Pierś z kurczaka,Chicken breast,mapped
Pierś z kurczaka (rozbita cienko),Chicken breast,mapped
Pierś z kurczaka (ugotowana lub z poprzedniego dnia),Chicken breast,mapped
Pierś z kurczaka (z poprzedniego dnia lub świeża),Chicken breast,mapped
Pietruszka korzeń,Celery root,mapped
Pietruszka liście,Parsley fresh,mapped
"Pietruszka, liście",Parsley fresh,mapped
Piniole,Pine nuts,mapped
Pistacje (łuskane),Pistachios,mapped
Pistacje łuskane,Pistachios,mapped
Polędwica sopocka,Ham (cooked),mapped
Polędwica wieprzowa,Pork tenderloin,mapped
Polędwica wieprzowa surowa,Pork tenderloin,mapped
Pomarańcza,Orange,mapped
Pomidor,Tomato,mapped
Pomidory cherry,Tomato,mapped
Pomidory koktajlowe,Tomato,mapped
Pomidory z puszki,Tomato passata,mapped
Pomidory z puszki (krojone),Tomato passata,mapped
Por,Leek,mapped
Proszek do pieczenia,,skip_spice
Przyprawa do drobiu,,skip_spice
"Płatki chili, sól",,skip_spice
"Płatki chili, sól, pieprz",,skip_spice
Płatki owsiane,Oats (dry),mapped
Ricotta,Ricotta,mapped
Rozmaryn,Rosemary dried,mapped
"Rozmaryn, tymianek, bazylia, sól, pieprz",UNMAPPED,unmapped
"Rozmaryn, tymianek, oregano, sól, pieprz",UNMAPPED,unmapped
"Rozmaryn, tymianek, sól, pieprz",UNMAPPED,unmapped
Rukola,Lettuce mix,mapped
Ryż basmati,White rice dry,mapped
Ryż brązowy,Brown rice dry,mapped
Ryż jaśminowy,White rice dry,mapped
Rzodkiewka,Radish,mapped
Salami,Ham (cooked),mapped
Salami (cienkie plastry),Ham (cooked),mapped
Sałata,Lettuce mix,mapped
Sałata lub mix sałat,Lettuce mix,mapped
Seler korzeniowy,Celery root,mapped
Seler naciowy,Celery stalk,mapped
Ser feta,Feta cheese,mapped
Ser gouda tłusty,Parmesan,mapped
Ser mozzarella,Mozzarella,mapped
Ser parmezan (tarty),Parmesan,mapped
Ser parmezan tarty,Parmesan,mapped
Ser twarogowy półtłusty,Cottage cheese,mapped
Ser typu feta,Feta cheese,mapped
Serek wiejski naturalny,Greek yogurt (plain),mapped
Siemię lniane mielone,Flax seeds ground,mapped
Siemię lniane świeżo mielone,Flax seeds ground,mapped
Soczewica zielona,Lentils (cooked),mapped
Soczewica zielona (ugotowana),Lentils (cooked),mapped
Sok cytrynowy,Lemon juice,mapped
Sok marchwiowy,Carrot juice,mapped
Sos sojowy,Soy sauce,mapped
Sos sojowy ciemny,Soy sauce,mapped
Suszone figi,Dried figs,mapped
Suszone morele,Dried apricots,mapped
Suszone pomidory (odsączone),Sun-dried tomatoes in oil,mapped
"Suszone pomidory (w oleju z ziołami, odsączone)",Sun-dried tomatoes in oil,mapped
Suszone pomidory w oliwie (odsączone),Sun-dried tomatoes in oil,mapped
Szczypiorek,Chives,mapped
Szpinak,Spinach,mapped
Szpinak świeży,Spinach,mapped
Szynka parmeńska,Ham (cooked),mapped
Szynka parmeńska (Prosciutto),Ham (cooked),mapped
Szynka parmeńska (prosciutto),Ham (cooked),mapped
Szynka z indyka,Turkey breast,mapped
Szynka z indyka (bez konserwantów),Turkey breast,mapped
Sól himalajska,,skip_spice
"Sól, pieprz",UNMAPPED,unmapped
"Sól, pieprz, oregano",UNMAPPED,unmapped
"Sól, pieprz, płatki chili",,skip_spice
"Sól, pieprz, zioła prowansalskie",,skip_spice
Sół himalajska,,skip_spice
"Sół, pieprz, płatki chili",,skip_spice
Słonecznik nasiona łuskane,Pumpkin seeds,mapped
Tahini,Tahini,mapped
Tortilla pełnoziarnista,Whole wheat tortilla,mapped
Truskawki,Strawberries,mapped
Truskawki (świeże lub mrożone),Strawberries,mapped
Tuńczyk w wodzie (odsączony),Tuna (canned in water),mapped
Twaróg półtłusty,Cottage cheese,mapped
Tymianek,Thyme dried,mapped
"Tymianek, czosnek granulowany, sól",Garlic,mapped
"Tymianek, czosnek granulowany, sól, pieprz",Garlic,mapped
"Tymianek, oregano, sól, pieprz",UNMAPPED,unmapped
"Tymianek, rozmaryn, papryka słodka, sół, pieprz",,skip_spice
"Tymianek, rozmaryn, sól, pieprz",UNMAPPED,unmapped
"Tymianek, rozmaryn, zioła prowansalskie, sól, pieprz",,skip_spice
"Tymianek, sól, pieprz",UNMAPPED,unmapped
"Tymianek, sół, pieprz",UNMAPPED,unmapped
Udka kurczaka (bez skóry),Chicken breast,mapped
Udka kurczaka bez skóry,Chicken breast,mapped
Wiórki kokosowe,Coconut flakes,mapped
Woda,Water,mapped
"Wołowina (rostbef lub ligawa, cienkie paski)",Beef stew meat,mapped
Wołowina gulaszowa,Beef stew meat,mapped
Wołowina gulaszowa (karkówka/łopatka),Beef stew meat,mapped
Wołowina mielona,Ground beef (15% fat),mapped
Wątróbka kurczaka,Chicken breast,mapped
Ziele angielskie,,skip_spice
Ziemniaki,Potato,mapped
Zioła prowansalskie,,skip_spice
"Zioła prowansalskie, rozmaryn, tymianek, sól, pieprz",,skip_spice
"Zioła prowansalskie, sól, pieprz",,skip_spice
"Zioła prowansalskie, tymianek, liść laurowy, sól, pieprz",,skip_spice
"Zioła prowansalskie, tymianek, sól, pieprz",,skip_spice
Łosoś wędzony,Smoked salmon,mapped
Śmietana 12%,Sour cream 12%,mapped
Żurawina suszona,Dried cranberries,mapped
1 IngredientName CatalogName Status
2 Awokado Avocado mapped
3 Bakłażan Eggplant mapped
4 Banan Banana mapped
5 Bataty Potato mapped
6 Bazylia suszona Basil dried mapped
7 Bazylia suszona, oregano, płatki chili, sół, pieprz skip_spice
8 Bazylia świeża Basil fresh mapped
9 Bazylia świeża lub suszona, sól, pieprz UNMAPPED unmapped
10 Bazylia świeża, pieprz UNMAPPED unmapped
11 Bazylia świeża, pieprz czarny UNMAPPED unmapped
12 Bazylia, oregano, pieprz UNMAPPED unmapped
13 Bazylia, oregano, sól, pieprz UNMAPPED unmapped
14 Bazylia, rozmaryn, sól, pieprz UNMAPPED unmapped
15 Bazylia, sól, pieprz UNMAPPED unmapped
16 Borówki amerykańskie Blueberries mapped
17 Brokuł Broccoli mapped
18 Brokuły Broccoli mapped
19 Brzoskwinia Peach nectarine mapped
20 Brzoskwinia (świeża lub mrożona) Peach nectarine mapped
21 Bułka tarta pełnoziarnista Breadcrumbs whole grain mapped
22 Cebula Onion mapped
23 Cebula czerwona Onion mapped
24 Chleb pita pełnoziarnisty Whole wheat bread mapped
25 Chleb żytni razowy Rye bread whole grain mapped
26 Ciecierzyca z puszki Chickpeas (cooked) mapped
27 Ciecierzyca z puszki (odsączona) Chickpeas (cooked) mapped
28 Cukinia Zucchini mapped
29 Cynamon Cinnamon ground mapped
30 Cytryna Lemon juice mapped
31 Cytryna (sok) Lemon juice mapped
32 Czosnek Garlic mapped
33 Czosnek granulowany Garlic mapped
34 Czosnek, sól, pieprz Garlic mapped
35 Czosnek, sół, pieprz Garlic mapped
36 Czosnek, tymianek, sól, pieprz Garlic mapped
37 Dorsz świeży filety bez skóry Cod mapped
38 Dynia pestki łuskane Pumpkin seeds mapped
39 Dżem truskawkowy niskosłodzony Strawberries mapped
40 Erytrol/Erytrytol skip_spice
41 Fasola czerwona w zalewie (konserwowa) Kidney beans (cooked) mapped
42 Fasola szparagowa Green beans mapped
43 Fasolka szparagowa Green beans mapped
44 Fasolka szparagowa mrożona Green beans mapped
45 Filet z dorsza lub dorada Cod mapped
46 Filet z piersi indyka Turkey breast mapped
47 Filet z piersi indyka (rozbite plastry) Turkey breast mapped
48 Filet z łososia Salmon mapped
49 Gałka muszkatołowa, sól, pieprz skip_spice
50 Gałka muszkatołowa, sół, pieprz skip_spice
51 Gruszka Peach nectarine mapped
52 Hummus Hummus mapped
53 Imbir mielony Ginger ground mapped
54 Jabłko Apple mapped
55 Jaja kurze całe Chicken egg (whole) mapped
56 Jaja kurze całe (na twardo) Chicken egg (whole) mapped
57 Jajko Chicken egg (whole) mapped
58 Jajko (do klopsików) Chicken egg (whole) mapped
59 Jajko (do panierki) Chicken egg (whole) mapped
60 Jajko ugotowane na twardo Chicken egg (whole) mapped
61 Jogurt grecki 2% Greek yogurt (plain) mapped
62 Jogurt naturalny Greek yogurt (plain) mapped
63 Kabanosy z kurczaka Chicken breast mapped
64 Kakao 16% proszek Cocoa powder 16% fat mapped
65 Kalafior Cauliflower mapped
66 Kapary Capers mapped
67 Kasza bulgur Bulgur dry mapped
68 Kasza gryczana Buckwheat groats dry mapped
69 Kasza jaglana Buckwheat groats dry mapped
70 Keczup Ketchup mapped
71 Kiełbasa chorizo Ham (cooked) mapped
72 Kiełki brokuła Broccoli mapped
73 Kiwi Kiwi mapped
74 Kminek mielony, papryka słodka, sól, pieprz skip_spice
75 Kminek mielony, płatki chili, sól, pieprz skip_spice
76 Kminek, papryka słodka, chili, sól skip_spice
77 Kolendra suszone liście Coriander dried mapped
78 Koncentrat pomidorowy 30% Tomato passata mapped
79 Koper ogrodowy Dill fresh mapped
80 Ksylitol skip_spice
81 Kukurydza konserwowa Sweet corn canned mapped
82 Kurkuma, kminek, bazylia, sól, pieprz UNMAPPED unmapped
83 Kurkuma, kminek, cynamon, kolendra suszona, imbir mielony, sól, pieprz UNMAPPED unmapped
84 Kurkuma, kminek, cynamon, kolendra suszona, sól, pieprz UNMAPPED unmapped
85 Kurkuma, kminek, kolendra suszona, sól UNMAPPED unmapped
86 Kuskus pełnoziarnisty Couscous dry mapped
87 Len mielony Flax seeds ground mapped
88 Len nasiona Flax seeds ground mapped
89 Len, nasiona Flax seeds ground mapped
90 Liść laurowy skip_spice
91 Majeranek Marjoram dried mapped
92 Makaron fusilli pełnoziarnisty Pasta whole grain dry mapped
93 Makaron penne pełnoziarnisty Pasta whole grain dry mapped
94 Makaron pełnoziarnisty Pasta whole grain dry mapped
95 Makaron pełnoziarnisty (fusilli) Pasta whole grain dry mapped
96 Makaron pełnoziarnisty (penne lub spaghetti) Pasta whole grain dry mapped
97 Makaron pełnoziarnisty (tagliatelle lub penne) Pasta whole grain dry mapped
98 Makaron rigatoni pełnoziarnisty Pasta whole grain dry mapped
99 Makaron spaghetti pełnoziarnisty Pasta whole grain dry mapped
100 Makaron tagliatelle pełnoziarnisty Pasta whole grain dry mapped
101 Maliny Raspberries mapped
102 Maliny (świeże lub mrożone) Raspberries mapped
103 Maliny świeże lub mrożone Raspberries mapped
104 Mango (świeże lub mrożone) Mango mapped
105 Marchew Carrot mapped
106 Marchewka Carrot mapped
107 Masło Butter mapped
108 Masło ekstra Butter mapped
109 Masło orzechowe Butter mapped
110 Mielona gałka muszkatołowa skip_spice
111 Mielona papryka chili skip_spice
112 Mielona słodka papryka skip_spice
113 Mielony filet z indyka skip_spice
114 Mielony filet z piersi indyka (bez skóry) skip_spice
115 Migdały Almonds mapped
116 Migdały w płatkach Almonds mapped
117 Mix sałat Lettuce mix mapped
118 Miód Honey mapped
119 Miód pszczeli Honey mapped
120 Mięso wołowe (świeżo mielone z rostbefu) Ground beef (15% fat) mapped
121 Mięso wołowe mielone Ground beef (15% fat) mapped
122 Mięso z piersi kurczaka bez skóry Chicken breast mapped
123 Mięso z podudzia indyka bez skóry Turkey breast mapped
124 Mleko 2% Milk 2% mapped
125 Mleko spożywcze 2% Milk 2% mapped
126 Morszczuk świeży Cod mapped
127 Musztarda dijonska Mustard dijon mapped
128 Mąka pszenna (do obtoczenia) Wheat flour type 1850 mapped
129 Mąka pszenna typ 1850 Wheat flour type 1850 mapped
130 Nasiona chia Chia seeds mapped
131 Natka pietruszki Parsley fresh mapped
132 Nektarynka Peach nectarine mapped
133 Noga (udo) kurczaka Chicken breast mapped
134 Ocet jabłkowy z dojrzałych jabłek Apple mapped
135 Ocet winny biały, sól, pieprz UNMAPPED unmapped
136 Olej lniany tłoczony na zimno Flaxseed oil mapped
137 Oliwa z oliwek Olive oil mapped
138 Oliwki czarne Olives black mapped
139 Oliwki czarne i zielone (mix) Olives black mapped
140 Oliwki zielone Olives green mapped
141 Oliwki zielone marynowane Olives green mapped
142 Oregano suszone Oregano dried mapped
143 Oregano, bazylia suszona, płatki chili, sól, pieprz skip_spice
144 Oregano, bazylia, sól UNMAPPED unmapped
145 Oregano, bazylia, sól, pieprz UNMAPPED unmapped
146 Oregano, pieprz UNMAPPED unmapped
147 Oregano, płatki chili, sól, pieprz skip_spice
148 Oregano, sok cytryny, sól, pieprz Lemon juice mapped
149 Oregano, sól, pieprz UNMAPPED unmapped
150 Oregano, tymianek, czosnek granulowany, sól Garlic mapped
151 Oregano, tymianek, sól, pieprz UNMAPPED unmapped
152 Orzechy nerkowca Cashews mapped
153 Orzechy nerkowca (bez soli) Cashews mapped
154 Orzechy włoskie Walnuts mapped
155 Papryka czerwona Bell pepper mapped
156 Papryka słodka, chili, oregano, sól, pieprz skip_spice
157 Parmezan tarty Parmesan mapped
158 Parmezan w płatkach Parmesan mapped
159 Passata pomidorowa Tomato passata mapped
160 Passata pomidorowa (przecier) Tomato passata mapped
161 Passata pomidorowa przecier Tomato passata mapped
162 Pestki granatu Pomegranate seeds mapped
163 Pesto bazyliowe Pesto basil mapped
164 Pieczarka uprawna świeża Mushrooms mapped
165 Pieczarki świeże Mushrooms mapped
166 Pieprz czarny mielony Black pepper ground mapped
167 Pierś z indyka Turkey breast mapped
168 Pierś z kurczaka Chicken breast mapped
169 Pierś z kurczaka (rozbita cienko) Chicken breast mapped
170 Pierś z kurczaka (ugotowana lub z poprzedniego dnia) Chicken breast mapped
171 Pierś z kurczaka (z poprzedniego dnia lub świeża) Chicken breast mapped
172 Pietruszka korzeń Celery root mapped
173 Pietruszka liście Parsley fresh mapped
174 Pietruszka, liście Parsley fresh mapped
175 Piniole Pine nuts mapped
176 Pistacje (łuskane) Pistachios mapped
177 Pistacje łuskane Pistachios mapped
178 Polędwica sopocka Ham (cooked) mapped
179 Polędwica wieprzowa Pork tenderloin mapped
180 Polędwica wieprzowa surowa Pork tenderloin mapped
181 Pomarańcza Orange mapped
182 Pomidor Tomato mapped
183 Pomidory cherry Tomato mapped
184 Pomidory koktajlowe Tomato mapped
185 Pomidory z puszki Tomato passata mapped
186 Pomidory z puszki (krojone) Tomato passata mapped
187 Por Leek mapped
188 Proszek do pieczenia skip_spice
189 Przyprawa do drobiu skip_spice
190 Płatki chili, sól skip_spice
191 Płatki chili, sól, pieprz skip_spice
192 Płatki owsiane Oats (dry) mapped
193 Ricotta Ricotta mapped
194 Rozmaryn Rosemary dried mapped
195 Rozmaryn, tymianek, bazylia, sól, pieprz UNMAPPED unmapped
196 Rozmaryn, tymianek, oregano, sól, pieprz UNMAPPED unmapped
197 Rozmaryn, tymianek, sól, pieprz UNMAPPED unmapped
198 Rukola Lettuce mix mapped
199 Ryż basmati White rice dry mapped
200 Ryż brązowy Brown rice dry mapped
201 Ryż jaśminowy White rice dry mapped
202 Rzodkiewka Radish mapped
203 Salami Ham (cooked) mapped
204 Salami (cienkie plastry) Ham (cooked) mapped
205 Sałata Lettuce mix mapped
206 Sałata lub mix sałat Lettuce mix mapped
207 Seler korzeniowy Celery root mapped
208 Seler naciowy Celery stalk mapped
209 Ser feta Feta cheese mapped
210 Ser gouda tłusty Parmesan mapped
211 Ser mozzarella Mozzarella mapped
212 Ser parmezan (tarty) Parmesan mapped
213 Ser parmezan tarty Parmesan mapped
214 Ser twarogowy półtłusty Cottage cheese mapped
215 Ser typu feta Feta cheese mapped
216 Serek wiejski naturalny Greek yogurt (plain) mapped
217 Siemię lniane mielone Flax seeds ground mapped
218 Siemię lniane świeżo mielone Flax seeds ground mapped
219 Soczewica zielona Lentils (cooked) mapped
220 Soczewica zielona (ugotowana) Lentils (cooked) mapped
221 Sok cytrynowy Lemon juice mapped
222 Sok marchwiowy Carrot juice mapped
223 Sos sojowy Soy sauce mapped
224 Sos sojowy ciemny Soy sauce mapped
225 Suszone figi Dried figs mapped
226 Suszone morele Dried apricots mapped
227 Suszone pomidory (odsączone) Sun-dried tomatoes in oil mapped
228 Suszone pomidory (w oleju z ziołami, odsączone) Sun-dried tomatoes in oil mapped
229 Suszone pomidory w oliwie (odsączone) Sun-dried tomatoes in oil mapped
230 Szczypiorek Chives mapped
231 Szpinak Spinach mapped
232 Szpinak świeży Spinach mapped
233 Szynka parmeńska Ham (cooked) mapped
234 Szynka parmeńska (Prosciutto) Ham (cooked) mapped
235 Szynka parmeńska (prosciutto) Ham (cooked) mapped
236 Szynka z indyka Turkey breast mapped
237 Szynka z indyka (bez konserwantów) Turkey breast mapped
238 Sól himalajska skip_spice
239 Sól, pieprz UNMAPPED unmapped
240 Sól, pieprz, oregano UNMAPPED unmapped
241 Sól, pieprz, płatki chili skip_spice
242 Sól, pieprz, zioła prowansalskie skip_spice
243 Sół himalajska skip_spice
244 Sół, pieprz, płatki chili skip_spice
245 Słonecznik nasiona łuskane Pumpkin seeds mapped
246 Tahini Tahini mapped
247 Tortilla pełnoziarnista Whole wheat tortilla mapped
248 Truskawki Strawberries mapped
249 Truskawki (świeże lub mrożone) Strawberries mapped
250 Tuńczyk w wodzie (odsączony) Tuna (canned in water) mapped
251 Twaróg półtłusty Cottage cheese mapped
252 Tymianek Thyme dried mapped
253 Tymianek, czosnek granulowany, sól Garlic mapped
254 Tymianek, czosnek granulowany, sól, pieprz Garlic mapped
255 Tymianek, oregano, sól, pieprz UNMAPPED unmapped
256 Tymianek, rozmaryn, papryka słodka, sół, pieprz skip_spice
257 Tymianek, rozmaryn, sól, pieprz UNMAPPED unmapped
258 Tymianek, rozmaryn, zioła prowansalskie, sól, pieprz skip_spice
259 Tymianek, sól, pieprz UNMAPPED unmapped
260 Tymianek, sół, pieprz UNMAPPED unmapped
261 Udka kurczaka (bez skóry) Chicken breast mapped
262 Udka kurczaka bez skóry Chicken breast mapped
263 Wiórki kokosowe Coconut flakes mapped
264 Woda Water mapped
265 Wołowina (rostbef lub ligawa, cienkie paski) Beef stew meat mapped
266 Wołowina gulaszowa Beef stew meat mapped
267 Wołowina gulaszowa (karkówka/łopatka) Beef stew meat mapped
268 Wołowina mielona Ground beef (15% fat) mapped
269 Wątróbka kurczaka Chicken breast mapped
270 Ziele angielskie skip_spice
271 Ziemniaki Potato mapped
272 Zioła prowansalskie skip_spice
273 Zioła prowansalskie, rozmaryn, tymianek, sól, pieprz skip_spice
274 Zioła prowansalskie, sól, pieprz skip_spice
275 Zioła prowansalskie, tymianek, liść laurowy, sól, pieprz skip_spice
276 Zioła prowansalskie, tymianek, sól, pieprz skip_spice
277 Łosoś wędzony Smoked salmon mapped
278 Śmietana 12% Sour cream 12% mapped
279 Żurawina suszona Dried cranberries mapped

View File

@@ -0,0 +1,110 @@
-- 006_diet_and_recipe_generators.sql
-- AI-assisted diet plan and recipe generation modules.
-- Apply after scripts 001005.
BEGIN;
-- ---------------------------------------------------------------------------
-- User profile for TDEE / goal-based planning
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS diet."DietUserProfiles" (
"UserId" uuid PRIMARY KEY
REFERENCES diet."AspNetUsers"("Id") ON DELETE CASCADE,
"HeightCm" numeric(5,2) NOT NULL CHECK ("HeightCm" > 0),
"WeightKg" numeric(5,2) NOT NULL CHECK ("WeightKg" > 0),
"Age" int NOT NULL CHECK ("Age" BETWEEN 10 AND 120),
"Sex" varchar(16) NOT NULL CHECK ("Sex" IN ('male', 'female')),
"ActivityLevel" varchar(32) NOT NULL
CHECK ("ActivityLevel" IN ('sedentary', 'light', 'moderate', 'active', 'very_active')),
"Goal" varchar(32) NOT NULL
CHECK ("Goal" IN ('lose_weight', 'maintain', 'gain_muscle', 'recomp')),
"AllergiesNotes" text NULL,
"DislikedFoods" text NULL,
"MealsPerDayMask" int NOT NULL DEFAULT 15 CHECK ("MealsPerDayMask" BETWEEN 1 AND 31),
"CreatedAt" timestamptz NOT NULL DEFAULT now(),
"UpdatedAt" timestamptz NULL
);
COMMENT ON COLUMN diet."DietUserProfiles"."MealsPerDayMask" IS 'Bitmask: bit0=Breakfast, bit1=SecondBreakfast, bit2=Lunch, bit3=Dinner, bit4=Snack';
-- ---------------------------------------------------------------------------
-- Diet generator wizard sessions
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS diet."DietGeneratorSessions" (
"Id" serial PRIMARY KEY,
"UserId" uuid NOT NULL REFERENCES diet."AspNetUsers"("Id") ON DELETE CASCADE,
"Status" varchar(32) NOT NULL DEFAULT 'macros_pending',
"ProposedCalories" int NULL CHECK ("ProposedCalories" IS NULL OR "ProposedCalories" > 0),
"ProposedProteinG" numeric(6,2) NULL,
"ProposedFatG" numeric(6,2) NULL,
"ProposedCarbsG" numeric(6,2) NULL,
"MacroRationale" text NULL,
"MacrosAcceptedAt" timestamptz NULL,
"PlanStartDate" date NULL,
"PlanDayCount" int NOT NULL DEFAULT 7 CHECK ("PlanDayCount" BETWEEN 1 AND 28),
"CalorieToleranceKcal" int NOT NULL DEFAULT 10 CHECK ("CalorieToleranceKcal" >= 0),
"PreferencesJson" jsonb NULL,
"CommittedAt" timestamptz NULL,
"CreatedAt" timestamptz NOT NULL DEFAULT now(),
"UpdatedAt" timestamptz NULL
);
CREATE INDEX IF NOT EXISTS "IX_DietGeneratorSessions_UserId_Status"
ON diet."DietGeneratorSessions" ("UserId", "Status");
-- ---------------------------------------------------------------------------
-- Draft meals (review before commit to MealPlanEntries)
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS diet."DietGeneratorDraftMeals" (
"Id" serial PRIMARY KEY,
"SessionId" int NOT NULL REFERENCES diet."DietGeneratorSessions"("Id") ON DELETE CASCADE,
"PlanDate" date NOT NULL,
"MealCategory" int NOT NULL CHECK ("MealCategory" BETWEEN 0 AND 4),
"RecipeId" int NOT NULL REFERENCES diet."Recipes"("Id") ON DELETE CASCADE,
"Portions" numeric(4,2) NOT NULL DEFAULT 1 CHECK ("Portions" > 0),
"Calories" int NULL,
"ProteinG" numeric(6,2) NULL,
"FatG" numeric(6,2) NULL,
"CarbsG" numeric(6,2) NULL,
"IsLocked" boolean NOT NULL DEFAULT false,
"GenerationVersion" int NOT NULL DEFAULT 1,
UNIQUE ("SessionId", "PlanDate", "MealCategory")
);
CREATE INDEX IF NOT EXISTS "IX_DietGeneratorDraftMeals_SessionId"
ON diet."DietGeneratorDraftMeals" ("SessionId");
-- ---------------------------------------------------------------------------
-- Recipe generator sessions (draft JSON until commit)
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS diet."RecipeGeneratorSessions" (
"Id" serial PRIMARY KEY,
"UserId" uuid NOT NULL REFERENCES diet."AspNetUsers"("Id") ON DELETE CASCADE,
"Status" varchar(32) NOT NULL DEFAULT 'draft',
"ConstraintsJson" jsonb NOT NULL DEFAULT '{}',
"DraftJson" jsonb NULL,
"SavedRecipeId" int NULL REFERENCES diet."Recipes"("Id") ON DELETE SET NULL,
"GenerationVersion" int NOT NULL DEFAULT 1,
"CreatedAt" timestamptz NOT NULL DEFAULT now(),
"UpdatedAt" timestamptz NULL
);
CREATE INDEX IF NOT EXISTS "IX_RecipeGeneratorSessions_UserId"
ON diet."RecipeGeneratorSessions" ("UserId");
-- ---------------------------------------------------------------------------
-- Recipe provenance (AI vs manual)
-- ---------------------------------------------------------------------------
ALTER TABLE diet."Recipes"
ADD COLUMN IF NOT EXISTS "Source" varchar(32) NOT NULL DEFAULT 'manual';
ALTER TABLE diet."Recipes"
ADD COLUMN IF NOT EXISTS "CreatedByUserId" uuid NULL
REFERENCES diet."AspNetUsers"("Id") ON DELETE SET NULL;
ALTER TABLE diet."Recipes"
ADD COLUMN IF NOT EXISTS "IsDraft" boolean NOT NULL DEFAULT false;
COMMENT ON COLUMN diet."Recipes"."Source" IS 'manual | excel | ai_generated';
COMMIT;

View File

@@ -0,0 +1,135 @@
-- 007_remove_duplicate_recipes_by_name.sql
-- Removes duplicate recipes that share the same "Name" (trimmed, exact match).
-- Keeps the row with the lowest "Id" for each name.
--
-- Analysis of Recipes-2.csv export (196 rows):
-- 168 unique names, 28 duplicate groups, 28 rows to delete (Ids 113140).
-- Those duplicate Ids mirror Ids 2956 one-to-one.
--
-- Run inside a transaction. Review the preview queries before COMMIT.
BEGIN;
-- ---------------------------------------------------------------------------
-- 1) Preview duplicates
-- ---------------------------------------------------------------------------
-- SELECT
-- r."Name",
-- array_agg(r."Id" ORDER BY r."Id") AS ids,
-- min(r."Id") AS keep_id,
-- array_agg(r."Id" ORDER BY r."Id") FILTER (WHERE r."Id" <> min(r."Id")) AS remove_ids
-- FROM diet."Recipes" r
-- GROUP BY r."Name"
-- HAVING count(*) > 1
-- ORDER BY min(r."Id");
-- ---------------------------------------------------------------------------
-- 2) Build duplicate map: remove_id -> keep_id
-- ---------------------------------------------------------------------------
CREATE TEMP TABLE recipe_dedup_map ON COMMIT DROP AS
SELECT
r."Id" AS remove_id,
d.keep_id
FROM diet."Recipes" r
INNER JOIN (
SELECT btrim("Name") AS name_key, MIN("Id") AS keep_id
FROM diet."Recipes"
GROUP BY btrim("Name")
HAVING COUNT(*) > 1
) d ON btrim(r."Name") = d.name_key
WHERE r."Id" <> d.keep_id;
-- Optional: restrict to known duplicate ids from export
-- DELETE FROM recipe_dedup_map WHERE remove_id NOT BETWEEN 113 AND 140;
DO $$
DECLARE
dup_count int;
BEGIN
SELECT count(*) INTO dup_count FROM recipe_dedup_map;
RAISE NOTICE 'Duplicate recipe rows to remove: %', dup_count;
END $$;
-- ---------------------------------------------------------------------------
-- 3) Re-point foreign keys to the canonical (lowest-id) recipe
-- ---------------------------------------------------------------------------
-- Meal planner / diet generator drafts
UPDATE diet."MealPlanEntries" e
SET "RecipeId" = m.keep_id,
"UpdatedAt" = now()
FROM recipe_dedup_map m
WHERE e."RecipeId" = m.remove_id;
UPDATE diet."DietGeneratorDraftMeals" d
SET "RecipeId" = m.keep_id
FROM recipe_dedup_map m
WHERE d."RecipeId" = m.remove_id;
-- AI recipe generator saved draft pointer
UPDATE diet."RecipeGeneratorSessions" s
SET "SavedRecipeId" = m.keep_id,
"UpdatedAt" = now()
FROM recipe_dedup_map m
WHERE s."SavedRecipeId" = m.remove_id;
-- Diet tracking (nullable FK)
UPDATE diet."MealConsumptions" c
SET "RecipeId" = m.keep_id
FROM recipe_dedup_map m
WHERE c."RecipeId" = m.remove_id;
-- Favorites: drop rows that would collide after merge, then re-point the rest
DELETE FROM diet."UserFavoriteRecipes" f
USING recipe_dedup_map m
WHERE f."RecipeId" = m.remove_id
AND EXISTS (
SELECT 1
FROM diet."UserFavoriteRecipes" f2
WHERE f2."UserId" = f."UserId"
AND f2."RecipeId" = m.keep_id
);
UPDATE diet."UserFavoriteRecipes" f
SET "RecipeId" = m.keep_id
FROM recipe_dedup_map m
WHERE f."RecipeId" = m.remove_id;
-- ---------------------------------------------------------------------------
-- 4) Delete duplicate recipes (Ingredients + RecipeSteps cascade)
-- ---------------------------------------------------------------------------
DELETE FROM diet."Recipes" r
USING recipe_dedup_map m
WHERE r."Id" = m.remove_id;
-- ---------------------------------------------------------------------------
-- 5) Verify
-- ---------------------------------------------------------------------------
DO $$
DECLARE
remaining_dup_names int;
recipe_count int;
BEGIN
SELECT count(*) INTO remaining_dup_names
FROM (
SELECT btrim("Name")
FROM diet."Recipes"
GROUP BY btrim("Name")
HAVING count(*) > 1
) d;
SELECT count(*) INTO recipe_count FROM diet."Recipes";
IF remaining_dup_names > 0 THEN
RAISE EXCEPTION 'Duplicate recipe names still present: % groups', remaining_dup_names;
END IF;
RAISE NOTICE 'Done. Active recipe count: %', recipe_count;
END $$;
COMMIT;
-- Optional hardening (uncomment if every recipe name must be unique going forward):
-- CREATE UNIQUE INDEX IF NOT EXISTS "UX_Recipes_Name"
-- ON diet."Recipes" (btrim("Name"))
-- WHERE "IsActive" AND NOT "IsDraft";

View File

@@ -0,0 +1,25 @@
-- 008_diet_draft_meal_ingredients.sql
-- Scaled ingredient amounts per diet generator draft meal (portions applied at plan time).
-- Apply after script 006.
BEGIN;
CREATE TABLE IF NOT EXISTS diet."DietGeneratorDraftMealIngredients" (
"Id" serial PRIMARY KEY,
"DraftMealId" int NOT NULL
REFERENCES diet."DietGeneratorDraftMeals"("Id") ON DELETE CASCADE,
"SourceIngredientId" int NULL
REFERENCES diet."Ingredients"("Id") ON DELETE SET NULL,
"Name" varchar(255) NOT NULL,
"AmountGrams" numeric(8,2) NULL,
"Unit" varchar(50) NULL,
"SortOrder" int NOT NULL DEFAULT 0
);
CREATE INDEX IF NOT EXISTS "IX_DietGeneratorDraftMealIngredients_DraftMealId"
ON diet."DietGeneratorDraftMealIngredients" ("DraftMealId");
COMMENT ON TABLE diet."DietGeneratorDraftMealIngredients" IS
'Ingredient weights recalculated for the planned portion size of each draft meal.';
COMMIT;

View File

@@ -0,0 +1,27 @@
-- Resync PostgreSQL identity sequences after bulk imports or manual ID inserts.
-- Safe to run multiple times. Run against the modwad database when new rows fail with:
-- duplicate key value violates unique constraint "Recipes_pkey"
SELECT setval(
pg_get_serial_sequence('diet."Recipes"', 'Id'),
COALESCE((SELECT MAX("Id") FROM diet."Recipes"), 1),
(SELECT MAX("Id") IS NOT NULL FROM diet."Recipes")
);
SELECT setval(
pg_get_serial_sequence('diet."Ingredients"', 'Id'),
COALESCE((SELECT MAX("Id") FROM diet."Ingredients"), 1),
(SELECT MAX("Id") IS NOT NULL FROM diet."Ingredients")
);
SELECT setval(
pg_get_serial_sequence('diet."RecipeSteps"', 'Id'),
COALESCE((SELECT MAX("Id") FROM diet."RecipeSteps"), 1),
(SELECT MAX("Id") IS NOT NULL FROM diet."RecipeSteps")
);
SELECT setval(
pg_get_serial_sequence('diet."RecipeGeneratorSessions"', 'Id'),
COALESCE((SELECT MAX("Id") FROM diet."RecipeGeneratorSessions"), 1),
(SELECT MAX("Id") IS NOT NULL FROM diet."RecipeGeneratorSessions")
);

173
database/scripts/README.md Normal file
View File

@@ -0,0 +1,173 @@
# Database scripts
SQL in this folder is applied **manually** on PostgreSQL. The API is database-first and does not run migrations.
## Diet tracking module
Run on your DailyMeals database:
```bash
psql "$DATABASE_URL" -f database/scripts/001_diet_tracking.sql
```
### Tables created
| Table | Purpose |
|-------|---------|
| `UserDailyGoals` | Daily calorie, macro, and water targets (per user) |
| `DrinkCatalog` | Preset drinks (water, tea, coffee, …) with default volumes |
| `MealConsumptions` | Meals the user ate (optional link to `Recipes`, macros snapshotted) |
| `DrinkConsumptions` | Hydration / beverage log |
| `DietReminders` | Reminder schedules (water, meal, custom) |
### API (after script + API deploy)
| Method | Endpoint |
|--------|----------|
| GET | `/api/diet/summary?date=YYYY-MM-DD` |
| GET/PUT | `/api/diet/goals` |
| GET/POST/DELETE | `/api/diet/meals` |
| GET | `/api/diet/drinks/catalog` |
| GET/POST/DELETE | `/api/diet/drinks` |
| GET/POST/PUT/DELETE | `/api/diet/reminders` |
| GET | `/api/diet/reminders/due?date=&time=` |
Web UI: **My Diet** at `/diet` in the React frontend.
## Ingredient nutrition catalog
```bash
psql "$DATABASE_URL" -f database/scripts/002_ingredient_nutrition_catalog.sql
```
### Tables created
| Table | Purpose |
|-------|---------|
| `IngredientCategories` | Food groups (meat, vegetables, dairy, …) |
| `IngredientNutritionCatalog` | Per-100 g calories, protein, fat, carbs, fiber |
### API (after script + API deploy)
| Method | Endpoint |
|--------|----------|
| GET | `/api/ingredient-catalog/categories` |
| GET | `/api/ingredient-catalog?category=&search=` |
| GET | `/api/ingredient-catalog/{id}` |
| POST | `/api/ingredient-catalog` |
| PUT | `/api/ingredient-catalog/{id}` |
| DELETE | `/api/ingredient-catalog/{id}` |
Web UI: **Ingredient catalog** at `/ingredients` in all frontends.
### Polish ingredient names
```bash
psql "$DATABASE_URL" -f database/scripts/003_ingredient_catalog_polish_names.sql
```
Adds `NamePl` column and Polish display names for all seeded catalog items. Search matches both English and Polish names.
## Extended features (meal planner, auth persistence, catalog linking)
```bash
psql "$DATABASE_URL" -f database/scripts/004_extended_features.sql
```
### Changes
| Object | Purpose |
|--------|---------|
| `RefreshTokens` | Persist web login sessions across API restarts |
| `MealPlanEntries` | Weekly meal planner (one recipe per meal slot per day) |
| `UserFavoriteRecipes` | Quick-log favorites |
| `Ingredients.CatalogItemId` | FK to nutrition catalog for auto macro calculation |
Run **after** scripts 001003.
## Catalog expansion + bulk ingredient linking
One-time migration for existing recipe data (based on your `Ingredients.csv` export):
```bash
psql "$DATABASE_URL" -f database/scripts/005_catalog_expansion_and_ingredient_linking.sql
```
### What it does
1. **Adds ~70 catalog items** missing from the seed (Polish staples: rye bread, dry pasta/rice, feta, tahini, passata, herbs/spices, …).
2. **Links `Ingredients.CatalogItemId`** via a name→catalog mapping (~218 ingredient name variants).
3. **Recalculates `Recipes` macros** as `SUM(catalog × AmountGrams / 100)` for all recipes with linked ingredients.
Reference mapping: `database/scripts/005_ingredient_name_mapping.csv` (ingredient name → catalog name → status).
After the script, check PostgreSQL notices for unlinked rows and recipes still missing macros. Spice rows (`do smaku`, `szczypta`) and rows without grams are intentionally skipped.
### API alternative (after linking)
If ingredients already have `CatalogItemId` set, you can recalculate without re-running SQL:
| Method | Endpoint |
|--------|----------|
| POST | `/api/recipes/recalculate-macros` |
Returns `{ recipesProcessed, recipesUpdated, unlinkedIngredientRows }`. Requires auth. Overwrites recipe macros when at least one linked ingredient has grams.
## AI generators (diet plan + recipes)
```bash
psql "$DATABASE_URL" -f database/scripts/006_diet_and_recipe_generators.sql
```
Configure OpenAI in `MealPlan.Api/appsettings.Local.json`:
```json
"OpenAI": {
"ApiKey": "sk-...",
"Model": "gpt-4.1-mini",
"MacrosModel": "gpt-4.1-mini",
"PlanModel": "gpt-4.1-mini",
"RecipeModel": "gpt-4.1",
"MaxTokens": 4096
}
```
| Setting | Used for |
|---------|----------|
| `MacrosModel` | Diet generator — refine daily kcal/macros |
| `PlanModel` | Diet generator — pick recipes for the week |
| `RecipeModel` | Recipe generator — ingredients + steps |
| `Model` | Fallback when a task model is omitted |
Without an API key, macro targets still use TDEE math and meal plans use a local greedy picker; recipe generation uses a simple fallback template.
### Diet generator API
| Method | Endpoint |
|--------|----------|
| GET/PUT | `/api/diet-generator/profile` |
| POST | `/api/diet-generator/sessions` |
| GET | `/api/diet-generator/sessions/{id}` |
| POST | `/api/diet-generator/sessions/{id}/propose-macros` |
| POST | `/api/diet-generator/sessions/{id}/accept-macros` |
| POST | `/api/diet-generator/sessions/{id}/generate-plan` |
| POST | `/api/diet-generator/sessions/{id}/regenerate-meal` |
| PATCH | `/api/diet-generator/sessions/{id}/meals/{mealId}` |
| POST | `/api/diet-generator/sessions/{id}/commit` |
Commit writes `UserDailyGoals` + `MealPlanEntries`. Daily calorie tolerance defaults to **10 kcal**.
### Recipe generator API
| Method | Endpoint |
|--------|----------|
| POST | `/api/recipe-generator/sessions` |
| GET | `/api/recipe-generator/sessions/{id}` |
| POST | `/api/recipe-generator/sessions/{id}/generate` |
| POST | `/api/recipe-generator/sessions/{id}/regenerate` |
| PUT | `/api/recipe-generator/sessions/{id}/draft` |
| POST | `/api/recipe-generator/sessions/{id}/commit` |
Saved recipes get `Source = ai_generated` and macros from the nutrition catalog.
Web UI: `/diet-generator` and `/recipe-generator` in the React frontend.