Add recipe delete endpoint - #1199
Merged
Merged
Conversation
dgee2
force-pushed
the
issue-1117-recipe-delete
branch
from
August 2, 2026 21:54
0132c63 to
45c372c
Compare
dgee2
force-pushed
the
issue-1117-recipe-delete
branch
from
August 3, 2026 07:53
45c372c to
3c0f945
Compare
dgee2
force-pushed
the
issue-1117-recipe-delete
branch
from
August 3, 2026 08:04
3c0f945 to
2350e7f
Compare
dgee2
force-pushed
the
issue-1117-recipe-delete
branch
from
August 3, 2026 08:09
2350e7f to
492eb72
Compare
dgee2
force-pushed
the
issue-1117-recipe-delete
branch
from
August 3, 2026 20:05
492eb72 to
db3fe04
Compare
dgee2
marked this pull request as ready for review
August 4, 2026 06:45
Contributor
There was a problem hiding this comment.
Pull request overview
Adds an owner-authorized recipe deletion endpoint to MenuApi and aligns API error handling with RFC7807 Problem Details (including new 409/403 handlers). The PR also expands recipe create/update behavior to persist steps alongside ingredients, and updates unit/integration test coverage accordingly.
Changes:
- Add
DELETE /api/recipe/{recipeId}(owner-only) plus service/repository support usingExecuteDeleteAsync. - Add reusable
ProblemDetailsExceptionHandler<T>and newConflict(409) /Forbidden(403) exception handlers; update recipe duplicate-title behavior to return 409. - Update recipe create/update flow to upsert steps; adjust validation + unit/integration tests.
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| backend/MenuApi/Validation/UpsertRecipeValidator.cs | Allows empty ingredients while still rejecting null ingredients/steps. |
| backend/MenuApi/Services/RecipeService.cs | Adds owner checks; upserts steps on create/update; adds delete orchestration. |
| backend/MenuApi/Services/IRecipeService.cs | Updates update signature (returns bool, takes callerId) and adds delete. |
| backend/MenuApi/Repositories/RecipeRepository.cs | Adds EF-translatable projection expression; uses 409 on unique conflicts; adds ExecuteDeleteAsync delete. |
| backend/MenuApi/Repositories/IRecipeRepository.cs | Adds repository delete contract. |
| backend/MenuApi/Recipes/RecipeApi.cs | Wires PUT authorization/404 handling and adds DELETE endpoint + response contracts. |
| backend/MenuApi/Program.cs | Registers new exception handlers (409/403). |
| backend/MenuApi/Exceptions/ProblemDetailsExceptionHandler.cs | New shared RFC7807 exception handler base class. |
| backend/MenuApi/Exceptions/ForbiddenAccessExceptionHandler.cs | New 403 Problem Details exception handler. |
| backend/MenuApi/Exceptions/ForbiddenAccessException.cs | New exception type for forbidden recipe access. |
| backend/MenuApi/Exceptions/ConflictExceptionHandler.cs | New 409 Problem Details exception handler. |
| backend/MenuApi/Exceptions/ConflictException.cs | New exception type for conflicts (e.g., duplicate recipe title). |
| backend/MenuApi/Exceptions/BusinessValidationExceptionHandler.cs | Refactors 422 handler to use the shared base. |
| backend/MenuApi.Tests/Validation/UpsertRecipeValidatorTests.cs | Updates validator expectations: empty ingredients now pass, null fails. |
| backend/MenuApi.Tests/Services/RecipeServiceTests.cs | Adds owner/not-found cases; adds delete tests; asserts steps upsert calls. |
| backend/MenuApi.Tests/Controllers/RecipeApiTests.cs | Updates PUT tests for auth + result shapes; adds DELETE tests. |
| backend/MenuApi.Integration.Tests/RecipeIntegrationTests.cs | Updates duplicate-title expectations from 422 to 409. |
| backend/MenuApi.Integration.Tests/RecipeDeleteIntegrationTests.cs | New end-to-end tests for owner delete cascade, non-owner 403, missing 404. |
| backend/MenuApi.Integration.Tests/RecipeCreateUpdateIntegrationTests.cs | New end-to-end tests covering steps on create/update and owner/not-found cases. |
| backend/MenuApi.Integration.Tests/Factory/TestDatabaseSeeder.cs | Adds helper to count steps for cascade verification. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Owner-only delete: 404 if the recipe doesn't exist, 403 if the caller isn't the owner (reusing RecipeService's existing fetch-then-check pattern from #1116), otherwise deletes via a single ExecuteDeleteAsync statement. RecipeIngredient/RecipeStep rows cascade via the FK constraints already configured with DeleteBehavior.Cascade — no RecipeShare/RecipePublication/etc. tables exist yet (out of scope until Epic 6, per #1099's own scope note). Part of #1117.
Unit tests cover the API/service layers' 204/401/403/404 branches. Integration tests cover owner delete (verifying both RecipeIngredient and RecipeStep rows are actually gone, not just that the recipe 404s afterward), non-owner delete via TestDatabaseSeeder returning 403, and delete of a nonexistent recipe returning 404. Part of #1117.
dgee2
force-pushed
the
issue-1117-recipe-delete
branch
from
August 4, 2026 06:52
db3fe04 to
8be6ca3
Compare
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
DELETE /api/recipe/{recipeId}, owner-only: 404 if missing, 403 if the caller isn't the owner, otherwise deletes via a singleExecuteDeleteAsyncstatement.RecipeIngredient/RecipeSteprows cascade via the FK constraints already configured withDeleteBehavior.Cascadein Epic [Epic] Core recipe model changes (DB schema) #1098 — noRecipeShare/RecipePublication/etc. tables exist yet, consistent with epic [Epic] Recipe authoring API expansion #1099's own scope note that those are Epic 6 work.Closes #1117
Part of #1099
Test plan
dotnet test MenuApi.Tests(unit)dotnet test MenuApi.Integration.Tests— owner delete (verifying both ingredient and step rows are actually gone, not just that the recipe 404s afterward), non-owner 403, missing-recipe 404