Technical documentation

Fullstack Test Shop

Where things are in the code, how to run it and what was checked.
Version 767226bf3c2f · prepared on 7 September 2026

About the project

A double click or repeated webhook must not create another order or deliver another code. If the supplier does not respond, the previous request needs to be checked before sending a new one.

Angular catalogue, NestJS API, orders in PostgreSQL. A worker handles payment and delivery. Suppliers are HTTP mocks in the demo. It includes timeout, repeated webhook and order recovery scenarios.

  • Payments and providers are explicitly mocked; no money is charged and codes are for demonstration only.
  • Up to 20 orders per session and 1,000 new demo orders in total. One-hour TTL, cleanup every five minutes.
  • The recovery example deliberately fails the first delivery attempt for one order. It does not change global provider modes.

Screenshots, diagrams and source evidence retain their original language; captions and descriptions are translated.

Architecture and diagrams

  • Prices and discounts are calculated on the server and saved in the order.
  • A unique index protects Idempotency-Key; replayed input is checked against the original intent.
  • Webhooks are saved to a durable inbox first. A separate worker processes payments and the delivery queue.
  • The provider requestId remains stable across retries. An ambiguous timeout does not immediately allow a second code to be issued.
Components of the published demo
Components of the published demo · Mermaid ↓
Main workflow
Main workflow · Mermaid ↓
Deployment of the published version
Deployment of the published version · Mermaid ↓
Data structure and storage boundaries
Data structure and storage boundaries · Mermaid ↓

Code map: files and dependencies

This map is tied to version 767226bf3c2f. The table lists the screen or API, related module and data.

FeatureScreen / APIModuleData / verification
PurchaseStorefront / POST ordersstorefront.component; ShopService.createOrderorders, products, promocodes; race tests
PaymentPOST payments/simulate → webhooks/paymentPaymentsController; acceptWebhookpayment_events; duplicate event_id
DeliveryOrder / GET orders/:idworker.service processDeliveryJobdelivery_jobs, provider_requests, fulfillments; recovery
SessionGuard for all public ordersportfolio-demo PortfolioGuardHMAC cookie, prefix owner; tests/portfolio/run.ts
Reset / TTLPOST demo/reset / timerPortfolioCleanup.clearportfolio orders only; ownership / expiry tests

Using the code map

  1. Before making a change, find the feature and trace its links to the API, state and storage.
  2. Check inputs, errors, repeated events and dependent workflows.
  3. After making a change, update the map and affected diagrams alongside the code.
  4. Run the related checks and link the new evidence to the source version.

Workflows and API

  1. Choose a product and complete a successful test payment. Wait for the code and inspect the history.
  2. Replay the same payment event: the code and delivery must remain unique.
  3. Create an order using the failure scenario, pay and select “Recover my order”.
  4. Check a declined payment, another session's UUID and resetting your own example.

Verification of the published version

CI: CI ↗ · 767226bf · this demo's version · 2026-09-07T00:49:05Z

CI: Portfolio immutable image ↗ · 767226bf · this demo's version · 2026-09-07T00:49:05Z

  • Real HTTP webhook, durable inbox, worker, single fulfillment preserved on event replay
  • Foreign GET/recover return 404; other session reset preserves first order
  • Payment failure; isolated first-attempt delivery fault; own recovery succeeds

These checks apply to the listed version. Business metrics and model quality on an independent dataset were not measured.

Measurements

Total project container resources · 2026-09-07T01:08:27 — 01:11:22 UTC
Total project container resources · 2026-09-07T01:08:27 — 01:11:22 UTC · Source data ↓
Measured scenario repetitions over HTTPS · 2026-09-07T01:08:36 UTC; methodology limitations in JSON
Measured scenario repetitions over HTTPS · 2026-09-07T01:08:36 UTC; methodology limitations in JSON · Source data ↓
  • 14 meaningful screenshots of the actual interface retained.
  • Each screenshot includes its date, scenario and code revision.
  • Peak container RAM in the short test: 218.56 MiB. Shared services are counted separately; the shop includes its own database.
  • 6 scenario repetitions measured; median 129.0 ms, maximum 1939 ms. Timing includes the browser and HTTPS; methodology and limitations are included.

Running and operating

The demo and original app use the same order model. PORTFOLIO_DEMO=true enables the demo guard. Without the flag, the original API contracts apply.

GitHub Actions builds a pinned commit SHA. A prebuilt GHCR image is uploaded to the VPS. The shop database remains separate from the new applications.

Start: docker compose --env-file .env.production -f compose.production.yaml up -d. Run prisma migrate deploy before switching releases. Secrets are stored only on the server. Do not use seed as an unconditional reset of a running shop.

Readiness: /api/health/ready checks PostgreSQL. During an incident, compare the order history, inbox and delivery job; retry delivery for the original orderId instead of creating another purchase.

Builds run outside the VPS; the server receives static files and versioned images. Secrets are kept separately. Logs rotate; changing log options requires recreating the container. No server-wide docker prune.

The code map links a screen or API to its module and data. A change needs those links checked, the map updated and the affected flows rerun: normal path, error, retry and reset. Diagrams can go stale, so their version is listed alongside them.

Rollback checked at 2026-09-07T01:07:46.255650+00:00: 20260907-verified → 20260907 → 20260907-verified. HTTPS, readiness and SHA were confirmed after each switch. This checks configuration and artifacts at one verified SHA; no reverse database migration was performed.

Stack

Angular / TypeScriptStorefront, state signals, HTTP client and order polling.
NestJSContracts, validation, webhooks, recovery operations and demo limits.
PostgreSQL / PrismaMonetary snapshots, inbox, leased queue, unique indexes and transactions.
Node.js workerProvider HTTP calls outside short transactions, retries and final delivery.

Materials and source code

Implementation history: 1–3 September 2026. Portfolio preparation: 7 September 2026.

The evidence archive retains its original language.