docs(payments): rewrite PAYMENT-DEPLOYMENT.md + add config verifier script#99
Open
TortoiseWolfe wants to merge 1 commit into
Open
docs(payments): rewrite PAYMENT-DEPLOYMENT.md + add config verifier script#99TortoiseWolfe wants to merge 1 commit into
TortoiseWolfe wants to merge 1 commit into
Conversation
284cae7 to
4c7b805
Compare
4 tasks
TortoiseWolfe
added a commit
that referenced
this pull request
May 20, 2026
…servability (#108) ROOT CAUSE (still WebKit-specific, but at a deeper layer than rounds 11-13) Even with rounds 11+12+13 applied (native scroll listener, sustained- hidden modal verification, timing-budget separation), webkit-msg 1/1 still intermittently fails on `messaging-scroll.spec.ts:266` "T007-T008: Jump button". PR #99 run 26176580568 caught one such failure with all 3 retries failing. Forensic from the failure-time screenshot at `/tmp/pr99-flake/extracted/resources/21b9a69b...png` (extracted from the blob report): the page IS loaded, the conversation IS open, the test IS clicking through the flow correctly. The button truly never renders. The race: 1. Test sets `messageThread.scrollTop = ...` + dispatches a native scroll event (round-11 pattern: works around React's onScroll not catching synthetic events on WebKit). 2. Native event fires → handleScroll() runs → setShowScrollButton (true) queues a React state update. 3. Test reads `scrollInfo` via a separate `.evaluate(...)` call — this reads DOM values, NOT React state. 4. Test asserts `expect(jumpButton).toBeVisible()` with 5s timeout. 5. React schedules the state update for the next microtask / animation frame. 6. WebKit's event loop on Linux CI under heavy concurrent shard load sometimes defers this render past the 5s assertion window. The DOM scroll position IS correct (step 1 + 3 agree). What's missing is observability of the *component's reaction* to the scroll. THE FIX (round 14a — first of two) Add `data-show-scroll-button={showScrollButton ? 'true' : 'false'}` to the MessageThread wrapper div. This attribute mirrors React state to the DOM during commit — visible to Playwright the moment the state-update flushes. The test now polls this attribute (via expect.poll with 50/100/200/500ms intervals) BEFORE asserting the button is visible. Why this is the structural fix and not another mitigation: - The attribute is a direct projection of the component's internal state — there's no in-between system (React reconciler vs WebKit event loop) for the test to race against. - The wrapper element is always in the DOM (it's the outer `relative h-full` container, not the scrollable child) — so the attribute query never returns null. - The component now exposes a stable, documented observability boundary for any future test that needs to know when the scroll- button state is true. - This pattern matches the round-10/-12 lesson: trust attribute polling over event-driven assumptions when crossing browser engine boundaries. WHAT THIS DOES NOT DO - Does NOT remove round-11's native scroll listener (it's still correct for catching the dispatched scroll event) - Does NOT remove round-12's sustained-hidden verification (it's still correct for the modal-retry flake) - Does NOT seed conversation data — that's round 14b in a follow-up PR. Round 14b fixes a separate failure mode (thin conversations not having enough scroll height to enter the `if` branch). ROUND 14 PROGRESS | Round | PR | Layer | |---|---|---| | 14a (this) | TBD | data-show-scroll-button attribute (observability) | | 14b | follow-up | seed 30 messages into test conversation (data shape) | VERIFICATION - 31/31 MessageThread unit tests pass (no regression) - Type-check clean - Lint clean - The E2E test `T007-T008: Jump button` now polls a state mirror that fires in the same React render as the button itself — eliminating the inter-system race. Co-authored-by: TurtleWolfe <TurtleWolfe@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…fig.sh
AUDIT FINDINGS
A payment-readiness audit (2026-05-20 session) found `docs/PAYMENT-DEPLOYMENT.md`
contained multiple bugs that misled forkers and risked secret leakage:
1. Lines 73-79 told users to put STRIPE_SECRET_KEY / PAYPAL_CLIENT_SECRET
in `.env.local`. SECURITY VIOLATION. The template deploys to GitHub
Pages (static export); non-NEXT_PUBLIC_ vars are never read by a Next
server runtime. Server logic runs in Supabase Edge Functions which
read secrets via Deno.env.get() after they're set in Supabase Vault.
The `.env.example` already documents this correctly at lines 138-181;
the deployment doc contradicted it.
2. Line 93 `supabase secrets set PAYPAL_CLIENT_ID=...` — wrong. PAYPAL_
CLIENT_ID is browser-safe (`NEXT_PUBLIC_*`), belongs in `.env`.
3. Lines 106-110 listed 5 function names — 3 were fictional:
`stripe-create-payment`, `paypal-create-subscription`, `send-receipt-
email`. Actual function names (verified): `stripe-webhook`, `paypal-
webhook`, `send-payment-email`.
4. The doc did NOT mention `PAYPAL_WEBHOOK_ID` as a required Vault
secret, despite `.env.example:147` documenting it.
5. PayPal event list (lines 144-148) used legacy `PAYMENT.SALE.*` events
instead of the modern Orders v2 `PAYMENT.CAPTURE.*` events that the
`paypal-webhook` source code actually listens for (verified by grep).
6. Stripe CLI install instructions were Mac-only (`brew install ...`).
This template's docker-first dev environment runs on WSL2 / Linux too.
7. The doc presented a "fill in keys + deploy + go-live" flow that
implicitly claimed the integration was operational. Cross-referencing
`grep -rohE "functions/v1/[a-z-]+" src/lib/payments src/components`
against `ls supabase/functions/` revealed 8 outbound Edge Functions
called by browser code that do NOT exist in the repo:
create-stripe-checkout, verify-stripe-session,
create-stripe-subscription, create-paypal-order,
capture-paypal-order, create-paypal-subscription,
cancel-subscription, resume-subscription
The TODO comment in `src/lib/payments/stripe.ts:48` confirms this:
"// (Edge Function will be created in Phase 5)". Phase 5 was never
completed. Without these functions, clicking "Pay" on `/payment-demo`
fails with a 404 from a nonexistent function URL.
CHANGES IN THIS COMMIT
`docs/PAYMENT-DEPLOYMENT.md` is fully rewritten:
- New "Status of the integration" table at the top makes the missing
Phase 0 work explicit — operators see this before sinking time into
setup
- Fixed function names match what's actually in `supabase/functions/`
- Secrets-belong-in-Vault is the single canonical guidance (no .env
fallback advice)
- PAYPAL_WEBHOOK_ID added to Step 3.2
- PayPal event list updated to the modern `PAYMENT.CAPTURE.*` family
(the webhook code still listens for `PAYMENT.SALE.*` too for legacy
compatibility, documented)
- Stripe CLI install includes both macOS (brew) and Linux/WSL2 (tar)
paths
- New Step 6 "Smoke-test locally (after Phase 0 ships)" makes the
dependency on the missing functions explicit
- Common-issues table includes "Pay button fails with 404 → Outbound
Edge Functions not deployed (Phase 0 work)"
- References point at the open issues tracking Phase 0 work
`scripts/check-payment-config.sh` is a new verifier script (executable):
- Reads `.env` and grep'd lines that look like `VAR=value`, masks the
value for display, flags placeholders (`xxxx...`, `your-anon-key`)
- Queries `supabase secrets list` to confirm all 5 Vault secrets are
set
- Exit 0: all 9 values present
- Exit 1: at least one missing (with remediation hint)
- Exit 2: supabase CLI not available (with install hint)
Style mirrors `scripts/prp-to-feature.sh` and other shipped scripts
(bash, set -e, ANSI colors).
Smoke-tested locally: correctly identifies that NEXT_PUBLIC_SUPABASE_URL
and ANON_KEY are set (existing dev env), STRIPE/PAYPAL not set, and
supabase CLI missing → exit 2 with install instruction.
WHAT THIS PR DOES NOT DO
- Does NOT write the 8 missing Edge Functions (tracked as separate
follow-up issues; estimated 2-3 dev days)
- Does NOT un-skip the E2E payment tests under `tests/e2e/payment/`
(they would still fail without Phase 0)
- Does NOT touch any application code (`src/`)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4c7b805 to
724425c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A payment-readiness audit (2026-05-20) found 7 bugs in
docs/PAYMENT-DEPLOYMENT.mdplus a missing utility script. This PR ships docs/script fixes only — no application code changes. Tracked as a side-quest emerging from the broader payment-readiness investigation.The deeper structural gap (8 missing Edge Functions) is now tracked as a 6-issue epic: #100 (with sub-issues #101–#106).
Bug fixes in
docs/PAYMENT-DEPLOYMENT.mdSTRIPE_SECRET_KEYin.env.local(security violation — secret in committed-shaped file)supabase secrets set..envis forNEXT_PUBLIC_*only. Matches.env.examplecanonical guidance.supabase secrets set PAYPAL_CLIENT_ID=...PAYPAL_CLIENT_IDis browser-safe (NEXT_PUBLIC_*), belongs in.envstripe-create-payment,paypal-create-subscription,send-receipt-emailstripe-webhook,paypal-webhook,send-payment-emailPAYPAL_WEBHOOK_IDnot mentioned.env.example:147already documents it as a required Vault secretPAYMENT.SALE.*(legacy API)PAYMENT.CAPTURE.*brew install ...(Mac-only)New: scripts/check-payment-config.sh
Companion verifier. Reads .env + queries supabase secrets list to confirm all 9 required env values are configured. Style mirrors existing scripts. Smoke-tested locally.
Exit codes: 0 = all set, 1 = missing, 2 = supabase CLI not available.
What this PR explicitly does NOT do
Related work
🤖 Generated with Claude Code