Skip to content

chore(waffo): let the provisioning scripts target the live store - #476

Open
moapacha wants to merge 1 commit into
mainfrom
claude/waffo-live-mode-scripts
Open

chore(waffo): let the provisioning scripts target the live store#476
moapacha wants to merge 1 commit into
mainfrom
claude/waffo-live-mode-scripts

Conversation

@moapacha

@moapacha moapacha commented Aug 6, 2026

Copy link
Copy Markdown
Member

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) is testMode: true and lives in the unactivated store sym's store. The activated store is a different one — ptoq (STO_49I9cJTwgDLWcsk727gG7N, isLive: true, KYB succeeded, murmur.ptoq.io + hi@ptoq.io verified) — 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, and waffo-bootstrap picked its store by name with a stores[0] fallback.

What changed

  • WAFFO_ENV_FILE selects the credential file for both scripts (default .env.local, override: true so an explicitly named file wins over an already-exported test value).
  • waffo-bootstrap honours WAFFO_STORE_ID and 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-register echoes the env file, store id and testMode it 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)

WAFFO_ENV_FILE=.env.waffo.prod bun run waffo:bootstrap
WAFFO_ENV_FILE=.env.waffo.prod WAFFO_WEBHOOK_TEST_MODE=0 bun run waffo:webhook-register

then repoint the Vercel production WAFFO_* vars at the live store/product/key and redeploy.

🤖 Generated with Claude Code

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>
@vercel

vercel Bot commented Aug 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
murmur Ready Ready Preview Aug 6, 2026 2:47pm

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

🔵 PR Size: size/XS

📊 Stats:

  • 34 additions
  • 7 deletions
  • 41 total changes
  • 2 files changed

This PR is tiny and quick to review.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The Waffo bootstrap and webhook registration scripts now support WAFFO_ENV_FILE. Bootstrap also validates optional WAFFO_STORE_ID values against visible stores and preserves fallback selection behavior. Webhook registration reports the selected environment file and store ID.

Changes

Waffo script configuration

Layer / File(s) Summary
Bootstrap configuration and store selection
scripts/waffo-bootstrap.ts
The bootstrap script documents production catalog provisioning, loads the selected dotenv file with override behavior, and validates WAFFO_STORE_ID before resource creation.
Webhook registration configuration and output
scripts/waffo-webhook-register.ts
The webhook registration script loads the selected dotenv file with override behavior and reports the environment file, store ID, test mode, and webhook URL.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested reviewers: jah-yee, koriyoshi2041

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description explains the change and rationale, but it omits the required checklist, Out of scope, Validation, and Reviewer focus sections. Add the missing template sections, complete the checklist, and document commands run, residual risk, out-of-scope items, and reviewer focus.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately identifies the main change: enabling provisioning scripts to target the live store.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch

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

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between ddddac2 and 78bb013.

📒 Files selected for processing (2)
  • scripts/waffo-bootstrap.ts
  • scripts/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

View job details

##[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

View job details

##[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.ts
  • scripts/waffo-webhook-register.ts
🔇 Additional comments (2)
scripts/waffo-webhook-register.ts (2)

2-12: LGTM!


45-47: LGTM!

Comment on lines +3 to +17
* 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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ 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.

Comment on lines +26 to +27
const envFile = process.env.WAFFO_ENV_FILE?.trim() || ".env.local";
loadEnv({ path: resolve(ROOT, envFile), override: true });

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ 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 || true

Repository: 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 so envFile, storeId, and testMode, 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.

Comment on lines +49 to +61
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;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ 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.

Suggested change
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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant