Skip to content

Feature/shopping list UI#65

Merged
JonathanPschl merged 10 commits into
mainfrom
feature/shopping-list-ui
Jun 15, 2026
Merged

Feature/shopping list UI#65
JonathanPschl merged 10 commits into
mainfrom
feature/shopping-list-ui

Conversation

@timn21

@timn21 timn21 commented Jun 14, 2026

Copy link
Copy Markdown
Collaborator

Shopping List & Recipes UI + per-user REST alignment

Adds the Recipes and Grocery Lists frontend, a full Recipes REST subsystem, and reworks
the existing grocery-list API.

Client

  • Recipes view (RecipeListView, new) — accordion of saved recipes, ingredients
    lazy-loaded on expand, copy & delete, loading/error/empty states.
  • Grocery Lists view (GroceryListView, new) — accordion with progress bar and
    per-item "picked up" checkboxes (persisted), copy & delete; collapsed cards show
    progress from summary counts, items load lazily on expand.
  • App.tsx — both views wired to the backend (load summaries, lazy detail, optimistic
    per-item PATCH toggle, delete); a generated dish is persisted as both a recipe and a
    grocery list.

Recipes: New REST subsystem (grocery-service)

  • Recipe entity + RecipeRepository, RecipeService, RecipeController.
  • GET/POST/PUT/DELETE /api/recipes (+ /{recipeId}), per-user via X-User-Id,
    summary-list + lazy detail. New DTOs (RecipeCreateRequest, RecipeDetailDTO,
    RecipeItemRequest/ResponseDTO, RecipeSummaryDTO).

Grocery-list: Reworked to match

  • Paths: /api/grocery-list/history/api/grocery-list, /history/{id}
    /{groceryListId}.
  • Identity: userId in the request body → X-User-Id header (set by the gateway);
    all operations are now per-user (ownership-scoped, 404 on not-owned) and return all of
    the caller's lists instead of the global top-20.
  • New endpoints: PUT /{groceryListId} (replace) and
    PATCH /{groceryListId}/items/{itemId} (toggle a single item's purchased).
  • Summaries now include itemCount/purchasedCount (single aggregate query) so the
    collapsed cards show progress without loading items; summary id field id
    groceryListId.
  • Quantity is nullable (Double); category parsing falls back to OTHER instead
    of throwing on unknown values.
  • Shared GroceryItem table for both subsystems via GroceryItemMapper + ItemRequest
    (validates name, normalizes unit, shared parseCategory); recipe/grocery
    controllers/services/DTOs aligned in structure.

Kubernetes

  • Helm: grocery-db/user-db added to Kubernetes deployment

@JonathanPschl JonathanPschl self-requested a review June 15, 2026 13:16

@JonathanPschl JonathanPschl left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Looks good! One thing to change maybe: I think we agreed that the GroceryLists will be generated by selecting Recipes from the RecipeList. Currently we immediately push a generated Recipe also as a GroceryList. I think we should have a quick call and discuss if we remove this until we implement #55 or if we merge it now and immediately finish and ship #55 asap.

This PR should also note that it closes:
#13
#15
#24
#53

@JonathanPschl JonathanPschl merged commit 7e7fe7b into main Jun 15, 2026
11 checks passed
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.

2 participants