|
| 1 | +# 🍳 LazyCook – Projekt-Handout |
| 2 | + |
| 3 | +> **Webanwendung zur intelligenten Rezeptsuche anhand vorhandener Zutaten** |
| 4 | +> DHBW Karlsruhe · Software Engineering · 4. Semester |
| 5 | +
|
| 6 | +--- |
| 7 | + |
| 8 | +## 👥 Team |
| 9 | + |
| 10 | +| Name | GitHub-Handle | |
| 11 | +|------|---------------| |
| 12 | +| Eden Bernhard | EdenBernhard | |
| 13 | +| Samuel Göbel | GalacticCodeGambit | |
| 14 | +| Frederik Behne | Hellocrafting | |
| 15 | +| Niclas Matzke | Nicoolaus | |
| 16 | +| Alexander Groer | PrussianBaron | |
| 17 | + |
| 18 | +**Product-Owner:** Samuel Göbel | **Betreuer:** Harald Ichters (DHBW Karlsruhe) |
| 19 | + |
| 20 | +--- |
| 21 | + |
| 22 | +## 📊 Statistiken |
| 23 | + |
| 24 | +### Stunden pro Person & Hauptbeiträge |
| 25 | + |
| 26 | + |
| 27 | + |
| 28 | +| Person | Hauptbeiträge | |
| 29 | +|--------|---------------| |
| 30 | +| Eden Bernhard | Frontend (Next.js/React), Authentication-Flow | |
| 31 | +| Samuel Göbel | Product-Owner, Backend (FastAPI), Datenbankdesign | |
| 32 | +| Frederik Behne | Frontend-Komponenten, UI/UX | |
| 33 | +| Niclas Matzke | Tests, CI/CD, SonarCloud-Integration | |
| 34 | +| Alexander Groer | Algorithmus (SUCUK), Rezeptfilterung, Code-Reviews | |
| 35 | + |
| 36 | +### Stunden pro Disziplin |
| 37 | + |
| 38 | + |
| 39 | + |
| 40 | +### Stunden pro Phase |
| 41 | + |
| 42 | + |
| 43 | + |
| 44 | +### Disziplin & Phase kombiniert |
| 45 | + |
| 46 | + |
| 47 | + |
| 48 | +--- |
| 49 | + |
| 50 | +## 🎯 Projektziel & Vision |
| 51 | + |
| 52 | +**LazyCook** löst ein alltägliches Problem: Was koche ich heute mit dem, was ich zu Hause habe? |
| 53 | + |
| 54 | +Nutzer geben ihre vorhandenen Zutaten (Name, Menge, Einheit) und die Personenanzahl ein – LazyCook filtert daraufhin passende Rezepte aus einer Datenbank und zeigt sie übersichtlich als **3×3-Matrix** an. So werden Lebensmittelverschwendung reduziert und lästige Einkäufe gespart. |
| 55 | + |
| 56 | +**Kernziele:** |
| 57 | +- Schnell (Rezepte in **< 5 Sekunden** nach Klick auf „Filtern") |
| 58 | +- Sicher (Passwörter gehasht mit **PBKDF2-HMAC SHA-256 + Salt**) |
| 59 | +- Benutzerfreundlich (Registrierung → RecipeFinder in **wenigen Klicks**) |
| 60 | +- Cross-Browser-kompatibel (Chrome, Firefox, Safari, Edge) |
| 61 | + |
| 62 | +--- |
| 63 | + |
| 64 | +## 🏗️ Architektur |
| 65 | + |
| 66 | +LazyCook folgt einem **schichtbasierten Architekturstil** (ADR04) mit drei klar getrennten Schichten: |
| 67 | + |
| 68 | +``` |
| 69 | +┌─────────────────────────────────────────────┐ |
| 70 | +│ Browser (Nutzer) │ |
| 71 | +└──────────────────┬──────────────────────────┘ |
| 72 | + │ HTTP (Port 8000) |
| 73 | +┌──────────────────▼──────────────────────────┐ |
| 74 | +│ Frontend – Next.js 16 / React 19 │ |
| 75 | +│ TypeScript · Tailwind CSS · shadcn/ui │ |
| 76 | +│ Seiten: Homepage · Login · RecipeFinder │ |
| 77 | +└──────────────────┬──────────────────────────┘ |
| 78 | + │ REST API / JSON (Port 3000) |
| 79 | +┌──────────────────▼──────────────────────────┐ |
| 80 | +│ Backend – Python / FastAPI │ |
| 81 | +│ Gunicorn + Uvicorn (4 Worker) │ |
| 82 | +│ Auth · Rezeptfilterung · SUCUK-Algo │ |
| 83 | +└──────────────────┬──────────────────────────┘ |
| 84 | + │ SQLite3 |
| 85 | +┌──────────────────▼──────────────────────────┐ |
| 86 | +│ Datenbank – SQLite (LazyCookDB.sqlite3) │ |
| 87 | +│ Tabellen: Konto · Nutzer · Rezept · │ |
| 88 | +│ Zutat · Besteht_Aus · Verfasser │ |
| 89 | +└─────────────────────────────────────────────┘ |
| 90 | +``` |
| 91 | + |
| 92 | +**Deployment:** Zwei Docker-Container (Frontend + Backend) via **Docker Compose**, mit persistiertem SQLite-Volume. |
| 93 | + |
| 94 | +--- |
| 95 | + |
| 96 | +## 🗄️ Datenbank-Design |
| 97 | + |
| 98 | + |
| 99 | + |
| 100 | +**Schlüssel-Tabellen:** |
| 101 | + |
| 102 | +| Tabelle | Schlüsselfelder | Beschreibung | |
| 103 | +|---------|-----------------|--------------| |
| 104 | +| `Konto` | id, email, passwort (PBKDF2), salt | Benutzerkonten – Passwörter niemals im Klartext | |
| 105 | +| `Nutzer` | id, name, kid → Konto | Nutzerprofile | |
| 106 | +| `Rezept` | id, name, vid → Verfasser | Rezept-Entitäten | |
| 107 | +| `Zutat` | id, name, mengenArt | Zutaten-Stammdaten | |
| 108 | +| `Besteht_Aus` | zid → Zutat, rid → Rezept, menge | **N:M-Beziehung** Zutat ↔ Rezept | |
| 109 | +| `Verfasser` | id, name | Rezeptautoren | |
| 110 | + |
| 111 | +--- |
| 112 | + |
| 113 | +## 🔍 SUCUK-Algorithmus |
| 114 | + |
| 115 | +**SUCUK** = *Search for Uncomplicated Cooking and User-friendly Kitchen recipes* |
| 116 | + |
| 117 | +Der Kern von LazyCook: Der Algorithmus empfängt die eingetragenen Zutaten und die Personenanzahl, gleicht sie gegen die `Besteht_Aus`-Tabelle ab und liefert die **Top-100 passendsten Rezepte** nach Übereinstimmungsgrad zurück. Das Frontend zeigt davon jeweils 9 (3×3-Matrix) an; ein „Mehr"-Button lädt weitere Ergebnisse. |
| 118 | + |
| 119 | +--- |
| 120 | + |
| 121 | +## 🛠️ Verwendete Technologien & Tools |
| 122 | + |
| 123 | +### Frontend |
| 124 | +| Technologie | Zweck | |
| 125 | +|-------------|-------| |
| 126 | +| **Next.js 16** | React-Framework, SSR/CSR | |
| 127 | +| **React 19** | UI-Komponentensystem | |
| 128 | +| **TypeScript** | Typsichere Entwicklung | |
| 129 | +| **Tailwind CSS** | Utility-First-Styling | |
| 130 | +| **shadcn/ui + Radix UI** | Barrierefreie UI-Komponenten | |
| 131 | +| **Lucide Icons** | Icon-Bibliothek | |
| 132 | + |
| 133 | +### Backend |
| 134 | +| Technologie | Zweck | |
| 135 | +|-------------|-------| |
| 136 | +| **Python 3.11** | Hauptsprache | |
| 137 | +| **FastAPI** | REST-API-Framework | |
| 138 | +| **Gunicorn + Uvicorn** | ASGI-Server (4 Worker) | |
| 139 | +| **Pydantic** | Request/Response-Validierung | |
| 140 | +| **hashlib (PBKDF2-HMAC)** | Passwort-Hashing mit Salt | |
| 141 | + |
| 142 | +### Datenbank & Infrastruktur |
| 143 | +| Technologie | Zweck | |
| 144 | +|-------------|-------| |
| 145 | +| **SQLite 3** | Eingebettete relationale Datenbank | |
| 146 | +| **Docker / Docker Compose** | Containerisierung & Deployment | |
| 147 | +| **Node.js 24 (alpine)** | Frontend-Container-Basis | |
| 148 | +| **Python 3.11 (slim)** | Backend-Container-Basis | |
| 149 | + |
| 150 | +### Qualität & DevOps |
| 151 | +| Technologie | Zweck | |
| 152 | +|-------------|-------| |
| 153 | +| **GitHub Actions** | CI/CD-Pipelines | |
| 154 | +| **Pytest + pytest-cov** | Backend Unit-Tests & Coverage | |
| 155 | +| **Super-Linter** | Python (Black, Flake8) + TS/CSS-Linting | |
| 156 | +| **SonarCloud** | Statische Code-Analyse, Metriken, Quality Gate | |
| 157 | +| **CodeQL** | Automatische Sicherheitsanalyse (Python, TS, Actions) | |
| 158 | +| **GitHub Projects** | Agiles Projektmanagement (Kanban) | |
| 159 | +| **IntelliJ IDEA** | Entwicklungsumgebung | |
| 160 | + |
| 161 | +--- |
| 162 | + |
| 163 | +## ✅ Tests & Metriken |
| 164 | + |
| 165 | +### Test-Suite (Backend) |
| 166 | +- **Framework:** Pytest |
| 167 | +- **Test-Dateien:** `test_main.py`, `test_database.py`, `test_email.py`, `test_password.py` |
| 168 | +- **Coverage-Messung:** `pytest-cov` → XML-Report für SonarCloud |
| 169 | + |
| 170 | +### CI/CD-Pipeline (GitHub Actions) |
| 171 | + |
| 172 | +``` |
| 173 | +Push / PR → main |
| 174 | + │ |
| 175 | + ├─▶ [ci.yml] Docker Compose Build |
| 176 | + │ → Services starten |
| 177 | + │ → Smoke-Test Frontend (Port 8000) |
| 178 | + │ → pytest Backend-Tests (im Container) |
| 179 | + │ |
| 180 | + ├─▶ [lint.yml] Super-Linter |
| 181 | + │ → Python: Black + Flake8 |
| 182 | + │ → TypeScript/JS: ESLint |
| 183 | + │ → CSS, Dockerfile, YAML, GitHub Actions |
| 184 | + │ |
| 185 | + ├─▶ [sonarqube.yml] pytest mit Coverage-Report (XML) |
| 186 | + │ → SonarCloud Scan |
| 187 | + │ → Quality Gate Check |
| 188 | + │ |
| 189 | + └─▶ [codeql.yml] CodeQL-Analyse |
| 190 | + → Python, TypeScript, Actions |
| 191 | +``` |
| 192 | + |
| 193 | +### SonarCloud-Metriken (Stand Demo) |
| 194 | + |
| 195 | +| Kategorie | Wert | |
| 196 | +|-----------|------| |
| 197 | +| Quality Gate | `[PLACEHOLDER – PASSED / FAILED]` | |
| 198 | +| Lines of Code | `[PLACEHOLDER]` | |
| 199 | +| Backend Coverage (gesamt) | `[PLACEHOLDER – z. B. XX %]` | |
| 200 | +| Line Coverage | `[PLACEHOLDER]` | |
| 201 | +| Branch Coverage | `[PLACEHOLDER]` | |
| 202 | +| Bugs | `[PLACEHOLDER]` | |
| 203 | +| Code Smells | `[PLACEHOLDER]` | |
| 204 | +| Vulnerabilities | `[PLACEHOLDER]` | |
| 205 | +| Reliability Rating | `[PLACEHOLDER – A/B/C]` | |
| 206 | +| Maintainability Rating | `[PLACEHOLDER – A/B/C]` | |
| 207 | + |
| 208 | +--- |
| 209 | + |
| 210 | +## 🏆 Highlights & Stolz-Punkte |
| 211 | + |
| 212 | +| # | Highlight | Details | |
| 213 | +|---|-----------|---------| |
| 214 | +| 1 | **Sicherheit** | PBKDF2-HMAC SHA-256, 100.000 Iterationen, zufälliges 16-Byte-Salt – kein Klartext-Passwort in der DB | |
| 215 | +| 2 | **SUCUK-Algorithmus** | Eigenentwickelter Rezept-Ranking-Algorithmus mit sprechender Abkürzung | |
| 216 | +| 3 | **Vollständige CI/CD-Pipeline** | 4 parallele GitHub Actions Workflows (CI, Lint, SonarCloud, CodeQL) | |
| 217 | +| 4 | **Architektur-ADRs** | 5 dokumentierte Architecture Decision Records (ADR01–ADR05) | |
| 218 | +| 5 | **LSP im Backend** | Liskov Substitution Principle ermöglicht späteren DB-Wechsel (z. B. → PostgreSQL) ohne Geschäftslogik-Änderung | |
| 219 | +| 6 | **Docker-Deployment** | Reproduzierbares, containerisiertes Setup mit einem einzigen `docker compose up` | |
| 220 | +| 7 | **Code-Qualität** | Automatisches Linting (Black, Flake8, ESLint) + SonarCloud Quality Gate bei jedem PR | |
| 221 | +| 8 | **UX-Entscheidungen** | Direkte Weiterleitung nach Registrierung (ADR02), 3×3-Matrix gegen Informationsüberladung (ADR03) | |
| 222 | + |
| 223 | +--- |
| 224 | + |
| 225 | +## 🔗 Ressourcen |
| 226 | + |
| 227 | +- **GitHub:** [github.com/GalacticCodeGambit/LazyCook](https://github.com/GalacticCodeGambit/LazyCook) |
| 228 | +- **SonarCloud Dashboard:** [sonarcloud.io/project/overview?id=GalacticCodeGambit_LazyCook](https://sonarcloud.io/project/overview?id=GalacticCodeGambit_LazyCook) |
| 229 | +- **Mockups:** `docs/mockup/` |
| 230 | +- **ADRs:** `docs/adr/` |
| 231 | + |
| 232 | +--- |
| 233 | + |
| 234 | +*Handout erstellt für die Abschlusspräsentation · DHBW Karlsruhe · 2026* |
0 commit comments