Amirali YaghoutiSenior Software Engineer

platform Case study

Fatahi Gold

Melted gold is priced by the gram and the price moves all day. A shop selling it needs a price on screen that is current, that already includes their own markup and fee, and that does not silently show a stale number when the upstream feed stops responding.

The business problem

The price a customer sees has to be the price the shop will honour, which means the shop's markup and fee must be applied before it is displayed, not in the customer's browser where it could be read or altered. The feed itself is the other half of the problem: an upstream price API that hangs would either freeze the page or, worse, leave a stale figure on screen that looks live.

What I delivered

  • A mobile-first Persian RTL progressive web app with a manifest, a service worker and an install flow, since the customers using it are on phones.
  • A server-side price endpoint that fetches the upstream feed, applies a percentage markup, a fixed markup and a fee, and returns only the final figure.
  • A five-second client poll against that endpoint, so the displayed price tracks the market without the browser ever seeing the raw upstream value.
  • A declared fallback price and a source field on every response, so the front end always knows whether it is showing a live figure or a fallback.
  • A four-second timeout on the upstream fetch, well inside the poll interval, so a hanging feed can never stack requests.
  • A separate order endpoint with its own timeout and token, keeping ordering independent of the pricing path.
  • Explicit security headers and a permissions policy that switches off geolocation, microphone and camera.
  • Dark and light theming with per-theme colors, and a shop-configurable brand accent, since the same app structure serves more than one gold retailer.

Technical approach

  • Markup and fee are applied on the server. The browser receives a price to display, never the inputs used to compute it.
  • The response names its own source, so a fallback price is identifiable rather than indistinguishable from a live one. That is the difference between a degraded display and a misleading one.
  • Upstream timeout is set below the poll interval on purpose: a slow feed produces a fallback, not a queue of in-flight requests.
  • Numeric parsing strips non-numeric characters before casting, because upstream price feeds are not consistent about formatting and a fatal parse error on a price display is unacceptable.
  • Pricing and ordering are separate endpoints with separate timeouts, so an ordering problem never takes the price board down.
  • All brand, markup, fee and theming values are configuration constants, which is what lets the same application serve a second retailer without a fork.

Result and evidence

The shop runs a live price board its customers can install on their phone, and the failure mode is a labelled fallback rather than a frozen or stale number. The configuration split means the same codebase has been set up for more than one gold retailer.

Commercial value

For a gold dealer the price display is the product. Getting the degraded state right matters more than the happy path, because a stale price shown as live is a commitment the shop did not intend to make.

implementation-brief.readme

Readable implementation brief

implementation_brief {
  project: "Fatahi Gold"
  stack: "PHP endpoints + vanilla JS, Persian RTL PWA"
  pricing: "api/price.php polled every 5s"
  computed_serverside: "percent markup + fixed markup + fee"
  degradation: "declared fallback price; every response names
                its source (live or fallback)"
  timeout: "4s upstream, inside the 5s poll, no pile-up"
  ordering: "separate endpoint, own timeout and token"
  headers: "nosniff, SAMEORIGIN, same-origin referrer,
            geolocation/mic/camera disabled"
  reuse: "brand, markup, fee and theme are constants"
}

What this project shows

The decision I would highlight is putting markup and fee on the server and having every response declare its source. It costs nothing and it is what makes the fallback honest.

Setting the upstream timeout inside the poll interval is a small piece of arithmetic that prevents the most common failure in polling front ends, which is request pile-up during an outage.