Files
pak-jabit/docs/MOCKS.md
T
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

140 lines
6.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 🏷️ 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.
```bash
# 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.*