About the project
The assignment asked for a digital goods shop with catalog, checkout and payment. I extended the base scenario with an idempotent webhook inbox, concurrency-safe key fulfillment, stage retries and observable failure states.
The test assignment is implemented as a complete digital shop flow: Angular storefront, NestJS API, PostgreSQL via Prisma, payment webhook, two key providers and a background fulfillment worker. The UI covers purchase, repeated payment events and recovery after stock or provider failures.
What sets the implementation apart
Fulfillment happens once even under repeated or concurrent webhooks. A stable provider request ID survives an ambiguous timeout; out_of_stock and delivery_failed recover on a later worker pass. Database constraints and FOR UPDATE SKIP LOCKED enforce invariants at the storage layer.
Application-code composition
Shares use Git application-file bytes at pinned revisions. Each file belongs to one subsystem under scripts/generate-stack-share.mjs rules; tests, assets, dependencies and generated files are excluded. Rounded to 0.1%. This describes code composition, not proficiency.
- 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.
Code map: files and dependencies
This map is tied to version 767226bf3c2f. The table lists the screen or API, related module and data.
| Feature | Screen / API | Module | Data / verification |
|---|---|---|---|
| Purchase | Storefront / POST orders | storefront.component; ShopService.createOrder | orders, products, promocodes; race tests |
| Payment | POST payments/simulate → webhooks/payment | PaymentsController; acceptWebhook | payment_events; duplicate event_id |
| Delivery | Order / GET orders/:id | worker.service processDeliveryJob | delivery_jobs, provider_requests, fulfillments; recovery |
| Session | Guard for all public orders | portfolio-demo PortfolioGuard | HMAC cookie, prefix owner; tests/portfolio/run.ts |
| Reset / TTL | POST demo/reset / timer | PortfolioCleanup.clear | portfolio orders only; ownership / expiry tests |
Using the code map
- Before making a change, find the feature and trace its links to the API, state and storage.
- Check inputs, errors, repeated events and dependent workflows.
- After making a change, update the map and affected diagrams alongside the code.
- Run the related checks and link the new evidence to the source version.
Workflows and API
- Choose a product and complete a successful test payment. Wait for the code and inspect the history.
- Replay the same payment event: the code and delivery must remain unique.
- Create an order using the failure scenario, pay and select “Recover my order”.
- 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
- 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 / TypeScript | Storefront, state signals, HTTP client and order polling. |
|---|---|
| NestJS | Contracts, validation, webhooks, recovery operations and demo limits. |
| PostgreSQL / Prisma | Monetary snapshots, inbox, leased queue, unique indexes and transactions. |
| Node.js worker | Provider 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.