Skip to content

Implement UUIDv7 recipe ids and soft delete - #1277

Merged
dgee2 merged 7 commits into
mainfrom
codex/1215-1216-uuidv7-soft-delete
Sep 8, 2026
Merged

dgee2 merged 7 commits into
mainfrom
codex/1215-1216-uuidv7-soft-delete

Conversation

@dgee2

@dgee2 dgee2 commented Sep 6, 2026

Copy link
Copy Markdown
Owner

Summary

Implements UUIDv7 entity identifiers and soft deletion for recipes in one coordinated change.

Closes #1215
Closes #1216

Changes

  • Converts recipe, recipe ingredient, recipe step, and menu user primary keys and foreign keys to application-generated UUIDv7 values.
  • Adds DeletedAtUtc, a global active-recipe query filter, filtered title uniqueness, and owner-only restore at POST /api/recipe/{recipeId}/restore.
  • Preserves ingredients and steps during soft deletion and adds frontend delete/Undo notifications with query invalidation.
  • Adds a guarded empty-schema migration because converting populated integer key tables would otherwise risk data loss.
  • Documents the current never-purge retention policy.

Verification

  • dotnet build MenuApi.sln --configuration Release --no-restore — passed, 0 warnings/errors.
  • dotnet test MenuApi.Tests --configuration Release --no-restore — 154 passed.
  • dotnet test MenuDB.Tests --configuration Release --no-restore — 16 passed.
  • pnpm test:unit — 156 passed.
  • pnpm test:storybook — 93 passed.
  • pnpm build — passed.
  • pnpm lint — passed with 0 errors and 19 existing warnings.
  • Full Aspire integration execution is blocked in this environment because the Docker runtime is unhealthy; the integration test project builds successfully.

Comment thread backend/MenuApi.Tests/Services/RecipeServiceTests.cs Fixed
@dgee2

dgee2 commented Sep 8, 2026

Copy link
Copy Markdown
Owner Author

🤖 This comment was written by Codex.

Addressed in commit 3467b13c. I consolidated the repeated media type, access-scope, and recipe endpoint literals in the new integration test, and renamed the restore catch parameter to satisfy the analyzer guidance. The quality gate should rerun on this commit. The separate backend integration failure was caused by a Redis health-check connection failure after 50 tests had passed, so I am leaving the test behavior unchanged and will verify the rerun.

dgee2 and others added 6 commits September 8, 2026 13:20
Closes #1215
Closes #1216

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
@dgee2
dgee2 force-pushed the codex/1215-1216-uuidv7-soft-delete branch from f8d072c to d9a78bf Compare September 8, 2026 12:20
@dgee2
dgee2 marked this pull request as ready for review September 8, 2026 20:35
Copilot AI lite review requested due to automatic review settings September 8, 2026 20:35

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The UUIDv7 + soft-delete implementation is cohesive across layers and is backed by updated unit/integration/frontend tests, with only a minor test-serialization consistency nit noted.

Pull request overview

This PR implements application-generated UUIDv7 identifiers for recipe-related entities and Menu users, and switches recipe deletion to a soft-delete model with an owner-only restore endpoint. It reshapes the EF Core schema (including a filtered uniqueness index for titles) and wires the new restore/undo flow through the backend API, repositories/services, integration/unit tests, and the Vue/Quasar frontend.

Changes:

  • Convert Recipe, RecipeIngredient, RecipeStep, and MenuUser identifiers (PKs/FKs) from int identity to UUIDv7 Guid, with ValueGeneratedNever() and app-side ID generation.
  • Add recipe soft delete via DeletedAtUtc, a global EF query filter, a filtered unique index for (OwnerUserId, Title), and POST /api/recipe/{recipeId}/restore.
  • Update frontend delete UX to show a Quasar Notify “Undo” action that calls restore and invalidates recipe queries; update backend + frontend tests accordingly.
File summaries
File Description
ui/menu-website/src/services/recipe-service.ts Adds restore mutation hook and updates cache invalidation to use UUID ids.
ui/menu-website/src/services/recipe-api.ts Adds typed API call for POST /api/recipe/{recipeId}/restore.
ui/menu-website/src/pages/RecipeList.test.ts Updates recipe-api mock to include restoreRecipe.
ui/menu-website/src/pages/RecipeDetail.vue Adds Quasar Notify delete/undo flow and restore handler.
ui/menu-website/src/pages/RecipeDetail.test.ts Registers Quasar Notify plugin in tests and adds undo test coverage.
ui/menu-website/src/pages/EditRecipe.test.ts Updates recipe-api mock to include restoreRecipe.
ui/menu-website/src/main.ts Registers Quasar Notify plugin for app-wide notifications.
ui/menu-website/src/components/organisms/recipe/recipe-form.test.ts Updates recipe-api mock to include restoreRecipe.
docs/specs/recipe-soft-delete.md Documents current “never purge” retention policy for soft-deleted recipes.
backend/MenuDB/Migrations/MenuDbContextModelSnapshot.cs Updates snapshot for UUID keys, DeletedAtUtc, filtered index, and query filter.
backend/MenuDB/Migrations/20260906190329_ConvertRecipeEntityIdsToUuidV7AndSoftDelete.Designer.cs Adds migration designer model reflecting UUID keys + soft delete changes.
backend/MenuDB/Migrations/20260906190329_ConvertRecipeEntityIdsToUuidV7AndSoftDelete.cs Adds guarded migration that drops/recreates empty entity tables with UUID keys + soft delete.
backend/MenuDB/Data/RecipeStepEntity.cs Switches step PK/FK types to Guid.
backend/MenuDB/Data/RecipeIngredientEntity.cs Switches ingredient PK/FK types to Guid.
backend/MenuDB/Data/RecipeEntity.cs Switches recipe PK/FK types to Guid and adds DeletedAtUtc.
backend/MenuDB/Data/MenuUserEntity.cs Switches menu user PK type to Guid.
backend/MenuDB/Configuration/RecipeStepEntityConfiguration.cs Changes step key generation to application-generated (ValueGeneratedNever).
backend/MenuDB/Configuration/RecipeIngredientEntityConfiguration.cs Changes ingredient key generation to application-generated (ValueGeneratedNever).
backend/MenuDB/Configuration/RecipeEntityConfiguration.cs Changes recipe key generation + adds query filter + filtered uniqueness index.
backend/MenuDB/Configuration/MenuUserEntityConfiguration.cs Changes menu user key generation to application-generated (ValueGeneratedNever).
backend/MenuDB.Tests/RecipeStepEntityConfigurationTests.cs Adds test asserting step key is Guid and not store-generated.
backend/MenuDB.Tests/RecipeIngredientEntityConfigurationTests.cs Adds tests for ingredient key types and key generation.
backend/MenuDB.Tests/RecipeEntityConfigurationTests.cs Adds tests for recipe key generation, query filter, and filtered index.
backend/MenuDB.Tests/MenuUserEntityConfigurationTests.cs Adds test asserting menu user key is Guid and not store-generated.
backend/MenuApi/ValueObjects/Recipe.cs Updates RecipeId Vogen type to wrap Guid.
backend/MenuApi/ValueObjects/MenuUserId.cs Updates MenuUserId Vogen type to wrap Guid.
backend/MenuApi/Services/RecipeService.cs Adds service method to restore a recipe (owner-checked).
backend/MenuApi/Services/IRecipeService.cs Adds RestoreRecipeAsync to the service contract.
backend/MenuApi/Repositories/RecipeStepRepository.cs Generates UUIDv7 step ids on upsert.
backend/MenuApi/Repositories/RecipeRepository.cs Generates UUIDv7 recipe/ingredient ids; implements soft delete + restore + include-deleted read.
backend/MenuApi/Repositories/MenuUserRepository.cs Generates UUIDv7 menu user ids on insert.
backend/MenuApi/Repositories/IRecipeRepository.cs Adds restore and include-deleted repository APIs.
backend/MenuApi/Recipes/RecipeApi.cs Adds POST {recipeId}/restore endpoint and response metadata.
backend/MenuApi.Tests/Services/RecipeServiceTests.cs Adds unit tests for restore behavior (success/not found/forbidden).
backend/MenuApi.Tests/Services/MenuUserServiceTests.cs Updates tests to use Guid-based MenuUserId.
backend/MenuApi.Tests/Repositories/RecipeRepositoryTests.cs Adds tests for UUIDv7 generation and query filter behavior; updates Guid-based ids.
backend/MenuApi.Tests/Controllers/RecipeApiTests.cs Adds controller tests for restore endpoint and updates Guid-based ids.
backend/MenuApi.Integration.Tests/ValidationIntegrationTests.cs Updates validation tests to use GUID ids in routes and JSON parsing.
backend/MenuApi.Integration.Tests/UserProvisioningIntegrationTests.cs Updates user id expectations and response model to Guid.
backend/MenuApi.Integration.Tests/RecipeWithIngredientsIntegrationTests.cs Updates recipe id handling from int to Guid.
backend/MenuApi.Integration.Tests/RecipeReadAuthorizationIntegrationTests.cs Updates recipe id handling from int to Guid.
backend/MenuApi.Integration.Tests/RecipeIntegrationTests.cs Updates recipe id handling and list DTO id type to Guid.
backend/MenuApi.Integration.Tests/RecipeDeleteIntegrationTests.cs Updates delete tests for soft-delete semantics and adds restore/duplicate-title scenarios.
backend/MenuApi.Integration.Tests/RecipeCreateUpdateIntegrationTests.cs Updates recipe id parsing and not-found route to GUID.
backend/MenuApi.Integration.Tests/Factory/TestDatabaseSeeder.cs Updates seeded ids to UUIDv7 and adds helpers for counts + soft delete.
.sonarcloud.properties Excludes EF migration scaffolding from SonarCloud CPD duplication checks.
Review details

Files not reviewed (1)

  • backend/MenuDB/Migrations/20260906190329_ConvertRecipeEntityIdsToUuidV7AndSoftDelete.Designer.cs: Generated file
  • Files reviewed: 45/46 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread backend/MenuApi.Integration.Tests/RecipeDeleteIntegrationTests.cs Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d9a78bf58c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread ui/menu-website/src/pages/RecipeDetail.vue
Comment thread backend/MenuApi/Repositories/RecipeRepository.cs
Co-authored-by: Codex <codex@openai.com>
@sonarqubecloud

sonarqubecloud Bot commented Sep 8, 2026

Copy link
Copy Markdown

@dgee2
dgee2 enabled auto-merge (squash) September 8, 2026 20:58
@dgee2
dgee2 disabled auto-merge September 8, 2026 20:59
@dgee2
dgee2 merged commit daca768 into main Sep 8, 2026
19 checks passed
@dgee2
dgee2 deleted the codex/1215-1216-uuidv7-soft-delete branch September 8, 2026 20:59

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6e3b4fe6fa

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread ui/menu-website/playwright.config.ts
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.

Soft-delete recipes with an undo window Use client-generated UUIDv7 primary keys for entity tables

3 participants