Seitenzustand in die Adresszeile

Neu web/src/urlState.js mit useUrlWert/useUrlZahl/useUrlWerte. Zwei
Regeln stecken darin, beide damit die Adresszeile brauchbar bleibt:
geschrieben wird immer mit replace - sonst legt jeder Tastendruck in
einem Suchfeld einen Verlaufseintrag an und die Zurueck-Taste braeuchte
zwanzig Versuche, um die Seite zu verlassen -, und Vorgabewerte fliegen
aus der URL, sonst sammelt sich "?typ=&q=&kat=" an.

useUrlWerte gibt es, weil zwei getrennte Schreibvorgaenge im selben
Durchlauf einander ueberschreiben: Beide bekommen denselben
Ausgangsstand. Wo ein Klick zwei Dinge aendert ("Kategorie 12, Karte
Masse"), muss es ein Aufruf sein.

Damit wandern in die URL:

- Rezepte: Das Rezept steht jetzt im PFAD (/rezepte/<slug>), weil es
  benennt, was man ansieht - so wie /products/:id und /i/:uid. Portionen
  und Suchbegriff als Parameter. "Pfannkuchen fuer 12" ist damit ein
  verschickbarer Link.
- Kategorien: Segment-Umschalter und die geoeffnete Seitenkarte
  (?typ=food&kat=6&panel=masse). Gespeichert wird die Kennung, nicht das
  Objekt - die Kategorien kommen erst vom Server.
- Gruppen: die geoeffnete Seitenkarte.
- Artikel: der Segment-Umschalter.
- Ein- und Auslagern: der gewaehlte Artikel als Kennung, nachgeladen beim
  Aufruf. Eine halbfertige Buchung ueberlebt damit ein Neuladen.

Die Portionszahl landet NUR in der URL, wenn jemand sie selbst gestellt
hat. Die Vorbelegung aus dem Rezept bleibt draussen - sonst traegt jedes
geoeffnete Rezept ein ?portionen mit sich herum, das gar keine
Entscheidung ist.

Dazu im Backend: Ein unbekanntes Rezept ist jetzt 404 statt 502 und sagt
"Dieses Rezept gibt es in Mealie nicht (mehr)" statt "Mealie kennt
/api/recipes/x nicht". Das wurde noetig, weil ein Rezept seit diesem
Commit verlinkbar ist und ein alter Link irgendwann ins Leere zeigt -
eine gewoehnliche Auskunft, kein Gateway-Fehler.

Von Hand durchgeklickt: Rezept oeffnen und Portionen auf 12 ->
/rezepte/pfannkuchen?portionen=12, Neuladen bringt 250 g -> 750 g zurueck;
unbekannter Slug zeigt den klaren Hinweis und laesst die Liste stehen;
Kategorie-Karte und Segment ueberstehen F5, Schliessen raeumt die URL;
/checkin?artikel=1 laedt den Artikel nach, ?artikel=999 raeumt die
Adresse und zeigt die Suchmaske. 1 neuer Test, Suite bei 518.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-10-02 16:13:37 +02:00
co-authored by Claude Opus 5
parent a1b10d9ec3
commit 18481bbca0
10 changed files with 270 additions and 28 deletions
+22
View File
@@ -18,6 +18,7 @@ from app.routers.mealie import (
mealie_token_setzen,
mealie_trennen,
)
from app.routers.recipes import get_recipe
from app.routers.settings import list_settings
from app.schemas import MealieConfigIn, MealieTokenIn
from app.services import mealie
@@ -301,3 +302,24 @@ def test_pfadvariante_wird_gepuffert(db, admin):
mealie.pfadvariante(db)
assert len(gesehen) == anzahl # keine zweite Anfrage
def test_unbekanntes_rezept_ist_ein_404_mit_klarem_text(db, admin):
"""Seit das Rezept im Pfad steht, kann ein Link ins Leere zeigen.
Das ist eine gewoehnliche Auskunft und kein Gateway-Fehler - und der Text
landet in der Oberflaeche, darf also nicht nach Innenleben klingen.
"""
db.add(Setting(key="mealie_base_url", value="https://m.example.com"))
db.add(IntegrationSecret(service="mealie", secret="t"))
db.commit()
mealie.setze_transport(httpx.MockTransport(
lambda request: httpx.Response(404, json={"detail": "Not found"}),
))
with pytest.raises(HTTPException) as fehler:
get_recipe("gibtsnicht", db=db, _=admin)
assert fehler.value.status_code == 404
assert "Rezept" in str(fehler.value.detail)
assert "/api/" not in str(fehler.value.detail)