From a763f656544ec10016e0ec82a8f376805af19a21 Mon Sep 17 00:00:00 2001 From: Nils-Johan Gynther Date: Fri, 17 Apr 2026 22:57:53 +0200 Subject: [PATCH] feat(categories): add category seeding functionality and update deployment script --- TEKNISK_BESKRIVNING.md | 13 ++ db/seeds/categories_supplement.sql | 282 +++++++++++++++++++++++++++++ deploy.sh | 7 + 3 files changed, 302 insertions(+) create mode 100644 db/seeds/categories_supplement.sql diff --git a/TEKNISK_BESKRIVNING.md b/TEKNISK_BESKRIVNING.md index d8843e76..797ba01f 100644 --- a/TEKNISK_BESKRIVNING.md +++ b/TEKNISK_BESKRIVNING.md @@ -389,6 +389,19 @@ model Category { Hierarkin har 3 nivåer: **Huvudkategori → Underkategori → Typ** Exempelträd: `Mejeri, ost & ägg → Mjölk → Laktosfri mjölk` +#### Kategori-seed + +Kategorier seedas på två sätt: + +1. **Migrationen** `20260417310000_add_category_tree/migration.sql` — seedar grundläggande kategorier vid `prisma migrate deploy` (körs bara en gång). + +2. **`db/seeds/categories_supplement.sql`** — idempotent supplementfil med ytterligare kategorier (använder `INSERT IGNORE`). Körs automatiskt av `deploy.sh` vid varje deploy: + ```bash + docker exec -i recipe-db mariadb -uroot -p"$MARIADB_ROOT_PASSWORD" "$MARIADB_DATABASE" \ + < db/seeds/categories_supplement.sql + ``` + Filen är säker att köra flera gånger — befintliga kategorier hoppas över. Lägg till nya kategorier i slutet av filen och kör `deploy.sh` för att applicera dem. + ### Product ```prisma model Product { diff --git a/db/seeds/categories_supplement.sql b/db/seeds/categories_supplement.sql new file mode 100644 index 00000000..22daaa15 --- /dev/null +++ b/db/seeds/categories_supplement.sql @@ -0,0 +1,282 @@ +-- ============================================================ +-- Supplement: Kategorier från produktfilen +-- Kör på servern: mysql -u root -p recipe_app < db/seeds/categories_supplement.sql +-- Använder INSERT IGNORE + subqueries — säkert att köra flera gånger. +-- ============================================================ + +-- ============================================================ +-- LEVEL 1 — Toppkategorier (nya) +-- ============================================================ +INSERT IGNORE INTO `Category` (`name`, `parentId`) VALUES + ('Dryck', NULL); + +-- ============================================================ +-- LEVEL 2 — under Dryck +-- ============================================================ +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Öl & cider', id FROM `Category` WHERE name = 'Dryck' AND parentId IS NULL; +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Läsk och Energidryck', id FROM `Category` WHERE name = 'Dryck' AND parentId IS NULL; + +-- ============================================================ +-- LEVEL 2 — under Bröd & Kakor (tillägg) +-- ============================================================ +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Knäckebröd & Skorpor', id FROM `Category` WHERE name = 'Bröd & Kakor' AND parentId IS NULL; + +-- ============================================================ +-- LEVEL 2 — under Färdigmat (tillägg) +-- ============================================================ +-- (Kylda såser hanteras på L3 — Såser, grytbaser... finns redan) + +-- ============================================================ +-- LEVEL 2 — under Fryst (tillägg) +-- ============================================================ +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Frukt & Bär', id FROM `Category` WHERE name = 'Fryst' AND parentId IS NULL; +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Färdigmat', id FROM `Category` WHERE name = 'Fryst' AND parentId IS NULL; + +-- ============================================================ +-- LEVEL 2 — under Frukt & Grönt (tillägg) +-- ============================================================ +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Grönsaker', id FROM `Category` WHERE name = 'Frukt & Grönt' AND parentId IS NULL; +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Frukt', id FROM `Category` WHERE name = 'Frukt & Grönt' AND parentId IS NULL; +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Färska bär', id FROM `Category` WHERE name = 'Frukt & Grönt' AND parentId IS NULL; +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Svamp', id FROM `Category` WHERE name = 'Frukt & Grönt' AND parentId IS NULL; + +-- ============================================================ +-- LEVEL 2 — under Glass, godis & snacks (tillägg) +-- ============================================================ +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Choklad', id FROM `Category` WHERE name = 'Glass, godis & snacks' AND parentId IS NULL; + +-- ============================================================ +-- LEVEL 2 — under Kött, chark & fågel (tillägg) +-- ============================================================ +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Kött', id FROM `Category` WHERE name = 'Kött, chark & fågel' AND parentId IS NULL; +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Fågel', id FROM `Category` WHERE name = 'Kött, chark & fågel' AND parentId IS NULL; + +-- ============================================================ +-- LEVEL 2 — under Mejeri, ost & ägg (tillägg) +-- ============================================================ +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Mellanmål & desserter', id FROM `Category` WHERE name = 'Mejeri, ost & ägg' AND parentId IS NULL; + +-- ============================================================ +-- LEVEL 2 — under Skafferi (tillägg) +-- ============================================================ +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Torkad frukt', id FROM `Category` WHERE name = 'Skafferi' AND parentId IS NULL; +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Torra baljväxter', id FROM `Category` WHERE name = 'Skafferi' AND parentId IS NULL; +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Bakning', id FROM `Category` WHERE name = 'Skafferi' AND parentId IS NULL; + +-- ============================================================ +-- LEVEL 3 — under Bröd & Kakor > Knäckebröd & Skorpor +-- ============================================================ +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Knäckebröd', c2.id + FROM `Category` c1 + JOIN `Category` c2 ON c2.parentId = c1.id AND c2.name = 'Knäckebröd & Skorpor' + WHERE c1.name = 'Bröd & Kakor' AND c1.parentId IS NULL; + +-- ============================================================ +-- LEVEL 3 — under Bröd & Kakor > Kex & Kakor (tillägg) +-- ============================================================ +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Söta kex & kakor', c2.id + FROM `Category` c1 + JOIN `Category` c2 ON c2.parentId = c1.id AND c2.name = 'Kex & Kakor' + WHERE c1.name = 'Bröd & Kakor' AND c1.parentId IS NULL; + +-- ============================================================ +-- LEVEL 3 — under Färdigmat > Såser, grytbaser & övriga smaksättare (tillägg) +-- ============================================================ +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Kylda såser', c2.id + FROM `Category` c1 + JOIN `Category` c2 ON c2.parentId = c1.id AND c2.name = 'Såser, grytbaser & övriga smaksättare' + WHERE c1.name = 'Färdigmat' AND c1.parentId IS NULL; + +-- ============================================================ +-- LEVEL 3 — under Fryst > Färdigmat +-- ============================================================ +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Pizza, paj & piroger', c2.id + FROM `Category` c1 + JOIN `Category` c2 ON c2.parentId = c1.id AND c2.name = 'Färdigmat' + WHERE c1.name = 'Fryst' AND c1.parentId IS NULL; + +-- ============================================================ +-- LEVEL 3 — under Fryst > Grönsaker & kryddor (tillägg) +-- ============================================================ +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Grönsaker', c2.id + FROM `Category` c1 + JOIN `Category` c2 ON c2.parentId = c1.id AND c2.name = 'Grönsaker & kryddor' + WHERE c1.name = 'Fryst' AND c1.parentId IS NULL; + +-- ============================================================ +-- LEVEL 3 — under Frukt & Grönt > Grönsaker +-- ============================================================ +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Bönor & Groddar', c2.id + FROM `Category` c1 + JOIN `Category` c2 ON c2.parentId = c1.id AND c2.name = 'Grönsaker' + WHERE c1.name = 'Frukt & Grönt' AND c1.parentId IS NULL; +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Paprika', c2.id + FROM `Category` c1 + JOIN `Category` c2 ON c2.parentId = c1.id AND c2.name = 'Grönsaker' + WHERE c1.name = 'Frukt & Grönt' AND c1.parentId IS NULL; +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Övriga grönsaker', c2.id + FROM `Category` c1 + JOIN `Category` c2 ON c2.parentId = c1.id AND c2.name = 'Grönsaker' + WHERE c1.name = 'Frukt & Grönt' AND c1.parentId IS NULL; +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Tomater', c2.id + FROM `Category` c1 + JOIN `Category` c2 ON c2.parentId = c1.id AND c2.name = 'Grönsaker' + WHERE c1.name = 'Frukt & Grönt' AND c1.parentId IS NULL; +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Färdigskuret', c2.id + FROM `Category` c1 + JOIN `Category` c2 ON c2.parentId = c1.id AND c2.name = 'Grönsaker' + WHERE c1.name = 'Frukt & Grönt' AND c1.parentId IS NULL; + +-- ============================================================ +-- LEVEL 3 — under Frukt & Grönt > Potatis & rotsaker (tillägg) +-- ============================================================ +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Rotsaker', c2.id + FROM `Category` c1 + JOIN `Category` c2 ON c2.parentId = c1.id AND c2.name = 'Potatis & rotsaker' + WHERE c1.name = 'Frukt & Grönt' AND c1.parentId IS NULL; + +-- ============================================================ +-- LEVEL 3 — under Frukt & Grönt > Frukt +-- ============================================================ +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Druvor', c2.id + FROM `Category` c1 + JOIN `Category` c2 ON c2.parentId = c1.id AND c2.name = 'Frukt' + WHERE c1.name = 'Frukt & Grönt' AND c1.parentId IS NULL; +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Citrusfrukt', c2.id + FROM `Category` c1 + JOIN `Category` c2 ON c2.parentId = c1.id AND c2.name = 'Frukt' + WHERE c1.name = 'Frukt & Grönt' AND c1.parentId IS NULL; + +-- ============================================================ +-- LEVEL 3 — under Glass, godis & snacks > Choklad +-- ============================================================ +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Chokladkakor & rullar', c2.id + FROM `Category` c1 + JOIN `Category` c2 ON c2.parentId = c1.id AND c2.name = 'Choklad' + WHERE c1.name = 'Glass, godis & snacks' AND c1.parentId IS NULL; + +-- ============================================================ +-- LEVEL 3 — under Kött, chark & fågel > Kött +-- ============================================================ +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Färdiglagat & pannfärdigt', c2.id + FROM `Category` c1 + JOIN `Category` c2 ON c2.parentId = c1.id AND c2.name = 'Kött' + WHERE c1.name = 'Kött, chark & fågel' AND c1.parentId IS NULL; +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Fläsk', c2.id + FROM `Category` c1 + JOIN `Category` c2 ON c2.parentId = c1.id AND c2.name = 'Kött' + WHERE c1.name = 'Kött, chark & fågel' AND c1.parentId IS NULL; + +-- ============================================================ +-- LEVEL 3 — under Kött, chark & fågel > Fågel +-- ============================================================ +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Fryst fågel', c2.id + FROM `Category` c1 + JOIN `Category` c2 ON c2.parentId = c1.id AND c2.name = 'Fågel' + WHERE c1.name = 'Kött, chark & fågel' AND c1.parentId IS NULL; + +-- ============================================================ +-- LEVEL 3 — under Mejeri, ost & ägg > Ost (tillägg) +-- ============================================================ +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Matlagningsost', c2.id + FROM `Category` c1 + JOIN `Category` c2 ON c2.parentId = c1.id AND c2.name = 'Ost' + WHERE c1.name = 'Mejeri, ost & ägg' AND c1.parentId IS NULL; + +-- ============================================================ +-- LEVEL 3 — under Skafferi > Torra baljväxter +-- ============================================================ +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Fröer & kärnor', c2.id + FROM `Category` c1 + JOIN `Category` c2 ON c2.parentId = c1.id AND c2.name = 'Torra baljväxter' + WHERE c1.name = 'Skafferi' AND c1.parentId IS NULL; + +-- ============================================================ +-- LEVEL 3 — under Skafferi > Bakning +-- ============================================================ +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Baktillbehör', c2.id + FROM `Category` c1 + JOIN `Category` c2 ON c2.parentId = c1.id AND c2.name = 'Bakning' + WHERE c1.name = 'Skafferi' AND c1.parentId IS NULL; + +-- ============================================================ +-- LEVEL 3 — under Skafferi > Kryddor & smaksättare (tillägg) +-- ============================================================ +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Övriga smaksättare', c2.id + FROM `Category` c1 + JOIN `Category` c2 ON c2.parentId = c1.id AND c2.name = 'Kryddor & smaksättare' + WHERE c1.name = 'Skafferi' AND c1.parentId IS NULL; + +-- ============================================================ +-- LEVEL 3 — under Skafferi > Pasta, ris & matgryn (tillägg) +-- ============================================================ +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Pasta', c2.id + FROM `Category` c1 + JOIN `Category` c2 ON c2.parentId = c1.id AND c2.name = 'Pasta, ris & matgryn' + WHERE c1.name = 'Skafferi' AND c1.parentId IS NULL; + +-- ============================================================ +-- LEVEL 3 — under Skafferi > Konserver & burkar (tillägg) +-- ============================================================ +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Fruktkonserver', c2.id + FROM `Category` c1 + JOIN `Category` c2 ON c2.parentId = c1.id AND c2.name = 'Konserver & burkar' + WHERE c1.name = 'Skafferi' AND c1.parentId IS NULL; +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Grönsakskonserver', c2.id + FROM `Category` c1 + JOIN `Category` c2 ON c2.parentId = c1.id AND c2.name = 'Konserver & burkar' + WHERE c1.name = 'Skafferi' AND c1.parentId IS NULL; +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Fisk-& skaldjurskonserver', c2.id + FROM `Category` c1 + JOIN `Category` c2 ON c2.parentId = c1.id AND c2.name = 'Konserver & burkar' + WHERE c1.name = 'Skafferi' AND c1.parentId IS NULL; + +-- ============================================================ +-- LEVEL 3 — under Skafferi > Asien (tillägg) +-- ============================================================ +INSERT IGNORE INTO `Category` (`name`, `parentId`) + SELECT 'Nudlar', c2.id + FROM `Category` c1 + JOIN `Category` c2 ON c2.parentId = c1.id AND c2.name = 'Asien' + WHERE c1.name = 'Skafferi' AND c1.parentId IS NULL; diff --git a/deploy.sh b/deploy.sh index cb2ff2c9..4d869191 100644 --- a/deploy.sh +++ b/deploy.sh @@ -20,5 +20,12 @@ docker compose build echo "Startar tjänster..." docker compose up -d +echo "Kör kategori-seed..." +MARIADB_ROOT_PASSWORD=$(grep MARIADB_ROOT_PASSWORD .env | cut -d '=' -f2 | tr -d '"' | tr -d "'") +MARIADB_DATABASE=$(grep MARIADB_DATABASE .env | cut -d '=' -f2 | tr -d '"' | tr -d "'") +docker exec -i recipe-db mariadb -uroot -p"$MARIADB_ROOT_PASSWORD" "$MARIADB_DATABASE" \ + < db/seeds/categories_supplement.sql +echo "Kategori-seed klar." + echo "Status:" docker compose ps