Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ app/ (routes, pages) worker/ (two interval loops)

## Limitations, honestly

- **Web app deployed; the worker is not.** The Next.js app is live on Vercel (https://settle-wine-alpha.vercel.app) in **real mode** against a hosted Postgres — landing, NEAR-wallet sign-in, invoice create / list / dashboard / receipt — and `GET /api/health` returns `{"status":"ok","demo":false,"database":"ok"}` from the running deployment, not only from a local boot. It was **re-deployed on 2026-11-09** from the merged tip — the Vercel project is not connected to Git, so a merge does not deploy — and the staleness probe in `DEPLOY.md` §8 went from 404 to 200. Loading the live URL in a real browser then found a hydration mismatch on the landing page (React #418): the server's HTML said wallet sign-in was unavailable while the browser's first render offered it, so React threw the markup away. Fixed here and pinned by the fifth e2e test, then deployed: the live page re-checked in Chromium at 1440 px and 390 px reports the sign-in button enabled, no page or console error, no failed request and no horizontal overflow. A screenshot of that page then caught the one defect no probe could: the hero receipt's amounts inherited the brand field's white text and rendered white-on-white, so the same e2e test now reads the amount's computed colour and fails it, and the fix (a `text-ink` on the card root) was proven by re-injecting the bug and watching the test go red first. A green `/api/health` detects neither problem, which is why the deploy notes now say to probe a route only the new artifact has and then read the first screen's console. It was **re-deployed once more on 2026-11-10** with S1.7: the challenge probe answers 200, `/api/health` is green, the landing page opens in Chromium with no console message, and the live `/api/tokens` carries `refundChain` and lists BTC as refund-only (`settleChain: null`) with no BTC asset among the payouts. Two things that URL does not do yet, stated plainly: **no live payment quote**, because the vendor `ONECLICK_JWT` (S0.8) is not in hand, so the pay page fails closed before it prices anything; and **no background worker**, because a serverless host cannot keep the long-lived 5 s poll / 60 s expire process. That second limit is exactly why `DEPLOY.md` §6 concluded that a two-process host is a paid decision — Render's free-plan page says free plans do not support background workers, and usage-based hosts bill a worker that never idles. A full live payment therefore still needs a host that runs both processes plus the JWT. The offline evidence is unchanged: `pnpm demo`, the E2E browser journey — which drives a **production build** (`pnpm build` + `pnpm start`, the same two commands a host runs) rather than `next dev` — and 671 passing offline tests (672 total, one Postgres-only skip). `DEPLOY.md` also records two constraints that were measured, not assumed: PGlite is single-process — two processes on one directory lost half their writes and killed one outright — so a hosted Settle needs Postgres; and demo mode deliberately refuses an `https://` URL, so the hosted app runs **real mode** (decision `SD-8`) and the demo story lives in `pnpm demo` and the video.
- **Web app deployed; the worker is not.** The Next.js app is live on Vercel (https://settle-wine-alpha.vercel.app) in **real mode** against a hosted Postgres — landing, NEAR-wallet sign-in, invoice create / list / dashboard / receipt — and `GET /api/health` returns `{"status":"ok","demo":false,"database":"ok"}` from the running deployment, not only from a local boot. It was **re-deployed on 2026-11-09** from the merged tip — the Vercel project is not connected to Git, so a merge does not deploy — and the staleness probe in `DEPLOY.md` §8 went from 404 to 200. Loading the live URL in a real browser then found a hydration mismatch on the landing page (React #418): the server's HTML said wallet sign-in was unavailable while the browser's first render offered it, so React threw the markup away. Fixed here and pinned by the fifth e2e test, then deployed: the live page re-checked in Chromium at 1440 px and 390 px reports the sign-in button enabled, no page or console error, no failed request and no horizontal overflow. A screenshot of that page then caught the one defect no probe could: the hero receipt's amounts inherited the brand field's white text and rendered white-on-white, so the same e2e test now reads the amount's computed colour and fails it, and the fix (a `text-ink` on the card root) was proven by re-injecting the bug and watching the test go red first. A green `/api/health` detects neither problem, which is why the deploy notes now say to probe a route only the new artifact has and then read the first screen's console. It was **re-deployed once more on 2026-11-10** with S1.7: the challenge probe answers 200, `/api/health` is green, the landing page opens in Chromium with no console message, and the live `/api/tokens` carries `refundChain` and lists BTC as refund-only (`settleChain: null`) with no BTC asset among the payouts. The **same day** it was deployed again with S4.15, the dark landing redesign: the served HTML carries the new hero ("Invoice in dollars. Paid in any token."), the challenge probe answers 200, `/api/health` is green, the sign-in button is enabled after hydration, and Chromium at 1440 px and 390 px reports **no page or console error and no horizontal overflow**. Two things that URL does not do yet, stated plainly: **no live payment quote**, because the vendor `ONECLICK_JWT` (S0.8) is not in hand, so the pay page fails closed before it prices anything; and **no background worker**, because a serverless host cannot keep the long-lived 5 s poll / 60 s expire process. That second limit is exactly why `DEPLOY.md` §6 concluded that a two-process host is a paid decision — Render's free-plan page says free plans do not support background workers, and usage-based hosts bill a worker that never idles. A full live payment therefore still needs a host that runs both processes plus the JWT. The offline evidence is unchanged: `pnpm demo`, the E2E browser journey — which drives a **production build** (`pnpm build` + `pnpm start`, the same two commands a host runs) rather than `next dev` — and 671 passing offline tests (672 total, one Postgres-only skip). `DEPLOY.md` also records two constraints that were measured, not assumed: PGlite is single-process — two processes on one directory lost half their writes and killed one outright — so a hosted Settle needs Postgres; and demo mode deliberately refuses an `https://` URL, so the hosted app runs **real mode** (decision `SD-8`) and the demo story lives in `pnpm demo` and the video.
- **A real quote has never been driven offline, and since 2026-11-10 no quote is served without the partner JWT.** The minimum refusal itself is not a guess — `try at least N` was provoked against the live API on 2026-11-09 with unauthenticated _dry_ quotes, which is what fixed the units it is rendered in (S0.13). Then, on **2026-11-10**, the same unauthenticated `POST /v0/quote` — dry or not, on three routes including the USDC→USDC call that had answered 200 the day before — returned `400 Internal server error`, while the same body with a bogus bearer returned `401 Invalid token`. The token list still answers without credentials. So a real payment now needs the partner JWT (S0.8, #11) even for a preview, plus a funded signer, a running worker and a two-process host.
- **Refund addresses are checked on five payout chains, plus Bitcoin.** `lib/core/address.ts` validates NEAR, EVM (EIP-55), Solana and, since S1.7, **BTC** — base58-check P2PKH/P2SH and segwit bech32/bech32m, mainnet only. Bitcoin is a _refund-only_ chain: a client can pay from BTC and is refunded there, but Settle never pays out to it. Everything else a client might pay from is still refused with a reason rather than accepted unchecked; for TON and Tron that is a missing validator, and for chains that need a memo it is the missing memo field. The memo list itself is ours and flagged 🔍, because 1Click does not publish which origins require one. Refusing errs safe: an address Settle cannot check is not one it will send money back to.
- **A region block is passed through, not recognised.** The vendor's own wording reaches the client; Settle does not match it against strings it guessed.
Expand Down
Loading
Loading