From 30fb8b265becc2298882c6265f925aec9b307c5f Mon Sep 17 00:00:00 2001 From: Nils-Johan Gynther Date: Mon, 20 Apr 2026 10:26:18 +0200 Subject: [PATCH] docs: enhance technical description with detailed development environment and deployment workflow --- TEKNISK_BESKRIVNING.md | 158 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 157 insertions(+), 1 deletion(-) diff --git a/TEKNISK_BESKRIVNING.md b/TEKNISK_BESKRIVNING.md index e473867c..60c62eed 100644 --- a/TEKNISK_BESKRIVNING.md +++ b/TEKNISK_BESKRIVNING.md @@ -27,7 +27,73 @@ Recipe App är en fullstack-applikation för hantering av hemmavaror, recept och | Container | Docker | 24+ | | Converter | Node.js (TypeScript) | Noll externa beroenden | -### Container- och deployupplägg +--- + +## Utvecklingsmiljö och deployment + +### Infrastruktur + +**Utvecklingsmiljön är en remote server** med följande struktur: + +- **Server:** Dedikerad maskin med Docker installerat +- **SSH-baserad utveckling:** All utveckling, bygge och körning av applikationen sker via SSH-kommandon på servern +- **Lokal förberedelse:** Mindre arbetsuppgifter kan förberedas lokalt och sedan pushas till servern för slutförande + +### Arbetsflöde + +``` +Lokal maskin + │ + ├─── Git-ändringar (commit) ──┐ + │ │ + └─── Push till Gitea-server ──→ Privat Gitea-instans + (i Docker-container) + │ + ↓ + Remote server + │ + ├─── git pull ────────────────┤ + │ │ + └─── docker compose build ─────┤ + │ │ + └─── docker compose up ───────┘ +``` + +### Git-server (Gitea) + +- **Gitea** körs i en Docker-container på servern +- **Privat git-server** för denna applikation +- Ändringar pushas lokalt till denna server: + ```bash + git push origin main + ``` + +### Bygge och körning på servern + +Efter push till Gitea: + +1. **SSH in på servern** + ```bash + ssh user@server + cd /path/to/recipe-app + ``` + +2. **Hämta senaste ändringar** + ```bash + git pull origin main + ``` + +3. **Bygg och starta applikationen** + ```bash + docker compose build + docker compose up -d + ``` + +Alla tjänster (frontend, backend, databas) startas via Docker Compose enligt `compose.yml`. + +--- + +## Container- och deployupplägg - `compose.yml` bygger lokala images för frontend och backend - `pull_policy: never` används för appens lokala images för att undvika felaktiga registry-pulls i Portainer @@ -1266,6 +1332,96 @@ Konfigureras via `.env` eller `docker compose up`: --- +## Databaskonfiguration och seeding + +### Databaskonfiguration + +**MariaDB 11** hostas i Docker-container (`recipe-db`) enligt `compose.yml`. Databasen använder: +- **Teckenuppsättning:** UTF-8 (utf8mb4) för korrekt stöd för svenska tecken +- **Sortering:** utf8mb4_swedish_ci för svensk alfabetisk sortering +- **Anslutning:** Via Prisma ORM från backend-tjänsten + +**Initialisering:** +1. `db/init/001-init.sql` körs vid första container-start (grundläggande tablestatus) +2. Prisma migrations körs automatiskt vid backend-start +3. `db/seeds/seed_all.sql` körs manuellt för att fylla på initiala kategorier och produkter + +### seed_all.sql — Kategori- och produktdatabas + +**Filplats:** `db/seeds/seed_all.sql` + +**Syfte:** +`seed_all.sql` är ensam sanningskälla för kategoriträdet. Den innehåller: +1. **Kategoristruktur** — Hierarkiskt träd från nivå 1 (toppkategorier) till nivå 3 (underkategorier) +2. **Initiala produkter** — 200+ standardprodukter (köttfärs, ost, frukt, etc.) +3. **Kategoritilldelning** — Kopplar produkterna till rätt kategorier + +**Struktur:** + +| Steg | Vad | Detaljer | +|------|-----|----------| +| **RESET** | Förberedelse | `SET foreign_key_checks = 0` → `TRUNCATE TABLE Category` → `UPDATE Product SET categoryId = NULL` | +| **STEG 1** | Kategorier NIVÅ 1-3 | INSERT INTO Category för alla toppkategorier, nivå 2 och nivå 3-kategorier. Använder SELECT med JOINs för hierarkisk struktur. | +| **STEG 2** | Produkter | `INSERT IGNORE INTO Product` — Befintliga produkter hoppas över (inga dubletter). | +| **STEG 3** | Kategoritilldelning | UPDATE Product ... WHERE name IN (...) för att tilldela rätt categoryId baserat på produktnamn. | + +**Köra seed_all.sql:** + +```bash +# Hämta lösenordet från .env eller Docker +DB_PASS=$(grep MARIADB_ROOT_PASSWORD .env | cut -d= -f2) + +# Kör skriptet in i databasen +docker exec -i recipe-db mariadb -uroot -p"$DB_PASS" recipe_app < db/seeds/seed_all.sql +``` + +**Viktigt:** Denna kommando kan köras **hur många gånger som helst**: +- `TRUNCATE` raderar alla befintliga kategorier (men inte produkterna själva) +- `INSERT IGNORE` förhindrar dubbletter av produkter +- Befintliga produkt-data (namn, märke, etc.) påverkas inte — endast `categoryId` uppdateras + +**Fördelar med denna design:** +- ✅ Reproducerbar — idempotent, kan köras flera gånger +- ✅ Enkel migrering — alla ändringar i kategoriträdet är i en fil +- ✅ Ingen datarisk — produkter försvinner aldrig, enbart omkategorisering +- ✅ Admin-gränssnittet kan senare modifiera kategorier interaktivt (seed_all är enbart för initial setup) + +### Kategoristruktur + +**Nivå 1 (Toppkategorier):** +- Bröd & Kakor +- Dryck +- Färdigmat +- Fryst +- Frukt & Grönt +- Glass, godis & snacks +- Kött, chark & fågel +- Mejeri, ost & ägg +- Skafferi +- Fisk & Skaldjur *(tillagd senare)* +- Vegetariskt *(tillagd senare)* + +**Nivå 2 (Underkategorier, exempel):** +- Bröd & Kakor > Bröd, Fastfoodbröd, Kex & Kakor, Knäckebröd & Skorpor +- Mejeri, ost & ägg > Ost, Allergi mejeri, Mjölk, Filmjölk & Yoghurt, Matlagning, Smör/margarin & jäst, Havre-/Soja-/Risdryck, Kvarg & Cottage cheese + +**Nivå 3 (Specifika kategorier, exempel):** +- Bröd & Kakor > Bröd > Matbröd, Rostbröd +- Frukt & Grönt > Grönsaker > Sallad & Kål, Auberginer & Zucchini, Paprika, Övriga grönsaker, Tomater + +### Uppdatering av kategorier + +Nya kategorier läggs till direkt i `db/seeds/seed_all.sql`. Efter ändringar: + +```bash +# Kör seed_all.sql igen för att uppdatera kategoriträdet +docker exec -i recipe-db mariadb -uroot -p"$DB_PASS" recipe_app < db/seeds/seed_all.sql +``` + +Produkterna behålls och omkategoriseras enligt de nya UPDATE-satserna. + +--- + ## Framtida arkitektur: Microservice Importer Recipe App har ett **companion-projekt** för receptimport: [`microservice-importer`](../microservice-importer/)