Files
juxtapoandClaude Opus 5 a58a61b98c Pak Jabit: full stack — storefront, Spree customisations, catalogue tooling
A South African men's apparel store on Spree 5.6 + Next.js 15. 160 products
live, three markets, live Malaysian courier rates, customer-owned carts.

What is here:
  storefront/  the Next.js app
  backend/     ONLY the custom Spree code. Spree itself is a prebuilt image
               that mounts no app code, so every file here needs an explicit
               volume entry in docker-compose.yml or it is silently ignored.
  catalogue/   the scripts that loaded and maintain the products
  docs/        manifest, mock registry, napkins

Real .env files are committed deliberately. This lives on the house's private
Gitea, and a clone that runs beats a clone that needs a secrets handover.
LANDMINE.md maps every key, what it opens, and what must be rotated before this
repo goes anywhere less private.

The admin API key used to be a literal in six catalogue scripts. They now read
SPREE_ADMIN_KEY from the environment and refuse to run without it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-15 22:09:55 +08:00

6.5 KiB
Raw Permalink Blame History

🏷️ MOCKS — every fake value in Pak Jabit

The convention: anything standing in for a real credential, rate, or record is tagged #mock. Going live = find them all, replace them, delete this list.

# storefront + backend files
rg '#mock' ~/pak-jabit-store ~/pak-jabit

🔴 rg cannot find half of them. Mocks that live in the Spree database — payment methods, test products, test orders, test users — have no file to grep. This file is the authority; the inline tags are a convenience. When you add a mock, add it here first.

⚠️ Never tag an env var inline. Docker Compose's env_file does not strip trailing comments — it takes the rest of the line as the value, so PHOTOROOM_API_KEY=abc123 #mock makes the key literally abc123 #mock and Photoroom fails with no error anywhere. The tag goes on its own line above, which is safe in both Compose and dotenv.


Files — rg '#mock' finds these

Storefront ~/pak-jabit-store/.env.production (celest-proto, 34.21.217.116)

Var Why it's mock Replace with
EASYPARCEL_CLIENT_ID Malaysia-only courier, left from the MY phase Bob Go credentials
EASYPARCEL_CLIENT_SECRET same Bob Go credentials
STORE_POSTCODE 10150 = Penang, Malaysia real SA warehouse postcode
STORE_STATE MY-07 = Penang, Malaysia real SA province

The whole EasyParcel lane (src/lib/easyparcel.ts, src/app/api/shipping/*, src/app/api/webhooks/easyparcel) is MY-only and dead for a South African store. It points at https://api.easyparcel.com — the production host, not a sandbox. It is not wired into the SA checkout path; it just hasn't been removed.

Backend ~/pak-jabit/.env (pak-jabit-backend, 35.247.170.3)

Var Why it's mock Replace with
PHOTOROOM_API_KEY sandbox key — every output is watermarked live key from /root/.photoroom/credentials (house box), 10/month

Storefront env — SPREE_CARD_PAYMENT_METHOD_ID

Tagged in .env.production. Holds pm_EfhxLZ9ck8, the prefixed id of the Bogus gateway. Repoint it at the Payfast payment method when that lands. The route that reads it (src/app/api/auth/cards/setup/route.ts) errors loud with an explicit message when it is unset — it never guesses an id, because a wrong one would attach cards to whichever gateway happened to match.

That route is itself #mock-shaped: it does BOTH halves of card setup in one request, which only works because Bogus needs no card entry. A real gateway must split it — server creates the session, the CLIENT collects the card in the gateway's hosted field against external_client_secret, then the server completes. Card numbers must never reach our server. The file says so at the top.


Database — grep will never find these

Payment methods

Name Class Why it's mock
Test Card (sandbox) Spree::Gateway::Bogus Fake card gateway, added 2026-09-15. Accepts 4111111111111111 (Visa), 5555555555554444 (MC), 378282246310005 (Amex), 6011111111111117 (Discover); anything else is a forced decline, which is how to test the failure path. show_in_admin? is false so it stays out of the admin list.
Test Payment Spree::PaymentMethod::Check Offline placeholder. No money moves.

Both carry #mock in their description column, visible in admin.

Replace with: Payfast, once NSH's merchant registration lands. Payflex after. Deactivate both of these before launch — a live store must not offer a gateway that approves every card ending in the right digits.

Shipping methods

Name Why it's mock
Standard Delivery (South Africa) Flat R99, zone South Africa (ZA only), added 2026-09-15. The number is a PLACEHOLDER, not a quoted rate — it exists so SA checkout can complete at all. Replace with Bob Go once the SA courier account is registered.

Before this, ZA sat in the Africa zone with no method attached and every physical method was bound to Malaysia/US, so a South African buyer got no quote and checkout dead-ended.

Shipping rates per market — all placeholders

Market Method Rate
South Africa (ZAR) Standard Delivery (South Africa) R99
Malaysia (MYR) EasyParcel Domestic live EasyParcel quote — not mock
United States (USD) Free Shipping $0

🔴 ZA and US are placeholders; Malaysia is real. MY charges the courier the customer picked, verified server-side against a live EasyParcel quote. They exist so each market can complete a checkout at all. A shipping rate only applies when its calculator's currency matches the ORDER's currency — every non-SA method was priced in a currency no order used, which produced no rate, no fulfillment, and a checkout with nothing to charge. That, not zones or stock, is why Malaysian checkout died silently.

Standard Shipping (USD $15) sits in the Malaysia zone and will never offer — wrong currency for that market. Harmless, but it is noise to clear when the MY lane is removed.

Products

Slug Why it's mock
studio-test-chinos Built 2026-09-15 proving the Image Studio pipe end to end. Kept deliberately as the worked example for colleagues testing the image editor. R259.11, watermarked sandbox images. Delete before launch.

That's 1 of 161 products. The other 160 are real scraped stock.

Orders

14 orders, 4 completed, all test. They are priced in the old currency at the old 23× rate — the newest completed one reads $2,577.12, which is neither ZAR nor a real price. They predate both the price fix and the ZAR switch. Purge before launch or the first real report is nonsense.

Users

Test accounts matching celeste-*@example.com — created during API verification on 2026-09-15. No real customers exist yet.


Not mock, but not real either

These aren't fake credentials; they're claims the store makes that nothing backs.

Thing Problem
"Free shipping over R500" Hardcoded storefront copy. No shipping rule exists behind it. A buyer who qualifies gets charged anyway — or gets no quote at all, see below.
SA shipping ZA is in the Africa zone with no shipping method attached. Every physical method is bound to Malaysia/US. A South African buyer gets no quote and cannot complete checkout. Blocked on courier registration.
S/M/L/XL buttons Decorative. No Spree::Variant behind them — every product is one variant.

Started 2026-09-15. Add to this file when you add a mock, not after.