feat(shopping): finalize GET /v1/shopping-list endpoint and regenerate OpenAPI types
Renamed endpoint to /v1/shopping-list to avoid Springdoc path conflict.
Added @RequiresHouseholdRole("planner") on generate. Regenerated
frontend OpenAPI schema with all new shopping list endpoints.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -22,7 +22,7 @@ public class ShoppingListController {
|
||||
this.householdResolver = householdResolver;
|
||||
}
|
||||
|
||||
@GetMapping("/v1/shopping-lists")
|
||||
@GetMapping("/v1/shopping-list")
|
||||
public ShoppingListResponse getByWeekStart(
|
||||
@RequestParam(required = false) LocalDate weekStart,
|
||||
Principal principal) {
|
||||
|
||||
4
backend/src/main/resources/application-docker.yml
Normal file
4
backend/src/main/resources/application-docker.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
spring:
|
||||
flyway:
|
||||
locations: classpath:db/migration,classpath:db/seed
|
||||
out-of-order: true
|
||||
@@ -1,2 +1,2 @@
|
||||
ALTER TABLE shopping_list
|
||||
ADD COLUMN generated_at timestamptz NOT NULL DEFAULT now();
|
||||
ADD COLUMN IF NOT EXISTS generated_at timestamptz NOT NULL DEFAULT now();
|
||||
|
||||
@@ -56,7 +56,7 @@ class ShoppingListControllerTest {
|
||||
when(householdResolver.resolve("sarah@example.com")).thenReturn(HOUSEHOLD_ID);
|
||||
when(shoppingService.getByWeekStart(eq(HOUSEHOLD_ID), any())).thenReturn(response);
|
||||
|
||||
mockMvc.perform(get("/v1/shopping-lists")
|
||||
mockMvc.perform(get("/v1/shopping-list")
|
||||
.param("weekStart", "2026-04-06")
|
||||
.principal(() -> "sarah@example.com"))
|
||||
.andExpect(status().isOk())
|
||||
@@ -69,7 +69,7 @@ class ShoppingListControllerTest {
|
||||
when(householdResolver.resolve("sarah@example.com")).thenReturn(HOUSEHOLD_ID);
|
||||
when(shoppingService.getByWeekStart(eq(HOUSEHOLD_ID), any())).thenReturn(null);
|
||||
|
||||
mockMvc.perform(get("/v1/shopping-lists")
|
||||
mockMvc.perform(get("/v1/shopping-list")
|
||||
.param("weekStart", "2026-04-06")
|
||||
.principal(() -> "sarah@example.com"))
|
||||
.andExpect(status().isNotFound());
|
||||
|
||||
File diff suppressed because one or more lines are too long
49
frontend/src/lib/api/schema.d.ts
vendored
49
frontend/src/lib/api/schema.d.ts
vendored
@@ -452,6 +452,22 @@ export interface paths {
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/v1/shopping-list": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get: operations["getByWeekStart"];
|
||||
put?: never;
|
||||
post?: never;
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/v1/ingredients": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
@@ -624,6 +640,11 @@ export interface components {
|
||||
/** Format: uuid */
|
||||
recipeId: string;
|
||||
};
|
||||
RecipeRef: {
|
||||
/** Format: uuid */
|
||||
id?: string;
|
||||
name?: string;
|
||||
};
|
||||
ShoppingListItemResponse: {
|
||||
/** Format: uuid */
|
||||
id?: string;
|
||||
@@ -636,13 +657,17 @@ export interface components {
|
||||
isChecked?: boolean;
|
||||
/** Format: uuid */
|
||||
checkedBy?: string;
|
||||
sourceRecipes?: string[];
|
||||
sourceRecipes?: components["schemas"]["RecipeRef"][];
|
||||
};
|
||||
ShoppingListResponse: {
|
||||
/** Format: uuid */
|
||||
id?: string;
|
||||
/** Format: uuid */
|
||||
weekPlanId?: string;
|
||||
/** Format: date-time */
|
||||
generatedAt?: string;
|
||||
/** Format: int32 */
|
||||
filteredStaplesCount?: number;
|
||||
items?: components["schemas"]["ShoppingListItemResponse"][];
|
||||
};
|
||||
TagCreateRequest: {
|
||||
@@ -1902,6 +1927,28 @@ export interface operations {
|
||||
};
|
||||
};
|
||||
};
|
||||
getByWeekStart: {
|
||||
parameters: {
|
||||
query?: {
|
||||
weekStart?: string;
|
||||
};
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
/** @description OK */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"*/*": components["schemas"]["ShoppingListResponse"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
searchIngredients: {
|
||||
parameters: {
|
||||
query?: {
|
||||
|
||||
Reference in New Issue
Block a user