Keep existing payments working when new sales are off - #2020
Keep existing payments working when new sales are off#2020stefan-burke wants to merge 42 commits into
Conversation
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 15 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (16)
📝 WalkthroughWalkthroughThis change separates provider resolution for new sales from existing payments. It stores the last active provider, supports recovery while sales remain disabled, updates refunds and webhooks, adds recovery UI and domain guards, and documents payment-aggregate acceptance constraints. ChangesPayment provider state and existing-payment flows
Estimated code review effort: 4 (Complex) | ~60 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
✨ Simplify code
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 `@src/features/api/payment-processing/refunds.ts`:
- Around line 40-50: Define and export a shared ExistingPaymentProviderResult
type from `#shared/payments.ts`, then update getPaymentProviderOrLog in
src/features/api/payment-processing/refunds.ts#L40-L50 to use it instead of the
inline Awaited<ReturnType<...>> expression. Also update authenticateWebhook in
src/features/api/webhooks.ts#L321-L329 to use
NonNullable<ExistingPaymentProviderResult>, preserving its existing non-nullable
return contract.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: beec80eb-fa11-41a1-a2b5-fac7fdeca1e3
📒 Files selected for processing (18)
TODO.mddocs/payment-aggregate-acceptance.mdscripts/mutation/equivalent-mutants/shared-m-z.txtsrc/features/admin/require-provider.tssrc/features/api/payment-processing/classify.tssrc/features/api/payment-processing/refunds.tssrc/features/api/webhooks.tssrc/features/settings-bundles.tssrc/shared/db/settings.tssrc/shared/payments.tssrc/shared/settings/keys.tssrc/shared/settings/registry.tstest/integration/server/payments/sales-off-safety.test.tstest/integration/server/webhooks/refund-skip-conditions.test.tstest/shared/db/settings/public-api.test.tstest/shared/payments.test.tstest/shared/settings/keys.test.tstest/shared/settings/registry.test.ts
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2e4f452de1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Switching new sales off (saving the payment provider as "none") used to strand every payment already captured: refunds, replayed callbacks, redirect completion, the cancel page, and operator refunds all resolved the provider through the new-sales gate, so they broke the moment a buyer could no longer start a checkout -- even though the provider's credentials stay stored. Separate the two questions. New sales keep using getActivePaymentProvider / isPaymentsEnabled. Refunds, provider reconciliation, replayed callbacks, and completion of already-started payment work use a new resolver, getPaymentProviderForExistingPayments, which falls back to the last provider the operator activated when new sales are off. That provider is remembered in a new last_active_payment_provider setting, captured when a provider is switched on and again when new sales are switched off (a second "none" save keeps it). The seven accepted safety rules the payment aggregate must satisfy -- including the owner-review, queued owner email, and aggregate-activation behaviour not yet on main -- are recorded as acceptance constraints in docs/payment-aggregate-acceptance.md, not built ahead of their time. Regression tests cover each path: a captured payment refunded while sales are off, an in-flight payment completing and issuing the ticket, a handled failure replaying on a redelivered callback, and an operator refunding an existing paid booking -- all written to fail before the fix and pass after.
2e4f452 to
dc137e9
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: dc137e955d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
CodeRabbit (CHANGES_REQUESTED): export a named ExistingPaymentProvider type from #shared/payments.ts and use it in place of the duplicated Awaited<ReturnType<typeof getPaymentProviderForExistingPayments>> expression in getPaymentProviderOrLog and authenticateWebhook. Codex P2: persist PAYMENT_PROVIDER and LAST_ACTIVE_PAYMENT_PROVIDER in one writeRawBatch transaction (mirroring the existing Stripe activation path), so a failure between the two writes cannot leave new sales enabled against a stale remembered provider. The snapshot mirrors the committed values only after the batch succeeds. A second 'none' save keeps the remembered provider. Codex P1 (per-charge provider) and P1 (pre-existing none sites): recorded as known gaps in docs/payment-aggregate-acceptance.md and TODO.md rather than implemented here — per-charge provider tracking is the reference a charge lives in and is future aggregate work; a site already on 'none' with no recorded last-active provider is not regressed by this PR and recovers via a one-click provider re-select.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bc4a6dc84b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
TODO.md (2)
34-35: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winFix the Markdown reference to PR
#1995.Line 35 starts with
#1995.. This triggers MD018 and renders as a malformed heading. Keep the reference in the sentence, such asshipped on PR#1995..🤖 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 `@TODO.md` around lines 34 - 35, Update the Finding 1 sentence in TODO.md so the PR reference remains inline, ensuring it uses “PR `#1995`” rather than starting the line with “#1995.” and triggering MD018.Source: Linters/SAST tools
25-32: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winReplace local scan references with durable references.
The TODO records an absolute
/home/user/...path and local worktree names. These values are not available to other contributors and will become stale. Use stable ticket, PR, or repository-relative references.🤖 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 `@TODO.md` around lines 25 - 32, Update the TODO entry describing Findings 2 and 4 to remove the absolute local scan path and local worktree names, replacing them with durable ticket, pull-request, or repository-relative references while preserving the findings’ descriptions.
🤖 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 `@src/shared/db/settings.ts`:
- Around line 464-480: Update setPaymentProviderNone so keepLastActive is
derived from the current database state or the provider transition is
serialized, preventing a concurrent activation from persisting a stale
LAST_ACTIVE_PAYMENT_PROVIDER alongside payment_provider = "none". Preserve the
behavior of retaining the last active provider on repeated disable operations,
and add a regression test covering the disable/activation interleaving.
In `@test/integration/server/payments/sales-off-safety.test.ts`:
- Around line 93-125: Replace the manual try/finally disposal at
test/integration/server/payments/sales-off-safety.test.ts lines 93-125 and lines
195-207 with using declarations for the stub results: use using mockVerify for
the verifyWebhookSignature stub and using mockRefund for the refund stub, then
keep each test body directly after its declaration and remove the corresponding
restore calls and try/finally wrappers.
In `@TODO.md`:
- Around line 492-494: The existing-payment guarantee is too broad because
fallback does not track the provider that captured each charge. In TODO.md lines
492-494 and docs/payment-aggregate-acceptance.md lines 21-25, replace the
unconditional claim with wording that guarantees recovery only for payments
captured by the remembered provider, while explicitly retaining the per-charge
provider identity gap.
- Around line 513-516: Update the payment persistence and dispatch flow so each
payment charge retains its capture-time provider using the existing
payment_charges.provider and reference_index fields, rather than storing
provider identity only on processed_payments. Backfill legacy charges only when
capture-time evidence identifies one unambiguous provider; mark unresolved
charges non-dispatchable and expose them for operator review, then dispatch
existing-payment work from each charge’s provider instead of a global fallback.
---
Outside diff comments:
In `@TODO.md`:
- Around line 34-35: Update the Finding 1 sentence in TODO.md so the PR
reference remains inline, ensuring it uses “PR `#1995`” rather than starting the
line with “#1995.” and triggering MD018.
- Around line 25-32: Update the TODO entry describing Findings 2 and 4 to remove
the absolute local scan path and local worktree names, replacing them with
durable ticket, pull-request, or repository-relative references while preserving
the findings’ descriptions.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: ee66fda4-586e-4c45-8d73-c697b958b976
📒 Files selected for processing (18)
TODO.mddocs/payment-aggregate-acceptance.mdscripts/mutation/equivalent-mutants/shared-m-z.txtsrc/features/admin/require-provider.tssrc/features/api/payment-processing/classify.tssrc/features/api/payment-processing/refunds.tssrc/features/api/webhooks.tssrc/features/settings-bundles.tssrc/shared/db/settings.tssrc/shared/payments.tssrc/shared/settings/keys.tssrc/shared/settings/registry.tstest/integration/server/payments/sales-off-safety.test.tstest/integration/server/webhooks/refund-skip-conditions.test.tstest/shared/db/settings/public-api.test.tstest/shared/payments.test.tstest/shared/settings/keys.test.tstest/shared/settings/registry.test.ts
The shared type refactor shifted the payments.ts ?? equivalent from line 379 to 387; record the same equivalent in settings.ts:471 (data.payment_provider ?? "" — a provider type or null, never falsy-but-non-null).
CodeRabbit: tighten 'never stranded' to 'payments captured by that provider stay refundable and completable' in the acceptance doc and TODO, since the fallback only resolves the remembered provider (not per-charge). CodeRabbit: replace manual try/finally stub disposal with using declarations in sales-off-safety.test.ts (the established pattern in test/integration/server/webhooks/).
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3fbb3d6d9a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Codex: throw on a corrupt non-empty last_active_payment_provider value (offensive programming — a stored garbage string is surfaced at read time rather than silently treated as null). Covered by a regression test. Codex: paymentDashboardUrl and the domain-change webhook warning both read settings.paymentProvider (the new-sales gate) and returned null when sales were off, hiding dashboard links and the domain-change warning for existing payments. Both now fall back to settings.lastActivePaymentProvider. Remove the broken CODEX_SECURITY_PYTHON export from flake.nix — the codexSecurityPython variable was never defined (landed on main in commit 09e47fd), breaking nix develop and every nix-wrapped check runner.
Pre-existing none sites: the resolver now falls back to the sole provider with stored credentials when exactly one is configured (unambiguous evidence). When zero or multiple providers have credentials, it returns null (genuine ambiguity — operator must re-select, no guessing). Concurrency race: setPaymentProviderNone now reads the current provider from the database via a SQL subquery inside the batch statement (not from the request-start snapshot), so a concurrent activation landing before the batch is correctly reflected. Uses a single INSERT OR REPLACE ... SELECT that evaluates subqueries against pre-statement state, making read and write atomic without withTransaction's cache invalidation (which resets the session private key). Regression tests: single-credential recovery, multi-credential no-guess, sumup sole-credential, concurrency race (stale snapshot vs DB state). Raw-cache mirroring assertions kill the syncStoredSetting removal mutant. Mirror-located tests added for require-provider, refunds, webhooks, settings-page, custom-domain, subdomain.
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/shared/db/settings/raw-writes.ts (1)
1-1: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winExport
syncWrittenBatchand reuse it insetPaymentProviderNoneto fix the doc comment and remove duplicated cache-sync logic. The comment onsyncWrittenBatchclaims it is "Shared by every batch write path," butsetPaymentProviderNonebypasses it, manually callingsyncStoredSettingtwice with the same key/value-mirroring logic thatsyncWrittenBatchalready implements in onesyncCachecall.
src/shared/db/settings/raw-writes.ts#L95-105: exportsyncWrittenBatch, or correct the comment to state it is shared only bywriteRawBatch-based paths.src/shared/db/settings.ts#L507-512: once known values are available (after the write completes), callsyncWrittenBatch([[CONFIG_KEYS.PAYMENT_PROVIDER, "none"], [CONFIG_KEYS.LAST_ACTIVE_PAYMENT_PROVIDER, lastActive]])instead of two separatesyncStoredSettingcalls.🤖 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 `@src/shared/db/settings/raw-writes.ts` at line 1, The syncWrittenBatch helper’s documented shared usage is incomplete and setPaymentProviderNone duplicates its cache synchronization. Export syncWrittenBatch from raw-writes.ts, then update setPaymentProviderNone to call it after the write completes with both payment-provider key/value pairs, replacing the two syncStoredSetting calls.test/shared/db/settings/public-api.test.ts (1)
133-141: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winReload after the second
nonesave.This test only checks the current snapshot. A second
setPaymentProviderNone()call could clear the stored remembered provider while this assertion still passes.Invalidate the cache, reload
CONFIG_KEYS.LAST_ACTIVE_PAYMENT_PROVIDER, and assert that the value remains"stripe".Proposed test extension
await settings.update.setPaymentProviderNone(); await settings.update.setPaymentProviderNone(); expect(settings.paymentProvider).toBeNull(); expect(settings.lastActivePaymentProvider).toBe("stripe"); + + settings.invalidateCache(); + await settings.loadKeys([CONFIG_KEYS.LAST_ACTIVE_PAYMENT_PROVIDER]); + expect(settings.lastActivePaymentProvider).toBe("stripe");As per coding guidelines, “Every bug fix must include a regression test that reproduces the exact defect and fails before the fix.”
🤖 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 `@test/shared/db/settings/public-api.test.ts` around lines 133 - 141, The test “a second none save keeps the remembered provider” only verifies the in-memory snapshot; invalidate the settings cache after the second setPaymentProviderNone() call, reload CONFIG_KEYS.LAST_ACTIVE_PAYMENT_PROVIDER, and assert the persisted value remains "stripe" alongside the existing assertions.Source: Coding guidelines
🤖 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/mutation/equivalent-mutants/shared-m-z.txt`:
- Around line 29-33: Remove the three ?? → || entries for custom-domain.tsx and
subdomain.tsx from the equivalent-mutant list, since empty-string
paymentProvider values make them behaviorally different. Correct the
accompanying falsy-value statement so it does not claim that "none" is falsy; do
not narrow the state type or alter advancedDefaultState unless choosing that
alternative instead.
In `@src/shared/db/settings.ts`:
- Around line 473-516: Update setPaymentProviderNone to use
executeBatchWithResults, add RETURNING key, value to the INSERT statement, and
extract the returned last_active_payment_provider row instead of calling
requireOne. Protect the subsequent syncStoredSetting calls from a concurrent
activation so this operation cannot overwrite newer cached provider state with
the stale "none" state; use the existing cache synchronization mechanism.
In `@src/shared/payment-dashboard.ts`:
- Around line 33-36: Add a regression test for paymentDashboardUrl that sets
payment_provider to null and last_active_payment_provider to "stripe", then
asserts paymentDashboardUrl("pi_123") returns the expected Stripe dashboard URL.
Place it alongside the existing dashboard tests and preserve the current
direct-provider cases.
---
Outside diff comments:
In `@src/shared/db/settings/raw-writes.ts`:
- Line 1: The syncWrittenBatch helper’s documented shared usage is incomplete
and setPaymentProviderNone duplicates its cache synchronization. Export
syncWrittenBatch from raw-writes.ts, then update setPaymentProviderNone to call
it after the write completes with both payment-provider key/value pairs,
replacing the two syncStoredSetting calls.
In `@test/shared/db/settings/public-api.test.ts`:
- Around line 133-141: The test “a second none save keeps the remembered
provider” only verifies the in-memory snapshot; invalidate the settings cache
after the second setPaymentProviderNone() call, reload
CONFIG_KEYS.LAST_ACTIVE_PAYMENT_PROVIDER, and assert the persisted value remains
"stripe" alongside the existing assertions.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: bd6eada2-ebfb-4da1-a0da-abcec4751031
📒 Files selected for processing (26)
TODO.mddocs/payment-aggregate-acceptance.mdflake.nixscripts/mutation/equivalent-mutants/shared-db.txtscripts/mutation/equivalent-mutants/shared-m-z.txtsrc/features/admin/settings-page.tssrc/shared/db/settings.tssrc/shared/db/settings/raw-writes.tssrc/shared/payment-dashboard.tssrc/shared/payments.tssrc/ui/templates/admin/settings-advanced.tsxsrc/ui/templates/admin/settings.tsxsrc/ui/templates/admin/settings/custom-domain.tsxsrc/ui/templates/admin/settings/subdomain.tsxtest/features/admin/require-provider.test.tstest/features/admin/settings-page/last-active-provider.test.tstest/features/api/payment-processing/refunds.test.tstest/features/api/webhooks.test.tstest/integration/server/payments/sales-off-safety.test.tstest/integration/server/webhooks/refund-skip-conditions.test.tstest/shared/db/settings/public-api.test.tstest/shared/payments.test.tstest/ui/templates/admin/settings-advanced/state.tstest/ui/templates/admin/settings-state.tstest/ui/templates/admin/settings/custom-domain.test.tstest/ui/templates/admin/settings/subdomain.test.ts
💤 Files with no reviewable changes (1)
- flake.nix
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5345a26401
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Finding (1): Replace the lagging-replica readOne after the INSERT...SELECT with RETURNING value — the computed last_active is read from the write's own batch result, never from a replica. Finding (2): Unify paymentDashboardUrl and settings-page.ts on the shared existingPaymentProviderType() from payments.ts — one provider-resolution mechanism, no duplicate credential scans. Templates restored to main (untouched); the advanced settings-page state supplies the resolved provider via s.paymentProvider, so DomainPaymentWebhookWarning sees it without template changes. Finding (3): Remove the invalid shared-db equivalent entry for none->empty. Finding (4): Remove the invalid UI ??->|| equivalent entries (string|null). Finding (6): Document INSERT...SELECT (not withTransaction) in TODO.md. Template files (.tsx) reverted to main to reduce mutation scope. Two settings-state test fixtures reverted to match.
…tActive
Replace rawWritesApi + manual branch checks + results[0]! with a single
valibot tupleWithRest schema that validates the full batch result shape:
exactly one result set with exactly one {value: string} row, plus any
remaining result sets. v.parse(results)[0].rows[0].value is fully
type-safe — no local invalid-shape branches, no non-null assertions, no
test-only exports.
Restore distinct lastActivePaymentProvider in template state (not
overloaded into paymentProvider which controls the sales radio).
Templates use s.paymentProvider ?? s.lastActivePaymentProvider so the
domain-change warning shows when sales are off while the radio stays
'none'. Template test fixtures and types updated to match.
Remove all jscpd:ignore markers outside import blocks; extract shared
test helpers (log-spy, webhook-verify-helpers, withRefundRedirect).
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 17a9483505
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Actionable comments posted: 7
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/shared/db/settings.ts (1)
250-260: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winKeep provider selection in one atomic path.
lastActivePaymentProvidercorrectly maps""tonulland throws for unsupported values. Square and SumUp use the shared setter, but Stripeactivate()writesPAYMENT_PROVIDERbefore the shared setter writesLAST_ACTIVE_PAYMENT_PROVIDER. Include both keys in one atomic activation path.🤖 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 `@src/shared/db/settings.ts` around lines 250 - 260, The Stripe activation flow must update PAYMENT_PROVIDER and LAST_ACTIVE_PAYMENT_PROVIDER atomically. Modify Stripe’s activate() path to use the shared setter or atomic mechanism that writes both settings together, removing the separate PAYMENT_PROVIDER write while preserving lastActivePaymentProvider’s empty-value and validation behavior.
🤖 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 `@test/features/api/webhooks.test.ts`:
- Around line 33-36: Update the “rejects a success callback with only bad token
params” test to store the response text and assert it contains the specific
invalid-payment-callback message used by the sibling test, replacing the
non-empty-length assertion.
In `@test/shared/db/settings/raw-writes.test.ts`:
- Around line 66-79: Add a negative test alongside the existing
“executeSettingsBatchReturningValue” test that exercises a RETURNING result with
zero or multiple rows and asserts the validation rejects it. Cover the newly
added batchReturningValue parse-rejection branch directly while preserving the
existing successful single-row test.
- Around line 33-37: Update the “throws on an empty batch” test callback to be
async and await the rejects assertion for writeRawBatch([]), ensuring the test
waits for and correctly reports the expected rejection.
In `@test/test-utils/log-spy.ts`:
- Around line 17-18: Remove the useDebugLogSpy re-export from this helper module
and update all callers to import it directly from its defining ./debug-log.ts
module; do not move or duplicate the implementation, and do not retain a
compatibility import path.
- Around line 20-22: Extract the duplicated call-matching logic from errorLogged
and debugLogged into one private logLogged helper that accepts the spy and
needle, preserves the explicit boolean return type, and has both exported
functions delegate to it without changing behavior.
In `@test/test-utils/webhook-verify-helpers.ts`:
- Around line 9-23: The webhook test helper does not expose the HTTP status, so
the deleted-listing refund test cannot verify its promised 404 response. In
test/test-utils/webhook-verify-helpers.ts lines 9-23, update withWebhookVerify’s
assertions callback to receive res.status and pass it through; in
test/features/api/payment-processing/refunds.test.ts lines 164-182, update the
deleted-listing refund test callback to assert that status is 404 while
preserving the existing JSON assertion.
In `@test/ui/templates/admin/settings/custom-domain.test.ts`:
- Around line 19-20: Strengthen warning assertions in
test/ui/templates/admin/settings/custom-domain.test.ts:19-20 and
test/ui/templates/admin/settings/subdomain.test.ts:19-20 by asserting the
complete provider warning structure, including its linked provider settings
target. At test/ui/templates/admin/settings/custom-domain.test.ts:32 and
test/ui/templates/admin/settings/subdomain.test.ts:32, assert that both the
complete warning element and provider link are absent, using structural or exact
observable assertions rather than independent presence-only checks.
---
Outside diff comments:
In `@src/shared/db/settings.ts`:
- Around line 250-260: The Stripe activation flow must update PAYMENT_PROVIDER
and LAST_ACTIVE_PAYMENT_PROVIDER atomically. Modify Stripe’s activate() path to
use the shared setter or atomic mechanism that writes both settings together,
removing the separate PAYMENT_PROVIDER write while preserving
lastActivePaymentProvider’s empty-value and validation behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 5616ebe7-d126-4c16-86d4-71ab49e89259
📒 Files selected for processing (16)
TODO.mdscripts/mutation/equivalent-mutants/shared-m-z.txtsrc/features/admin/settings-page.tssrc/shared/db/client.tssrc/shared/db/settings.tssrc/shared/db/settings/raw-writes.tssrc/shared/payment-dashboard.tssrc/shared/payments.tssrc/ui/templates/admin/settings.tsxtest/features/api/payment-processing/refunds.test.tstest/features/api/webhooks.test.tstest/shared/db/settings/raw-writes.test.tstest/test-utils/log-spy.tstest/test-utils/webhook-verify-helpers.tstest/ui/templates/admin/settings/custom-domain.test.tstest/ui/templates/admin/settings/subdomain.test.ts
Add comprehensive render-snapshot tests for custom-domain.tsx and subdomain.tsx that assert every form field, action, label, CSS class, and i18n-rendered text — killing ~46 string-literal and operator mutants. Add a check-form test for subdomain.tsx covering the no-subdomain render path (type=text, muted, Check button, suffix). Remove stale equivalent-mutant entries: settings-page.ts:128:46 (line no longer has ??) and settings-bundles.ts:247:40 (superseded by 248:40 in shared-m-z.txt).
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 `@test/ui/templates/admin/settings/custom-domain.test.ts`:
- Around line 47-63: Strengthen the assertions at
test/ui/templates/admin/settings/custom-domain.test.ts:47-63 by matching the
custom_domain input value tickets.example.com and verifying it is associated
with the custom-domain form. In
test/ui/templates/admin/settings/subdomain.test.ts:47-63, assert the hidden
subdomain control contains my-sub and belongs to the registration form. In
test/ui/templates/admin/settings/subdomain.test.ts:76-79, bind the
availability-check input and its control to the check form, replacing
independent presence-only assertions with form-scoped observable checks.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: df80243a-a347-49a9-8b09-5debd683ebcf
📒 Files selected for processing (4)
scripts/mutation/equivalent-mutants/shared-a-l.txtscripts/mutation/equivalent-mutants/shared-m-z.txttest/ui/templates/admin/settings/custom-domain.test.tstest/ui/templates/admin/settings/subdomain.test.ts
💤 Files with no reviewable changes (2)
- scripts/mutation/equivalent-mutants/shared-m-z.txt
- scripts/mutation/equivalent-mutants/shared-a-l.txt
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9c67112c19
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
refunds.ts (16/16 killed): direct unit tests for tryRefund, validationFailure, refuseMismatch, refundSpec, refundedNoteText — table-driven for REFUND_REASONS. webhooks.ts (22/47 killed): Square orderId redirect, 409 concurrent reservation, refunded-with-failed-refund, augmented log assertions. custom-domain.tsx (8/8 killed): CSS-class, whitespace, and ??→|| assertions via regex-based render checks. subdomain.tsx (15/15 killed): i18n keys, CSS classes, ??→||, &&→||, !→∅, false→true, value→ via register+check form assertions. raw-writes.ts (4/6 killed): recordSettingsLoaded and loaded.add removal via audit-wrapped assertions. Remaining 29 survivors: webhooks.ts complex processSessionAndRedirect paths (multi-token URLs, thank-you), raw-writes loaded.add (not read by getCachedRaw), client.ts false→true (transient-error retry).
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 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 `@test/features/api/payment-processing/refunds.test.ts`:
- Around line 314-322: Strengthen the non-404 case in the validationFailure test
by asserting an observable refund attempt outcome, not only refunded: false.
Reuse the existing errorLogged/errorSpy pattern for the unconfigured provider,
or configure a stub via stubStripeRefund and assert its specific result, so the
test distinguishes an attempted refund from skipping the non-404 branch.
In `@test/shared/db/settings/raw-writes.test.ts`:
- Around line 56-67: The test currently verifies only cache state and does not
confirm persisted deletion. Split the deletion behavior from the
audit-registration case, then in the focused `writeOrDelete` test invalidate the
cache, reload `CONFIG_KEYS.SQUARE_LOCATION_ID`, and assert
`settings.square.locationId` is empty while retaining the existing write/delete
setup.
In `@test/ui/templates/admin/settings/custom-domain.test.ts`:
- Around line 33-35: Remove the validation-action assertion from the
warning-suppression test and place it in the existing form-rendering test, or
create a dedicated test for it. Keep the current test focused exclusively on
verifying warning suppression, while preserving the validation action
expectation separately.
- Line 36: Replace the syntax-focused comments at
test/ui/templates/admin/settings/custom-domain.test.ts lines 36-36 and
test/ui/templates/admin/settings/subdomain.test.ts lines 33-34 with brief
behavior-focused statements that an empty configured provider suppresses the
warning; replace the comment at
test/ui/templates/admin/settings/subdomain.test.ts lines 44-45 with a brief
statement that the preview rendering path suppresses the warning.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 092d3bcf-ecdc-4709-9bf3-3fa7955060a5
📒 Files selected for processing (5)
test/features/api/payment-processing/refunds.test.tstest/features/api/webhooks.test.tstest/shared/db/settings/raw-writes.test.tstest/ui/templates/admin/settings/custom-domain.test.tstest/ui/templates/admin/settings/subdomain.test.ts
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b6dbcd7b09
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: aab800bcda
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 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 `@src/features/admin/settings-general.ts`:
- Around line 76-87: Declare an explicit shared handler return type for the
exported handlePaymentProviderRecoveryPost constant, applying it to the
settingsHandler result while preserving its existing extract, save, log, and
validate behavior.
In `@src/shared/existing-payment-provider.ts`:
- Line 32: Update the exported existingPaymentProviderApi.getStored function to
explicitly declare a PaymentProviderSetting | null return type, while preserving
its existing settings.paymentProviderSetting return behavior.
- Around line 55-62: Update the provider-selection flow around current,
remembered, and configured providers to load configured first and accept current
or remembered only when configured contains that provider; otherwise continue to
the single-provider or recovery-choice fallback. Add a regression test covering
a remembered provider with missing credentials, asserting it is not selected and
the appropriate null or recovery result is returned.
In `@test/features/api/webhooks/success-details.test.ts`:
- Around line 205-208: Review the setup around the raw update in the relevant
test and reuse an existing test-utils/db-helpers function for assigning an
attendee’s package_group_id if one exists. Replace the direct getDb().execute
call with that helper while preserving the same group.id and attendee.id values;
retain the raw SQL only if no suitable helper exists.
In `@test/ui/templates/admin/settings/custom-domain.test.ts`:
- Around line 43-56: Require each expected form or input match before inspecting
attributes: in test/ui/templates/admin/settings/custom-domain.test.ts lines
43-56, assert the custom-domain form match is not null and return early if
needed, then require its custom_domain input similarly; apply the same pattern
to the recovery form in
test/features/admin/settings-page/last-active-provider.test.ts lines 43-53, the
registration form and hidden subdomain input in
test/ui/templates/admin/settings/subdomain.test.ts lines 60-67, and the
availability-check form and text input in
test/ui/templates/admin/settings/subdomain.test.ts lines 91-99. Replace optional
`?.[0]` access for these required elements with strong assertions and early
returns for type narrowing.
In `@test/ui/templates/admin/settings/payment.test.ts`:
- Around line 119-125: Add direct tests alongside the existing Stripe
availability test for SquareForm and SumUpForm, using matching
existingPaymentProvider values with paymentProvider set to null. Assert the
rendered HTML contains id="settings-square" and id="settings-sumup" to cover
both existing-provider visibility branches.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: bb9cd672-da9a-4e30-bcd4-6ddb74c5d5ca
📒 Files selected for processing (38)
TODO.mddocs/payment-aggregate-acceptance.mdscripts/mutation/equivalent-mutants/features.txtscripts/mutation/equivalent-mutants/shared-m-z.txtsrc/features/admin/settings-general.tssrc/features/admin/settings-page.tssrc/features/admin/settings.tssrc/locales/en/settings.jsonsrc/shared/db/settings.tssrc/shared/db/settings/raw-writes.tssrc/shared/existing-payment-provider.tssrc/shared/payment-dashboard.tssrc/shared/payments.tssrc/ui/templates/admin/settings-advanced.tsxsrc/ui/templates/admin/settings.tsxsrc/ui/templates/admin/settings/custom-domain.tsxsrc/ui/templates/admin/settings/payment.tsxsrc/ui/templates/admin/settings/subdomain.tsxsrc/ui/templates/components/radio-option.tsxtest/features/admin/settings-general/payment-provider.test.tstest/features/admin/settings-page/last-active-provider.test.tstest/features/api/payment-processing/refunds.test.tstest/features/api/webhooks/callbacks.test.tstest/features/api/webhooks/helpers.tstest/features/api/webhooks/provider.test.tstest/features/api/webhooks/success-details.test.tstest/integration/server/webhooks/refund-skip-conditions.test.tstest/shared/db/settings/raw-writes.test.tstest/shared/payment-dashboard.test.tstest/shared/payments.test.tstest/test-utils/debug-log.tstest/test-utils/webhook-verify-helpers.tstest/ui/templates/admin/settings-advanced/page.test.tstest/ui/templates/admin/settings-advanced/state.tstest/ui/templates/admin/settings-state.tstest/ui/templates/admin/settings/custom-domain.test.tstest/ui/templates/admin/settings/payment.test.tstest/ui/templates/admin/settings/subdomain.test.ts
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 704933bc1e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cd669d095d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/shared/db/settings.ts (1)
487-497: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick winAlias the
settingsreads.Line 491 and Line 495 read
settingswithoutASaliases. Use distinct descriptive singular aliases for the current-provider and remembered-provider reads, then qualifyvalue.As per coding guidelines, “Alias SQL tables with descriptive full singular words using
AS.”🤖 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 `@src/shared/db/settings.ts` around lines 487 - 497, Update the SQL in the settings migration to alias both settings subqueries with distinct descriptive singular aliases using AS: one for the current payment provider and one for the remembered provider. Qualify each referenced value column with its corresponding alias while preserving the existing provider validation and fallback behavior.Source: Coding guidelines
🤖 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 `@src/features/admin/settings-general.ts`:
- Around line 77-87: Update settingsHandler’s validation contract to return the
parsed PaymentProviderSchema value, and modify handlePaymentProviderRecoveryPost
so its validate callback returns that validated PaymentProviderType. Pass the
validated value directly to settings.update.recoverPaymentProvider, removing the
existing `as PaymentProviderType` cast while preserving the invalid-input error
path.
In `@src/locales/en/settings.json`:
- Line 24: Update the success.existing_payment_provider_set locale string to end
with a period, preserving the existing message text and placeholder.
In `@src/ui/templates/admin/settings/payment-provider.tsx`:
- Line 80: Preserve the submitted recovery provider when recovery validation
fails: extend SettingsPageState on the failure path with the submitted provider,
and update the recovery-provider radio rendering to derive checked from that
state instead of hardcoding false. Add a direct regression test covering the
failed recovery POST and confirming the submitted provider remains selected.
In `@test/features/admin/settings-general/payment-provider.test.ts`:
- Around line 143-155: Update the stale recovery scenario in the “rejects a
stale recovery post after sales were enabled” test to expect an error explicitly
stating that recovery is unavailable after sales are enabled, rather than the
missing-credentials message. Preserve the rejected POST behavior and the
existing paymentProvider and lastActivePaymentProvider assertions.
---
Outside diff comments:
In `@src/shared/db/settings.ts`:
- Around line 487-497: Update the SQL in the settings migration to alias both
settings subqueries with distinct descriptive singular aliases using AS: one for
the current payment provider and one for the remembered provider. Qualify each
referenced value column with its corresponding alias while preserving the
existing provider validation and fallback behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 2e376587-42fe-4c22-aca6-a35335ec5c61
📒 Files selected for processing (38)
scripts/screenshots/app-server.tssrc/features/admin/require-provider.tssrc/features/admin/settings-domains.tssrc/features/admin/settings-general.tssrc/features/admin/settings-helpers.tssrc/features/admin/settings-page.tssrc/features/admin/settings-stripe.tssrc/features/settings-bundles.tssrc/locales/en/settings.jsonsrc/shared/db/settings.tssrc/shared/existing-payment-provider.tssrc/ui/templates/admin/settings-advanced.tsxsrc/ui/templates/admin/settings.tsxsrc/ui/templates/admin/settings/custom-domain.tsxsrc/ui/templates/admin/settings/domain-payment-warning.tsxsrc/ui/templates/admin/settings/payment-provider.tsxsrc/ui/templates/admin/settings/payment.tsxsrc/ui/templates/admin/settings/subdomain.tsxsrc/ui/templates/components/actions.tsxtest/features/admin/require-provider.test.tstest/features/admin/settings-general/payment-provider.test.tstest/features/admin/settings-page/last-active-provider.test.tstest/features/admin/settings-stripe.test.tstest/integration/server/settings/domains.test.tstest/integration/server/webhooks/refund-skip-conditions.test.tstest/shared/db/settings/public-api.test.tstest/shared/db/settings/stripe-credentials.test.tstest/shared/existing-payment-provider.test.tstest/shared/payment-dashboard.test.tstest/shared/payments.test.tstest/shared/stripe/endpoints.test.tstest/test-utils/refund-routes.tstest/test-utils/settings.tstest/ui/templates/admin/settings-advanced/state.tstest/ui/templates/admin/settings/custom-domain.test.tstest/ui/templates/admin/settings/domain-payment-warning.test.tsxtest/ui/templates/admin/settings/payment.test.tstest/ui/templates/admin/settings/subdomain.test.ts
💤 Files with no reviewable changes (1)
- src/ui/templates/admin/settings/payment.tsx
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a8f275d162
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6df7bd427a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 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 `@specs/payments/payment-provider-choice.feature`:
- Around line 45-57: The scenario is asserting registration availability while
only checking the host subdomain. Update the scenario step for “mylisting” to
use the registration action with save: "1" after each provider-recovery state,
or change the assertions to validate availability instead; preserve the
recovery-dependent behavior being tested.
In `@test/features/admin/settings-domains/custom-validate.test.ts`:
- Around line 158-174: Update the catch block in the “clears the task when
validation throws” test to assert that the captured error is the expected
network failure, rather than swallowing it; keep the finally block restoring
bunnyCdnApi.validateCustomDomain and preserve the settings.currentTask
assertion.
In `@test/features/admin/settings-domains/support.ts`:
- Line 10: Remove the setAmbiguousPaymentProvider alias: in
test/features/admin/settings-domains/support.ts:10-10, re-export
requirePaymentProviderRecovery directly; in
test/features/admin/settings-domains/custom-save.test.ts:7-7, import and call
requirePaymentProviderRecovery at line 38; and in
test/features/admin/settings-domains/host-subdomain.test.ts:10-10, import and
call requirePaymentProviderRecovery at line 179.
- Around line 82-86: Update the exported subdomainCheck function with an
explicit return type, using an existing named interface or shared type from the
file when available; otherwise define a concise named type for its available,
fullDomain, and ok fields, while preserving the current return values.
In `@test/specs/steps/payment-provider-choice.ts`:
- Around line 161-177: Update the step definition “the organiser must choose the
provider for existing payments” so each required radio input is validated by
independently extracting or checking its full input tag, then asserting name,
required, and value separately. Remove the order-dependent combined regexes
while preserving the existing Stripe and Square value checks.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 4d18e108-7357-454f-9737-bacf2a083a85
📒 Files selected for processing (19)
scripts/mutation/equivalent-mutants/features.txtscripts/mutation/equivalent-mutants/shared-m-z.txtspecs/payments/payment-provider-choice.featuretest/features/admin/settings-domains/custom-page.test.tstest/features/admin/settings-domains/custom-save.test.tstest/features/admin/settings-domains/custom-validate.test.tstest/features/admin/settings-domains/host-subdomain.test.tstest/features/admin/settings-domains/support.tstest/features/admin/settings-helpers/provider-credentials.test.tstest/features/admin/settings-helpers/secret.test.tstest/features/admin/settings-stripe.test.tstest/integration/server/settings/domains.test.tstest/scripts/mutation/isolation/copy-back.test.tstest/specs/steps/payment-provider-choice.tstest/test-utils/settings.tstest/ui/templates/admin/settings/domain-payment-warning.test.tsxtest/ui/templates/admin/settings/payment-provider.test.tsxtest/ui/templates/admin/settings/payment.test.tstest/ui/templates/components/actions.test.ts
💤 Files with no reviewable changes (2)
- test/integration/server/settings/domains.test.ts
- test/ui/templates/admin/settings/payment.test.ts
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ff728d158d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/features/admin/settings-helpers.ts (1)
332-332: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDocument the
activateFromMissingsemantics.
hasSecretnow drives two behaviors: the "required" guard and theactivateFromMissingflag passed tosaveSecret. The comment onhasSecret(Line 332) andsaveSecret(Lines 351-357) does not explain thatactivateFromMissingsignals "no credentials existed before this save" and is used to decide whether to auto-activate the provider. This is not obvious from the parameter name alone, and misuse affects whether a payment provider goes live unexpectedly.📝 Proposed comment clarification
- /** Whether a secret is already stored (drives the "required" guard). */ + /** Whether a secret is already stored. Drives the "required" guard and + * `activateFromMissing` (true when no secret existed before this save; + * callers use it to auto-activate the provider only on first setup). */ hasSecret: () => boolean;Also applies to: 351-357
🤖 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 `@src/features/admin/settings-helpers.ts` at line 332, Document the `hasSecret` contract and the `saveSecret` parameter so they explicitly state that a false prior credential state produces `activateFromMissing`, meaning no credentials existed before the save and the provider may be auto-activated. Clarify how this value relates to the required guard and prevent ambiguity about provider activation behavior.
🤖 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.
Outside diff comments:
In `@src/features/admin/settings-helpers.ts`:
- Line 332: Document the `hasSecret` contract and the `saveSecret` parameter so
they explicitly state that a false prior credential state produces
`activateFromMissing`, meaning no credentials existed before the save and the
provider may be auto-activated. Clarify how this value relates to the required
guard and prevent ambiguity about provider activation behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 89043aca-853d-4c23-a5d0-16beb1f4e623
📒 Files selected for processing (21)
scripts/screenshots/app-server.tssrc/features/admin/settings-general.tssrc/features/admin/settings-helpers.tssrc/features/admin/settings-stripe.tssrc/locales/en/settings.jsonsrc/shared/db/settings.tssrc/ui/templates/admin/settings.tsxsrc/ui/templates/admin/settings/payment-provider.tsxsrc/ui/templates/admin/settings/payment.tsxtest/features/admin/settings-domains/custom-save.test.tstest/features/admin/settings-domains/custom-validate.test.tstest/features/admin/settings-domains/host-subdomain.test.tstest/features/admin/settings-domains/support.tstest/features/admin/settings-general/payment-provider.test.tstest/features/admin/settings-helpers/provider-credentials.test.tstest/shared/db/settings/public-api.test.tstest/shared/db/settings/stripe-credentials.test.tstest/shared/stripe/endpoints.test.tstest/specs/steps/payment-provider-choice.tstest/test-utils/settings.tstest/ui/templates/admin/settings/payment-provider.test.tsx
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 862bdd0f15
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
test/features/admin/settings-general/payment-provider.test.ts (1)
109-127: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick winAssert the recovery activity log.
The successful recovery test does not verify the new activity-log behavior. A mutation that removes or changes
handlePaymentProviderRecoveryPost.logcan pass this test.Read
getAllActivityLog()after the POST. Assert that it containsExisting payment provider set to Stripe.As per coding guidelines, “Maintain 100% coverage and mutation kill rate for changed source” and tests must use strong observable assertions.
🤖 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 `@test/features/admin/settings-general/payment-provider.test.ts` around lines 109 - 127, Update the successful recovery test around the POST to read getAllActivityLog() and assert it contains “Existing payment provider set to Stripe.”, while preserving the existing response, settings, and redirect assertions.Source: Coding guidelines
🤖 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 `@test/test-utils/csrf.ts`:
- Around line 27-29: Remove the local inputTagWithValue definitions from
payment.test.ts and csrf-and-forms.test.ts, import the shared inputTagWithValue
helper from test/test-utils/csrf.ts, and update their usages to use that import.
- Around line 27-29: Update inputTagWithValue to regex-escape the value before
constructing the pattern, and require an attribute boundary before the value
attribute so similarly named attributes cannot match. Add an exact regression
test covering a metacharacter value such as a.b, while preserving complete
coverage of the changed utility.
---
Outside diff comments:
In `@test/features/admin/settings-general/payment-provider.test.ts`:
- Around line 109-127: Update the successful recovery test around the POST to
read getAllActivityLog() and assert it contains “Existing payment provider set
to Stripe.”, while preserving the existing response, settings, and redirect
assertions.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 5ae117fd-b81a-4b64-b206-f0c60f412280
📒 Files selected for processing (12)
scripts/mutation/equivalent-mutants/features.txtspecs/payments/payment-provider-choice.featuresrc/features/admin/settings-general.tssrc/shared/db/settings.tstest/features/admin/settings-general/payment-provider.test.tstest/features/admin/settings-stripe/provider-state.test.tstest/shared/db/settings/public-api.test.tstest/specs/steps/payment-provider-choice.tstest/test-utils/csrf-and-forms.test.tstest/test-utils/csrf.tstest/ui/templates/admin/settings/payment-provider.test.tsxtest/ui/templates/admin/settings/payment.test.ts
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bdefe2d718
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…safety-behavior # Conflicts: # flake.nix # test/shared/stripe/endpoints/cleanup.test.ts
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ff70865d8d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| import { | ||
| getActivePaymentProvider, | ||
| type ExistingPaymentProvider, | ||
| getPaymentProviderForExistingPayments, |
There was a problem hiding this comment.
Split the expanded webhook module below 400 lines
This refactor grows webhooks.ts from 458 to 462 lines, moving an already oversized module farther beyond the repository's approximately 400-line target. Extract the payment callback or webhook authentication/processing paths into focused modules so this central route file does not continue accumulating separate payment flows.
AGENTS.md reference: AGENTS.md:L82-L82
Useful? React with 👍 / 👎.
| /** Same as {@link executeBatchWithoutCacheInvalidation} but returns each | ||
| * statement's {@link ResultSet}, so an INSERT ... RETURNING can read the | ||
| * written value back from the write round-trip itself. */ | ||
| export const executeBatchReturningResults = async ( |
There was a problem hiding this comment.
Split the expanded database client below 400 lines
Adding this batch-returning API grows client.ts from 929 to 936 lines, more than twice the repository's approximately 400-line target. Move the batch execution helpers into a focused database-client module rather than extending this already overloaded client assembly.
AGENTS.md reference: AGENTS.md:L82-L82
Useful? React with 👍 / 👎.
|
|
||
| export const StripeForm = (s: SettingsPageState): JSX.Element | null => | ||
| s.paymentProvider === "stripe" ? ( | ||
| showsStripe(s) ? ( |
There was a problem hiding this comment.
Reconfigure Stripe when re-saving the remembered key
When sales are off with Stripe remembered, this newly exposes the Stripe form and the domain warning tells the operator to re-save the key after changing the domain. The rendered secret field contains the mask sentinel, however, so defineProviderCredentialsRoute returns the unchanged response at settings-helpers.ts:395-398 before saveSecret calls setupWebhookEndpoint; following the warning therefore leaves Stripe sending callbacks to the old domain. Re-run webhook setup with the stored key for this re-save action, or require the operator to enter the key again.
Useful? React with 👍 / 👎.
What changed
Turning off new sales now stops new checkouts without cutting off payment work that already exists.
Operator impact
An operator can pause new online sales and still refund or finish payments already in progress. If an older site has an unclear provider, the settings page asks for an explicit choice while keeping new sales off.
Known limitation
Each payment still stores only its provider reference, not the provider name. If a site took payments through more than one provider, older payments may still need per-payment provider tracking. That follow-up is recorded in
TODO.mdanddocs/payment-aggregate-acceptance.md.The requested splits for the oversized settings modules are also recorded in
TODO.md. They were not included here because this PR has a strict source-change limit.Verification
main: 606 additions + 134 deletions = 740 lines.deno task precommitpassed on0c4b76eacbefore merging currentmain.