← All projects

E-Commerce API

A marketplace REST API with refresh token rotation, race-free stock reservation, RFC 7807 errors and integration tests on real PostgreSQL, plus a React 19 front end.

Personal projectFull-stack developer2026
.NET 10ASP.NET CoreEF CorePostgreSQLJWTTestcontainersDockerReact 19TypeScriptGitHub Actions
View source on GitHub

A marketplace where users list products and buy from each other. The feature set is intentionally small; the point of the project is the parts that usually break in real systems: token security, overselling under concurrency, consistent error contracts and tests that run against a real database.

Architecture

The backend follows Clean Architecture with five projects:

ProjectResponsibility
DomainEntities with behaviour, repository and unit-of-work contracts, no framework dependencies
ApplicationUse cases, DTOs with validation, typed exceptions, settings
InfrastructureEF Core, repositories, JWT, BCrypt, migrations, seeding
ApiControllers, authentication, exception handling, rate limiting, health checks

The front end is React 19 with TypeScript, Vite, TanStack Query and Tailwind CSS.

Refresh token rotation with reuse detection

Access tokens live for 15 minutes. Refresh tokens are single-use and stored only as SHA-256 hashes, so a database leak does not hand out usable tokens.

If a refresh token that has already been used shows up again, it has almost certainly been stolen. The API then revokes every session for that user, and a small middleware rejects access tokens tied to a revoked session even before they expire. Logout uses the same mechanism, so it takes effect immediately instead of "whenever the JWT expires".

Never oversell

Checking stock and then saving an order is a classic race condition: two buyers can both see "1 left". Instead, stock is reserved with a single conditional update inside the same transaction as the order insert:

UPDATE "Products"
SET "Quantity" = "Quantity" - @qty
WHERE "Id" = @id AND "DeletedAt" IS NULL AND "Quantity" >= @qty;

If no row is updated, the order is rejected; if the insert fails, the transaction rolls the reservation back. An integration test fires eight concurrent orders at three units of stock and asserts that exactly three succeed and the stock ends at zero.

One error contract

Every failure is returned as RFC 7807 application/problem+json, mapped centrally from typed application exceptions (400, 401, 403, 404, 409). Controllers have no try/catch, and the React client reads the same detail and errors fields everywhere.

Testing and CI

  • Unit tests cover login and registration rules, token rotation and reuse detection, order placement and rollback, ownership checks and domain invariants.
  • Integration tests run the real API, middleware and EF Core migrations against PostgreSQL in Testcontainers: the full auth flow, replay attacks, 403/409 responses, search and the concurrency test above.
  • GitHub Actions builds the backend with warnings as errors, checks formatting, runs both test suites, lints and builds the front end and builds the Docker image.

What I would add next

  • A background job to purge used and expired refresh tokens.
  • A cart with multiple order lines and order status transitions through the API.

© 2026. All rights reserved.