Personal engineering portfolio
A commerce case study focused on interface behavior, product search, checkout flow, and defensible backend boundaries.
Stack: Java 21, Spring Boot, PostgreSQL + pgvector, Kafka, Next.js, React
I built this project to show how interface work, data flow, and backend boundaries fit together in a storefront. You can browse products, search in plain English, build a cart, and place an order through a checkout backed by a Stripe test-mode payment and one verified event boundary. Each boundary is a decision I can explain and defend.
System shape
Gateway + BFFs + domain services, with one defended async boundary
Design choices
A few choices that shaped the project
Next.js · React SPA
Two frontends, one API contract
The Next.js UI is the portfolio storefront with server-rendered architecture context; the React SPA is a separate browser-rendered storefront. Both use the same gateway routes for browse, search, cart, checkout, and SSE order progress — no SPA-only backend adapter.
Open the React SPA ↗LLM parsing · pgvector retrieval · grounded explanation
Search with one honest path
Search starts with plain English. An LLM extracts structured filters, pgvector retrieves catalog items, and Postgres reloads product-domain truth. A separate grounded call explains results it cannot add, remove, or re-rank. There is no hidden keyword fallback.
Stripe webhook · one Kafka event · SSE
Checkout with a defended async boundary
Place Order is a synchronous REST chain to a Stripe test-mode checkout boundary. Duplicate submits, lost payment responses, and webhook redelivery are handled with idempotency and locking, without turning checkout into a saga. Kafka appears only after the verified webhook.
Preview the checkout pipelineArchitecture preview
Representative checkout pipeline
Public preview of the same shape used after checkout: sync Place Order, Stripe test-mode PaymentIntent, verified webhook, one Kafka fact, durable order status, and SSE push.
Toggle diagram
Architecture preview
Representative checkout pipeline
Public preview of the same shape used after checkout: sync Place Order, Stripe test-mode PaymentIntent, verified webhook, one Kafka fact, durable order status, and SSE push.
Representative data only. This is not a scenario simulator: no saga, no outbox/inbox, no inventory reservation, and no broader Kafka topology are hidden behind the diagram.
Try the search
Search in plain English
Try something like "running shoes under $120". The search is designed to accept everyday language while still staying grounded in the catalog.
From the catalog
Featured products
These are live products from the backend, not static homepage fixtures.







