Skip to content

Work

Point-of-sale commerce platform — storefront, admin and API

A Swedish e-commerce platform for selling and configuring POS hardware and payment terminals: a Next.js storefront and admin UI over a Clean Architecture ASP.NET Core API, live on Azure.

Next.js 16 · React 19 · ASP.NET Core 10 · PostgreSQL · Stripe · Azure
Context
Swedish retailers buying a point-of-sale setup are not buying one product — they are configuring hardware bundles, payment terminals and recurring services that must fit together. This platform sells that, end to end.
Problem
POS commerce is not a flat catalogue: bundles, compatibility and subscriptions have to be configured correctly at purchase, and staff need to manage catalogue, orders, discounts, vendors and content without touching code.
Constraints
A Swedish-language market, card payments through a PSP, frontend and backend deployed independently to Azure App Service, and an API contract that must stay consumable by more than one client.
Role
Sole developer — storefront, admin, API and infrastructure, over 1,100 commits.
Architecture
A Next.js 16 frontend (storefront, admin dashboard and BFF route handlers) over an ASP.NET Core 10 Web API structured as a four-project Clean Architecture shell with vertical-slice endpoints; PostgreSQL via EF Core, Stripe payments, background jobs and transactional email; a code-generated typed API client keeps the contract in sync.
Key decisions
Vertical slices over layered controllers — each feature owns its endpoint, DTOs and service. A generated API client instead of a hand-written fetch layer, so backend/frontend drift fails at build time rather than in production. A deterministic seed catalogue so any environment boots realistic.
Outcome
Frontend and backend run on Azure App Service (both verified live 2026-07-15). An xUnit + Testcontainers integration suite and Playwright visual tests guard the release path. No sales metrics are published.
Evidence
Private repository; sole authorship verifiable from commit history. References available on request.
Confidentiality
Anonymised — the brand and its legal seller are not named here.