chore(waffo): let the provisioning scripts target the live store - #476
chore(waffo): let the provisioning scripts target the live store#476moapacha wants to merge 1 commit into
Conversation
Going live means provisioning a different store with a different API key than the test credentials in .env.local. Both scripts hardcoded that file and waffo-bootstrap picked its store by name (falling back to whichever store happened to be first), so neither could be pointed at the activated store without editing the test credentials in place. - WAFFO_ENV_FILE selects the credential file (default .env.local). - waffo-bootstrap honours WAFFO_STORE_ID, and fails loudly when the id is not visible to the key in use — a test key cannot see the live store's production catalogue, and silently creating a second product is worse than stopping. - The webhook script now reports which env file and store it registered against, so a test-mode registration is obvious in the output. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
🔵 PR Size: size/XS 📊 Stats:
This PR is tiny and quick to review. |
📝 WalkthroughWalkthroughThe Waffo bootstrap and webhook registration scripts now support ChangesWaffo script configuration
Estimated code review effort: 3 (Moderate) | ~20 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/waffo-bootstrap.ts`:
- Around line 3-17: Update the bootstrap output messages to consistently use the
selected envFile value for credential instructions and webhook registration. In
the webhook command, include WAFFO_ENV_FILE=${envFile} and derive the
environment or mode from the selected configuration instead of hard-coding
“test”, ensuring production provisioning never directs operators to .env.local
or the test environment.
- Around line 49-61: Update the configuredStoreId initialization in the
bootstrap store-selection flow to normalize a trimmed empty WAFFO_STORE_ID to
undefined, so the existing Murmur and first-store fallbacks remain available.
Preserve validation for non-empty configured IDs and the subsequent storeId
fallback order.
- Around line 26-27: Make WAFFO_ENV_FILE a strict boundary in
scripts/waffo-bootstrap.ts lines 26-27 and scripts/waffo-webhook-register.ts
lines 14-16: when explicitly supplied, validate and load that file first,
failing if it is missing or incomplete before applying .env/.env.local fallback
values; preserve the lower-priority fallback order so envFile, storeId,
testMode, and credentials remain consistent in both scripts.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 5fb313fc-4aa4-4568-af49-21a39061751f
📒 Files selected for processing (2)
scripts/waffo-bootstrap.tsscripts/waffo-webhook-register.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (3)
- GitHub Check: verify
- GitHub Check: Analyze (python)
- GitHub Check: Analyze (javascript-typescript)
⚠️ CI failures not shown inline (2)
GitHub Actions: Security / Bun dependency audit: chore(waffo): let the provisioning scripts target the live store
Conclusion: failure
##[group]Run bun audit --audit-level=high
�[36;1mbun audit --audit-level=high�[0m
shell: /usr/bin/bash -e {0}
##[endgroup]
�[0m�[1mbun audit �[0m�[2mv1.3.9 (cf6cdbbb)�[0m
fast-uri >=3.0.0 <3.1.5
`@modelcontextprotocol/sdk` › ajv › fast-uri
eslint › `@eslint/eslintrc` › ajv › fast-uri
high: fast-uri vulnerable to host confusion via backslash authority introducer - https://github.com/advisories/GHSA-7p8r-x3mc-p8w7
ip-address <=10.3.0
`@modelcontextprotocol/sdk` › express-rate-limit › ip-address
high: ip-address: Address4 decodes leading-zero octets as decimal while resolvers decode them as octal, allowing SSRF and trust-boundary bypass - https://github.com/advisories/GHSA-mwp4-54f8-5fhr
brace-expansion >=4.0.0 <5.0.9
eslint › `@eslint/eslintrc` › minimatch › brace-expansion
eslint-config-next › typescript-eslint › `@typescript-eslint/utils` › `@typescript-eslint/typescript-estree` › minimatch › brace-expansion
shadcn › ts-morph › `@ts-morph/common` › minimatch › brace-expansion
high: brace-expansion: DoS via unbounded intermediate arrays, bypassing the CVE-2026-14257 mitigation - https://github.com/advisories/GHSA-rgw5-rvv9-x895
undici >=8.0.0 <8.9.0
(direct dependency)
shadcn › undici
high: undici vulnerable to cross-user information disclosure and parse-time crash via degenerate private cache directives - https://github.com/advisories/GHSA-4cwx-7wf7-3272
high: undici vulnerable to cross-user information disclosure and parse-time crash via degenerate private cache directives - https://github.com/advisories/GHSA-4cwx-7wf7-3272
5 vulnerabilities (5 high)
To update all dependencies to the latest compatible versions:
bun update
To update all dependencies to the latest versions (including breaking changes):
bun update --latest
##[error]Process completed with exit code 1.
GitHub Actions: Security / 2_Bun dependency audit.txt: chore(waffo): let the provisioning scripts target the live store
Conclusion: failure
##[group]Run bun audit --audit-level=high
�[36;1mbun audit --audit-level=high�[0m
shell: /usr/bin/bash -e {0}
##[endgroup]
�[0m�[1mbun audit �[0m�[2mv1.3.9 (cf6cdbbb)�[0m
fast-uri >=3.0.0 <3.1.5
`@modelcontextprotocol/sdk` › ajv › fast-uri
eslint › `@eslint/eslintrc` › ajv › fast-uri
high: fast-uri vulnerable to host confusion via backslash authority introducer - https://github.com/advisories/GHSA-7p8r-x3mc-p8w7
ip-address <=10.3.0
`@modelcontextprotocol/sdk` › express-rate-limit › ip-address
high: ip-address: Address4 decodes leading-zero octets as decimal while resolvers decode them as octal, allowing SSRF and trust-boundary bypass - https://github.com/advisories/GHSA-mwp4-54f8-5fhr
brace-expansion >=4.0.0 <5.0.9
eslint › `@eslint/eslintrc` › minimatch › brace-expansion
eslint-config-next › typescript-eslint › `@typescript-eslint/utils` › `@typescript-eslint/typescript-estree` › minimatch › brace-expansion
shadcn › ts-morph › `@ts-morph/common` › minimatch › brace-expansion
high: brace-expansion: DoS via unbounded intermediate arrays, bypassing the CVE-2026-14257 mitigation - https://github.com/advisories/GHSA-rgw5-rvv9-x895
undici >=8.0.0 <8.9.0
(direct dependency)
shadcn › undici
high: undici vulnerable to cross-user information disclosure and parse-time crash via degenerate private cache directives - https://github.com/advisories/GHSA-4cwx-7wf7-3272
high: undici vulnerable to cross-user information disclosure and parse-time crash via degenerate private cache directives - https://github.com/advisories/GHSA-4cwx-7wf7-3272
5 vulnerabilities (5 high)
To update all dependencies to the latest compatible versions:
bun update
To update all dependencies to the latest versions (including breaking changes):
bun update --latest
##[error]Process completed with exit code 1.
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Keep auth, AI, notification, and memory integrations behind
src/lib/platform/or another narrow adapter boundary; do not spread service-specific wiring across feature files.
Files:
scripts/waffo-bootstrap.tsscripts/waffo-webhook-register.ts
🔇 Additional comments (2)
scripts/waffo-webhook-register.ts (2)
2-12: LGTM!
45-47: LGTM!
| * Create the Murmur store + generic notes top-up product on Waffo. | ||
| * | ||
| * Requires: | ||
| * WAFFO_MERCHANT_ID | ||
| * WAFFO_PRIVATE_KEY (or WAFFO_PRIVATE_KEY_BASE64) | ||
| * | ||
| * Optional: | ||
| * WAFFO_STORE_ID target an existing store instead of picking by name | ||
| * WAFFO_ENV_FILE credential file to load (default `.env.local`); point | ||
| * it at e.g. `.env.waffo.prod` to provision the live store | ||
| * | ||
| * Usage: | ||
| * bun run waffo:bootstrap | ||
| * | ||
| * Prints WAFFO_STORE_ID and WAFFO_TOPUP_PRODUCT_ID for .env.local. | ||
| * Prints WAFFO_STORE_ID and WAFFO_TOPUP_PRODUCT_ID for the env file. |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Use the selected environment file in all bootstrap instructions.
When WAFFO_ENV_FILE points to .env.waffo.prod, the existing messages still direct the operator to .env.local. The webhook command also omits WAFFO_ENV_FILE, and the message hard-codes test. This can make the go-live flow update or register the wrong environment.
Use envFile in the credential instructions and print a command such as WAFFO_ENV_FILE=${envFile} bun run waffo:webhook-register. Do not hard-code the webhook mode.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/waffo-bootstrap.ts` around lines 3 - 17, Update the bootstrap output
messages to consistently use the selected envFile value for credential
instructions and webhook registration. In the webhook command, include
WAFFO_ENV_FILE=${envFile} and derive the environment or mode from the selected
configuration instead of hard-coding “test”, ensuring production provisioning
never directs operators to .env.local or the test environment.
| const envFile = process.env.WAFFO_ENV_FILE?.trim() || ".env.local"; | ||
| loadEnv({ path: resolve(ROOT, envFile), override: true }); |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n -C 4 'WAFFO_ENV_FILE|loadEnv\(' \
scripts/waffo-bootstrap.ts \
scripts/waffo-webhook-register.ts
tmp_dir="$(mktemp -d)"
trap 'rm -rf "$tmp_dir"' EXIT
curl -fsSL \
'https://raw.githubusercontent.com/motdotla/dotenv/v17.4.2/lib/main.js' \
> "$tmp_dir/main.js"
rg -n -C 4 'readFileSync|error' "$tmp_dir/main.js"Repository: p-to-q/murmur
Length of output: 5484
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the exact dotenv call results and script startup/error paths.
for f in scripts/waffo-bootstrap.ts scripts/waffo-webhook-register.ts; do
echo "=== $f ==="
wc -l "$f"
sed -n '1,80p' "$f"
done
echo "=== package dotenv scripts references ==="
rg -n '"dotenv"|dotenv-vault|loadEnv\(' . --glob '!node_modules' --glob '!dist' --glob '!build' | head -100
echo "=== local dotenv implementation files if any ==="
fd -i 'dotenv|vault' . node_modules 2>/dev/null | head -50 || trueRepository: p-to-q/murmur
Length of output: 7370
Make WAFFO_ENV_FILE a strict env boundary.
When WAFFO_ENV_FILE is supplied, load it first and fail if it is missing or incomplete before loading .env/.env.local. The current calls also load .env after .env.local, so local values can override script defaults or explicit credentials.
scripts/waffo-bootstrap.ts#L26-L27: apply the explicit-file guard before any lower-priority env fallback.scripts/waffo-webhook-register.ts#L15-L17: apply the same guard soenvFile,storeId, andtestMode, printed at registration, match the credentials used.
📍 Affects 2 files
scripts/waffo-bootstrap.ts#L26-L27(this comment)scripts/waffo-webhook-register.ts#L14-L16
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/waffo-bootstrap.ts` around lines 26 - 27, Make WAFFO_ENV_FILE a
strict boundary in scripts/waffo-bootstrap.ts lines 26-27 and
scripts/waffo-webhook-register.ts lines 14-16: when explicitly supplied,
validate and load that file first, failing if it is missing or incomplete before
applying .env/.env.local fallback values; preserve the lower-priority fallback
order so envFile, storeId, testMode, and credentials remain consistent in both
scripts.
| const configuredStoreId = process.env.WAFFO_STORE_ID?.trim(); | ||
| if (configuredStoreId && !stores.some((s) => s.id === configuredStoreId)) { | ||
| console.error( | ||
| `WAFFO_STORE_ID ${configuredStoreId} is not visible to this API key.\n` + | ||
| `Stores this key can see: ${stores.map((s) => `${s.id} (${s.name})`).join(", ") || "none"}`, | ||
| ); | ||
| process.exitCode = 1; | ||
| return; | ||
| } | ||
| let storeId = | ||
| configuredStoreId ?? | ||
| stores.find((s) => s.name === "Murmur")?.id ?? | ||
| stores[0]?.id; |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Treat an empty WAFFO_STORE_ID as unset.
process.env.WAFFO_STORE_ID?.trim() returns "" for the blank value documented in .env.example. configuredStoreId ?? ... preserves that empty string, so storeId skips the Murmur and first-store fallbacks and creates a new store.
Normalize blank values to undefined, or use configuredStoreId || ....
Proposed fix
- const configuredStoreId = process.env.WAFFO_STORE_ID?.trim();
+ const configuredStoreId =
+ process.env.WAFFO_STORE_ID?.trim() || undefined;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const configuredStoreId = process.env.WAFFO_STORE_ID?.trim(); | |
| if (configuredStoreId && !stores.some((s) => s.id === configuredStoreId)) { | |
| console.error( | |
| `WAFFO_STORE_ID ${configuredStoreId} is not visible to this API key.\n` + | |
| `Stores this key can see: ${stores.map((s) => `${s.id} (${s.name})`).join(", ") || "none"}`, | |
| ); | |
| process.exitCode = 1; | |
| return; | |
| } | |
| let storeId = | |
| configuredStoreId ?? | |
| stores.find((s) => s.name === "Murmur")?.id ?? | |
| stores[0]?.id; | |
| const configuredStoreId = | |
| process.env.WAFFO_STORE_ID?.trim() || undefined; | |
| if (configuredStoreId && !stores.some((s) => s.id === configuredStoreId)) { | |
| console.error( | |
| `WAFFO_STORE_ID ${configuredStoreId} is not visible to this API key.\n` + | |
| `Stores this key can see: ${stores.map((s) => `${s.id} (${s.name})`).join(", ") || "none"}`, | |
| ); | |
| process.exitCode = 1; | |
| return; | |
| } | |
| let storeId = | |
| configuredStoreId ?? | |
| stores.find((s) => s.name === "Murmur")?.id ?? | |
| stores[0]?.id; |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/waffo-bootstrap.ts` around lines 49 - 61, Update the
configuredStoreId initialization in the bootstrap store-selection flow to
normalize a trimmed empty WAFFO_STORE_ID to undefined, so the existing Murmur
and first-store fallbacks remain available. Preserve validation for non-empty
configured IDs and the subsequent storeId fallback order.
Why
Production is still transacting in Waffo test mode: the one succeeded purchase in the prod DB (
ORD_4fdgGMNYPwIXFrNczNYH15, $1.99 → 30 notes, 2026-07-17) istestMode: trueand lives in the unactivated storesym's store. The activated store is a different one —ptoq(STO_49I9cJTwgDLWcsk727gG7N,isLive: true, KYB succeeded,murmur.ptoq.io+hi@ptoq.ioverified) — and it currently has no product and no webhook.Provisioning that store needs a production API key and an explicit store id. Neither script could express that: both hardcoded
.env.local, andwaffo-bootstrappicked its store by name with astores[0]fallback.What changed
WAFFO_ENV_FILEselects the credential file for both scripts (default.env.local,override: trueso an explicitly named file wins over an already-exported test value).waffo-bootstraphonoursWAFFO_STORE_IDand aborts when that id is invisible to the key in use, listing what the key can see. A test key cannot provision the live store's production catalogue; failing loudly beats creating a stray duplicate product.waffo-webhook-registerechoes the env file, store id andtestModeit registered with — a test-mode registration is now obvious in the output.No runtime/product code touched; these are operator scripts only.
Go-live sequence (needs a production API key, dashboard-only step)
then repoint the Vercel production
WAFFO_*vars at the live store/product/key and redeploy.🤖 Generated with Claude Code