Skip to content

Blatt17#170

Merged
GalacticCodeGambit merged 46 commits into
mainfrom
blatt17
May 20, 2026
Merged

Blatt17#170
GalacticCodeGambit merged 46 commits into
mainfrom
blatt17

Conversation

@GalacticCodeGambit
Copy link
Copy Markdown
Owner

No description provided.

PrussianBaron and others added 30 commits May 4, 2026 15:11
… geschrieben. Die dazugehörigen Abhängigkeiten in requirements.txt angepasst. Sie werden in test_main.py aufgerufen.

Namens faktorisierung ist schwer bei den Klassennamen da bei tests der pycharm Debugger eher auf klassen mit test_ vorne guckt. Deswegen leider test_
* Rename models.py to Models.py

* Rename auth.py to Auth.py

* Rename Routes.py to routes.py

* Added Refactoring Summary

* Refactor documentation for code naming conventions

* Fix spelling errors in refactoring documentation

Corrected spelling of 'Refaktorisierung' and 'Frontend'.

* Delete project/data/LazyCookDB.sqlite3

* AI Agent md's changed

* Passwort und Email Änderung zu Popups geändert. und neugeordnet untereinander

* Update README.md to mark tasks as completed for account management features

* Add CI/CD pipeline and Super Linter configuration

* Test für lint

* Test ci/cd lint.yml

* Test ci/cd lint.yml

* Test ci/cd lint.yml

* Test ci/cd lint.yml regex Filter

* Test ci/cd lint.yml

* Test ci/cd lint.yml

* Test ci/cd lint.yml regex Filter angepasst

* Tests für Database, passwort überprüfung und email überürufung wurden geschrieben. Die dazugehörigen Abhängigkeiten in requirements.txt angepasst. Sie werden in test_main.py aufgerufen.
Namens faktorisierung ist schwer bei den Klassennamen da bei tests der pycharm Debugger eher auf klassen mit test_ vorne guckt. Deswegen leider test_

* ci pipeline abhägigkeit mit rein gemacht

* Feat bei Ci yml entfernt

* Update FILTER_REGEX_INCLUDE pattern in lint.yml

* Update lint.yml

* Enable validation for the entire codebase

* Update lint.yml

* Update lint.yml

* Enable validation for all codebase in lint workflow

* Remove Python Black and Markdown validation

* Update lint workflow to include additional validations

* Update FILTER_REGEX_INCLUDE to support YAML files

* Update lint.yml

* Update lint.yml

* Refactor CI configuration to use Docker Compose v2 syntax and add GitHub Super Linter step

* Test ci.yml

* Update ci.yml

* Enable Flake8 validation for Python files

* Test ci.yml

* Remove 'feat/*' branch from push trigger in CI configuration

* Python black gelöst

---------

Co-authored-by: Samuel Goebel <goebelsamuel@gmail.com>
Co-authored-by: Eden Tabea Bernhard <105359952+EdenBernhard@users.noreply.github.com>
Co-authored-by: Nicoolaus <162422307+Nicoolaus@users.noreply.github.com>
Co-authored-by: Hellocrafting <alexanderfgroer@gmail.com>
Co-authored-by: nicla <niclas.matzke@gmail.com>
Co-authored-by: Hellocrafting <75727565+Hellocrafting@users.noreply.github.com>
# Conflicts:
#	project/data/LazyCookDB.sqlite3
# Conflicts:
#	.github/workflows/ci.yml
#	project/backend/tests/test_database.py
#	project/backend/tests/test_email.py
#	project/backend/tests/test_main.py
#	project/backend/tests/test_password.py
* Separate linter configuration into its own workflow file

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Update README.md to reflect linter workflow separation and installation instructions

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
# Conflicts:
#	project/backend/Database.py
#	project/backend/EmailService.py
#	project/backend/Routes.py
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Feature: Forgot Password link in signin modal. Popup for Email Input. Konto deletion reactivation.

* Feature: Email and Password change popup width changed

* Feature: Fix problem with refresh token and include show Password

* Feature: forgot password functionality works with redirection to homepage

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Fix: Copilot review suggestion

* fix: make password visibility toggle keyboard focusable

Agent-Logs-Url: https://github.com/GalacticCodeGambit/LazyCook/sessions/bf26f4ce-caa3-43fa-b940-13d7be23d7bf

Co-authored-by: EdenBernhard <105359952+EdenBernhard@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
EdenBernhard and others added 16 commits May 10, 2026 17:01
# Conflicts:
#	project/backend/Routes.py
#	project/frontend/app/components/fields.tsx
#	project/frontend/app/homepage/forgotPassword.tsx
#	project/frontend/app/profile/changePasswordPopup.tsx
#	project/frontend/app/profile/page.tsx
#	project/frontend/lib/auth.tsx
* Feature: Forgot Password link in signin modal. Popup for Email Input. Konto deletion reactivation.

* Feature: Email and Password change popup width changed

* Feature: Fix problem with refresh token and include show Password

* Feature: forgot password functionality works with redirection to homepage

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Fix: Copilot review suggestion

* Fix: Copilot review suggestion

* Fix: Copilot review suggestion

* Fix: Copilot review suggestion

* Feat: Ingredients suggestions. Top 5 most typed shown in popup

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Feat: Ingredients suggestions. Top 5 most typed shown in popup

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Removed participant names from the review protocol.
* Datenschutz und Impressum MD's hinzugefügt und calls angepasst.

* Datenschutz und Impressum MD's hinzugefügt und calls angepasst. (Kommentar war invalide)

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Update navigation comments for Datenschutz and Impressum links

* Fix Datenschutz and Impressum, Add Datenschutz and Impressum pages with navigation links

* Add MarkdownRenderer component for rendering Markdown content in Impressum and Datenschutz pages

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* refactor: extract shared markdown reader helper

Agent-Logs-Url: https://github.com/GalacticCodeGambit/LazyCook/sessions/9460d714-3139-45d5-b2e2-e6ee6e3d8563

Co-authored-by: GalacticCodeGambit <150372421+GalacticCodeGambit@users.noreply.github.com>

* Update Impressum.md

---------

Co-authored-by: F <150372421+GalacticCodeGambit@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 20, 2026 13:00
@GalacticCodeGambit GalacticCodeGambit merged commit 4b2f2a3 into main May 20, 2026
8 of 9 checks passed
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends LazyCook with (1) password reset (“Passwort vergessen” + Reset-Link per Mail + Reset-Page), (2) ingredient-usage tracking to show “Top 5” ingredient suggestions in the recipe finder popup, and (3) markdown-rendered legal pages (Impressum/Datenschutz). It also splits linting into a dedicated GitHub Actions workflow and refactors parts of the frontend auth/profile UI.

Changes:

  • Added forgot/reset-password flow end-to-end (backend routes + email template + frontend pages/modals).
  • Added ingredient usage tracking + “Top ingredients” API and frontend suggestion badges with localStorage caching.
  • Added markdown rendering utilities and pages for Impressum/Datenschutz; added separate lint workflow and README updates.

Reviewed changes

Copilot reviewed 37 out of 38 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
README.md Adds setup/lint docs and badges; installation instructions updated.
project/frontend/package.json Adds react-markdown + remark-gfm dependencies for markdown pages.
project/frontend/lib/auth.tsx Makes API base URL configurable; adjusts token handling and authenticated fetch logic.
project/frontend/app/reset-password/page.tsx New reset-password page consuming the token query param and calling backend reset endpoint.
project/frontend/app/recipeFinder/style.css Adds styling for ingredient suggestion badges and stacked popup fields.
project/frontend/app/recipeFinder/popup.tsx Adds “Top 5” ingredient suggestion badge UI and focus handling.
project/frontend/app/recipeFinder/page.tsx Loads/caches suggestions, updates them after search, and passes them into the popup.
project/frontend/app/profile/page.tsx Refactors profile settings to use reusable modal components for email/password change and deletion confirm.
project/frontend/app/profile/changePasswordPopup.tsx New change-password popup component (used from profile).
project/frontend/app/profile/changeEmailPopup.tsx New change-email popup component (used from profile).
project/frontend/app/lib/read-markdown.ts Server-side helper to read markdown files from the homepage markdown directory.
project/frontend/app/layout.tsx Fixes global stylesheet import name.
project/frontend/app/impressum/page.tsx New Impressum page rendering existing markdown via renderer.
project/frontend/app/homepage/signin.tsx Adds “Passwort vergessen?” entry point and improves error classification.
project/frontend/app/homepage/MarkdownFiles/Impressum.md Adds Impressum markdown content.
project/frontend/app/homepage/MarkdownFiles/Datenschutz.md Adds Datenschutzerklärung markdown content.
project/frontend/app/homepage/homepage.tsx Adds navbar links to legal pages and a “forgot password” modal state.
project/frontend/app/homepage/forgotPassword.tsx New forgot-password modal form calling backend request endpoint.
project/frontend/app/globals.css Fixes a CSS variable typo (10 px10px).
project/frontend/app/datenschutz/page.tsx New Datenschutz page rendering existing markdown via renderer.
project/frontend/app/components/markdown-renderer.tsx New markdown renderer component using react-markdown + GFM.
project/frontend/app/components/fields.tsx Enhances Field component with password show/hide toggle.
project/Dockerfile-frontend Pins Node image tag more specifically.
project/compose.yaml Adds FRONTEND_URL env var for backend to build reset links / CORS origin.
project/backend/SearchRecipeNames.py Adds helper to find recipes by name substring.
project/backend/Routes.py Adds forgot/reset-password endpoints; adds recipes search usage tracking + top ingredients endpoints; adjusts refresh account mapping.
project/backend/RecipeSUCUK.py Adds/updates recipe search algorithm draft (SUCUK).
project/backend/Recipe.py Refactors recipe model, persistence helpers, and matching/rating helpers.
project/backend/Models.py Extends Token model + adds request models for password reset and recipe search.
project/backend/LazyCookAdministration.py Makes CORS allowed origin configurable via FRONTEND_URL.
project/backend/Ingridient.py Removes old misspelled Ingredient class file.
project/backend/Ingredient.py Adds new Ingredient class file.
project/backend/EmailService.py Adds password-reset email sending helper.
project/backend/Database.py Enables WAL; renames Ingredient table; adds IngredientUsage + PasswordResetToken tables and new helper queries.
project/backend/Auth.py Adds password reset token generation/validation.
docs/Review-Protokoll-01.md Adds a review protocol document.
.github/workflows/lint.yml Introduces dedicated lint workflow using GitHub Super-Linter.
.github/workflows/ci.yml Removes linter job from CI workflow (now in lint.yml).
Comments suppressed due to low confidence (4)

project/backend/Database.py:281

  • getIngridientByName ist aktuell kaputt: es selektiert aus Recipe und vergleicht id = ?, obwohl der Parameter name heißt. Außerdem wird (name) statt (name,) übergeben. Das führt dazu, dass Ingredient-Lookups fehlschlagen. Bitte auf SELECT id, amountType FROM Ingredient WHERE name = ? umstellen und korrektes Tuple verwenden.
def getIngridientByName(name: str):
    with getDB() as con:
        cur = con.cursor()
        cur.execute(
            """
                    SELECT id, amountType
                    FROM Recipe
                    WHERE id = ?
                    """,
            (name),
        )
        row = cur.fetchone()
        return dict(row) if row else None

project/backend/Database.py:345

  • Die SQL in getAllocatedRecipes ist syntaktisch/inhaltlich fehlerhaft (Komma nach JOIN, Where nach Komma, Join-Bedingung rid=id ist unklar, Exists_from.id scheint nicht zu existieren). Bitte Query korrigieren oder die Funktion entfernen, falls ungenutzt.
def getAllocatedRecipes(name: str) -> list[dict]:

    with getDB() as con:
        cur = con.cursor()
        cur.execute(
            """
                    SELECT rid 
                    FROM Exists_from
                    Inner Join Ingredient on rid=id,
                    Where Exists_from.id = ?
                    """,
            (name,),
        )
        rows = cur.fetchall()
        return [dict(row) for row in rows]

project/backend/Recipe.py:66

  • Die Methode heißt getingredients, aber der SUCUK-Algorithmus nutzt getIngredients() / recipe.getIngredients(). Dadurch gibt es zur Laufzeit einen AttributeError. Bitte die Methode konsistent benennen (und ggf. alle Call-Sites anpassen).
    def getingredients(self) -> list[Ingredient]:
        return self.__ingredients

    def setIngredient(self, ingredients: list[Ingredient]):
        self.__ingredients = ingredients

project/backend/Database.py:69

  • Schema-Änderung: initDB() erstellt jetzt eine Tabelle Ingredient (statt zuvor Ingridient). Da die DB in project/data persistiert wird, bleibt eine bestehende alte Tabelle unverändert bestehen (keine Migration) und Queries, die Ingredient erwarten, können auf älteren Datenbanken fehlschlagen. Bitte Migration/Kompatibilität (Rename/Copy) vorsehen oder wenigstens beim Startup prüfen und eine klare Fehlermeldung geben.
        cur.execute("""
                    CREATE TABLE IF NOT EXISTS Ingredient (
                                                         id INTEGER PRIMARY KEY AUTOINCREMENT,
                                                         name TEXT UNIQUE NOT NULL,
                                                         amountType VARCHAR(30) NOT NULL
                        )
                    """)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread README.md
1. Klonen das Repository:
`git clone https://github.com/GalacticCodeGambit/LazyCook.git`
2. Navigieren zum Projektverzeichnis:
`cd LazyCook/Project`
Comment thread README.md

Für die Funktion [#115](https://github.com/GalacticCodeGambit/LazyCook/issues/115) von Email Versenden/Empfangen muss im Ordner `project/` eine `.env` Datei mit den folgenden Variablen angelegt werden:
```
EMAIL_HOST=<dein.mail@gmail.com>
Comment on lines 111 to +139
@@ -118,23 +121,22 @@ async function fetchWithAuth(url: string, options: RequestInit = {}): Promise<Re
const refreshToken = getRefreshToken();
if (!refreshToken) throw new Error("Nicht eingeloggt");

let tokens;
try {
const tokens = await apiRefreshTokens(refreshToken);
saveTokens(tokens.access_token, tokens.refresh_token);

// Erneuter Versuch mit neuem Access Token
res = await fetch(API_URL+url, {
...options,
headers: {
...options.headers,
Authorization: `Bearer ${tokens.access_token}`,
},
});
tokens = await apiRefreshTokens(refreshToken);
} catch {
// Refresh fehlgeschlagen → komplett ausloggen
clearTokens();
throw new Error("Session abgelaufen");
}
saveTokens(tokens.access_token, tokens.refresh_token);

res = await fetch(url, {
...options,
headers: {
...options.headers,
Authorization: `Bearer ${tokens.access_token}`,
},
});
Comment on lines +77 to +114
def sendPasswordResetEmail(to_email: str, name: str, resetLink: str) -> None:
try:
msg = MIMEMultipart("alternative")
msg["Subject"] = "Passwort zurücksetzen – Lazy Cook"
msg["From"] = gmailUser
msg["To"] = to_email

html = f"""
<div style="font-family: sans-serif; max-width: 500px; margin: auto;">
<h2>Hallo {name},</h2>
<p>du hast angefordert, dein Passwort bei <strong>Lazy Cook</strong> zurückzusetzen.</p>
<p>Klicke auf den Button, um ein neues Passwort festzulegen:</p>
<p style="text-align:center; margin: 24px 0;">
<a href="{resetLink}"
style="background:#030213; color:#fff; padding:12px 24px;
text-decoration:none; border-radius:6px; display:inline-block;">
Passwort zurücksetzen
</a>
</p>
<p style="font-size:12px; color:#666;">
Oder kopiere diesen Link in deinen Browser:<br>
<a href="{resetLink}">{resetLink}</a>
</p>
<p>Der Link ist <strong>30 Minuten</strong> gültig.</p>
<p>Falls du das nicht angefordert hast, ignoriere diese E-Mail einfach – dein Passwort bleibt unverändert.</p>
<br>
<p>– Das Lazy Cook Team</p>
</div>
"""
msg.attach(MIMEText(html, "html"))

with smtplib.SMTP_SSL("smtp.gmail.com", 465) as server:
server.login(gmailUser, gmailPassword)
server.sendmail(gmailUser, to_email, msg.as_string())

except Exception as e:
print(f"E-Mail Fehler: {e}")
raise
Comment thread project/backend/Auth.py
Comment on lines +19 to 22
import hashlib

PASSWORD_RESET_EXPIRE_MINUTES = 30

Comment thread project/backend/Recipe.py
Comment on lines +20 to +23
if not zid:
return False
else:
addIngredientToRecipe(zid, rid, ingridient.getAmount())
Comment on lines +22 to +28
def __filterRecipes(recipes: list[Recipe], Ingredient: Ingredient) -> list[Recipe]:
for recipe in recipes:
for recipeIngredient in recipe.getIngredients():
if recipeIngredient.getName() == Ingredient.getName():
recipe.incrementMatching()
recipe.setRating(recipe.getMatching() / len(recipe.getIngredients()))
return recipes
Comment on lines +52 to +62
ini = []
ini.append(Ingredient("Linguine", 10))
ini.append(Ingredient("Fresh Basil", 10))
ini.append(Ingredient("Pine Nuts", 10))
ini.append(Ingredient("Parmesan", 10))
ini.append(Ingredient("Ground Beef", 10))
ini.append(Ingredient("Cumin", 10))
ini.append(Ingredient("Cucumber", 10))
arr = findRecipes(ini)
for i in arr:
print(i.getName() + " " + str(i.getRating()))
Comment on lines +5 to +31
class Ingredient:
def __init__(self, name: str, amount: float):
self.__name = name
self.__amount = amount

def getName(self) -> str:
return self.__name

def setName(self, name: str):
self.__name = name

def getAmount(self) -> float:
return self.__amount

def setAmount(self, amount: float):
self.__amount = amount

def setAmountType(self, amountType: str):
self.__amountType = amountType

def getAmountType(self):
return self.__amountType

def saveInDB(self):
if not self.__amountType:
return False
else:
Comment on lines +95 to +111
try {
const endpoint = isForgot
? `${API_URL}/users/forgot-password`
: `${API_URL}/users/me`;

const body = isForgot
? { newPassword }
: { currentPassword, newPassword };

const fetcher = isForgot ? fetch : fetchWithAuth;

const res = await fetcher(endpoint, {
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants