Skip to content

feat: validate basket products against Catalog — architecture impact demo - #6

Open
ivanmilevtues wants to merge 1 commit into
mainfrom
feat/basket-catalog-validation
Open

ivanmilevtues wants to merge 1 commit into
mainfrom
feat/basket-catalog-validation

Conversation

@ivanmilevtues

Copy link
Copy Markdown
Member

Architecture demo

Introduce a real new runtime dependency: Basket API → Catalog Service. Basket updates now check that each distinct product exists in Catalog before writing to Redis. This demonstrates an architectural change rather than a cosmetic code change.

Baseline and expected analysis

I inspected .codeboarding/analysis.json on the latest fork main before implementing this change. Its Basket API component (8) has no outgoing relation to Catalog Service (5), including their child components. The baseline is intentionally unchanged in this PR: the review must infer the new relationship from source.

Expected highlights:

  • Basket API: new outbound HTTP dependency and validation before persistence.
  • Catalog Service: newly consumed product lookup endpoint (its implementation is unchanged).
  • Application Host and Defaults: service discovery reference and startup dependency; Basket enables the existing outgoing HTTP defaults.

The architecture tradeoff is visible at a glance: nonempty basket writes now depend on Catalog availability. This is an expected review result, not a claim that the generated graph has already been verified.

Behavior

  • Queries GET /api/catalog/items/{id}?api-version=2.0 once per distinct product.
  • Missing or nonpositive product IDs return InvalidArgument without overwriting the basket.
  • HTTP/network failures and HTTP timeouts return Unavailable without overwriting the basket.
  • Empty baskets need no Catalog call. Existing read/delete paths are unchanged.
  • Validation checks existence, not stock reservation; checkout validation remains necessary.

Verification

  • All 14 Basket unit tests pass, including missing products after a successful lookup, upstream failures, duplicate IDs, empty baskets, and invalid IDs.
  • Command: dotnet test --project tests/Basket.UnitTests/Basket.UnitTests.csproj "-p:DefaultItemExcludes=**/obj/**" (excludes stale local obj files).
  • git diff --check passes.
  • Created directly from the latest fork main, independently of logging PR fix: report catalog embedding latency in milliseconds #5.

Leave open for the CodeBoarding architecture review demo.

Introduce a Basket API to Catalog Service dependency for architecture review.

Amp-Thread-ID: https://ampcode.com/threads/T-01a0d0bb-dbb1-77fc-9712-4aeb9f411d79
Co-authored-by: Amp <amp@ampcode.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-24T00:36:53.124323Z c068b52 PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@ivanmilevtues

Copy link
Copy Markdown
Member Author

Additional verification: AppHost builds successfully with dotnet build src/eShop.AppHost/eShop.AppHost.csproj "-p:DefaultItemExcludes=**/obj/**". Zero errors; one existing Aspire CLI bundle configuration warning (ASPIRE010).

@github-actions

github-actions Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

CodeBoarding review

Status: 1 changed component

See the full change in CodeBoarding.

graph LR
    n_Ordering["Ordering"]
    n_ClientApp["ClientApp"]
    n_Webhooks["Webhooks"]
    n_Identity["Identity"]
    n_WebApp["WebApp"]
    n_EventBus["EventBus"]
    n_js["js"]
    n_Loose_files_in_src_WebApp["Loose files in src.WebApp"]
    n_Ordering -- "calls" --> n_Webhooks
    n_Ordering -- "calls" --> n_EventBus
    n_ClientApp -- "calls" --> n_Webhooks
    n_Webhooks -- "calls" --> n_ClientApp
    n_WebApp -- "calls" --> n_Webhooks
    classDef added fill:#1f883d,stroke:#0b5d23,color:#ffffff;
    classDef modified fill:#bf8700,stroke:#7d4e00,color:#ffffff;
    classDef deleted fill:#cf222e,stroke:#82071e,color:#ffffff,stroke-dasharray:5 3;
    class n_Webhooks modified;
Loading

download artifacts · run 35938972530

@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: c068b520e5

ℹ️ 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 on lines +76 to +79
catch (OperationCanceledException) when (!context.CancellationToken.IsCancellationRequested)
{
throw new RpcException(new Status(StatusCode.Unavailable, "Catalog validation timed out. Please retry."));
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Catch resilience-pipeline timeout exceptions

When the outgoing Catalog request reaches the timeout configured by the newly enabled AddStandardResilienceHandler, Polly throws TimeoutRejectedException, which does not derive from OperationCanceledException. Consequently this catch is skipped and the gRPC call surfaces as an unhandled Unknown/Internal error rather than the promised retryable Unavailable status. Catch the resilience timeout exception explicitly while continuing to let caller-initiated cancellation propagate.

Useful? React with 👍 / 👎.

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.

1 participant