Skip to content

Add Medusa PayKit payment providers - #406

Merged
redeyecz merged 30 commits into
masterfrom
feat/paykit_module
May 14, 2026
Merged

Add Medusa PayKit payment providers#406
redeyecz merged 30 commits into
masterfrom
feat/paykit_module

Conversation

@redeyecz

@redeyecz redeyecz commented May 13, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Add local Medusa v2 PayKit payment providers for GoPay, Stripe, and Comgate,
    including provider config, runtime client loading, amount normalization,
    provider metadata mapping, refund/capture/cancel handling, and webhook event
    mapping.
  • Add GoPay GET webhook bridge at /hooks/payment/paykit_gopay while keeping
    Stripe/Comgate on Medusa’s generic payment webhook route.
  • Add PayKit feature flags and provider env wiring for Docker/local config, plus
    PayKit SDK dependencies.
  • Add PayKit seed workflow and seedPaykit script for region payment provider
    setup.
  • Add focused unit coverage for PayKit base behavior, provider-specific amount
    handling, webhook mapping, runtime loading, and GoPay hook behavior.
  • Add initial storefront GoPay payment-session data payload with customer email,
    cart item id, manual capture, and cart metadata.

Summary by CodeRabbit

  • New Features

    • Added PayKit payment integrations: GoPay, Stripe and Comgate with webhook handling.
    • Seed workflow to populate region payment-provider associations.
  • Bug Fixes

    • Improved amount conversion and webhook amount normalisation across providers.
  • Chores

    • Added environment configuration flags for PayKit providers.
    • Bumped Medusa-related dependencies to 2.15.2 and updated CI/Docker settings.

Review Change Stack

@semanticdiff-com

semanticdiff-com Bot commented May 13, 2026

Copy link
Copy Markdown

Review changes with  SemanticDiff

Changed Files
File Status
  apps/medusa-be/vitest.config.ts  36% smaller
  .github/workflows/medusa-be-tests-after-ci.yml  22% smaller
  apps/medusa-be/package.json  21% smaller
  .env.docker Unsupported file format
  .mise.toml Unsupported file format
  apps/frontend-demo/package.json  0% smaller
  apps/medusa-be/medusa-config.ts  0% smaller
  apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts  0% smaller
  apps/medusa-be/src/modules/payment-paykit/README.md Unsupported file format
  apps/medusa-be/src/modules/payment-paykit/__tests__/amounts.unit.spec.ts  0% smaller
  apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts  0% smaller
  apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts  0% smaller
  apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts  0% smaller
  apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts  0% smaller
  apps/medusa-be/src/modules/payment-paykit/__tests__/medusa-config.unit.spec.ts  0% smaller
  apps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.ts  0% smaller
  apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts  0% smaller
  apps/medusa-be/src/modules/payment-paykit/config.ts  0% smaller
  apps/medusa-be/src/modules/payment-paykit/core/base.ts  0% smaller
  apps/medusa-be/src/modules/payment-paykit/medusa-config.ts  0% smaller
  apps/medusa-be/src/modules/payment-paykit/runtime.ts  0% smaller
  apps/medusa-be/src/modules/payment-paykit/services/comgate.ts  0% smaller
  apps/medusa-be/src/modules/payment-paykit/services/gopay.ts  0% smaller
  apps/medusa-be/src/modules/payment-paykit/services/stripe.ts  0% smaller
  apps/medusa-be/src/modules/payment-paykit/types/index.ts  0% smaller
  apps/medusa-be/src/modules/payment-paykit/utils/amounts.ts  0% smaller
  apps/medusa-be/src/modules/payment-paykit/utils/mappers.ts  0% smaller
  apps/medusa-be/src/modules/payment-paykit/webhooks.ts  0% smaller
  apps/medusa-be/src/scripts/seed-paykit.ts  0% smaller
  apps/medusa-be/src/workflows/seed/paykit-payment-providers.ts  0% smaller
  apps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.ts  0% smaller
  apps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.ts  0% smaller
  apps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.ts  0% smaller
  apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts  0% smaller
  apps/n1/package.json  0% smaller
  docker-compose.yaml  0% smaller
  docker/development/medusa-be/Dockerfile Unsupported file format
  docker/development/n1/Dockerfile Unsupported file format
  docker/development/payload/Dockerfile Unsupported file format
  libs/storefront-data/package.json  0% smaller
  package.json  0% smaller
  pnpm-lock.yaml Unsupported file format
  pnpm-workspace.yaml  0% smaller
  scripts/e2e/medusa-be-http.sh Unsupported file format

@vercel

vercel Bot commented May 13, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
new-engine-ui-storybook Ready Ready Preview, Comment May 14, 2026 10:18am

@blacksmith-sh

blacksmith-sh Bot commented May 13, 2026

Copy link
Copy Markdown

Blacksmith Account Suspended

This Blacksmith account requires additional verification. Jobs targeting Blacksmith runners will not be picked up and will remain queued until they timeout.

Please contact Blacksmith Support for assistance.

@coderabbitai

coderabbitai Bot commented May 13, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@redeyecz has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 14 minutes and 34 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 59313973-fe4b-4d6a-9b8a-632d9cca9e22

📥 Commits

Reviewing files that changed from the base of the PR and between 4066c82 and d10d15d.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (43)
  • .env.docker
  • .github/workflows/medusa-be-tests-after-ci.yml
  • .mise.toml
  • apps/frontend-demo/package.json
  • apps/medusa-be/medusa-config.ts
  • apps/medusa-be/package.json
  • apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts
  • apps/medusa-be/src/modules/payment-paykit/README.md
  • apps/medusa-be/src/modules/payment-paykit/__tests__/amounts.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/medusa-config.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/config.ts
  • apps/medusa-be/src/modules/payment-paykit/core/base.ts
  • apps/medusa-be/src/modules/payment-paykit/medusa-config.ts
  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
  • apps/medusa-be/src/modules/payment-paykit/services/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/services/gopay.ts
  • apps/medusa-be/src/modules/payment-paykit/services/stripe.ts
  • apps/medusa-be/src/modules/payment-paykit/types/index.ts
  • apps/medusa-be/src/modules/payment-paykit/utils/amounts.ts
  • apps/medusa-be/src/modules/payment-paykit/utils/mappers.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/scripts/seed-paykit.ts
  • apps/medusa-be/src/workflows/seed/paykit-payment-providers.ts
  • apps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.ts
  • apps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.ts
  • apps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.ts
  • apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts
  • apps/medusa-be/vitest.config.ts
  • apps/n1/package.json
  • docker-compose.yaml
  • docker/development/medusa-be/Dockerfile
  • docker/development/n1/Dockerfile
  • docker/development/payload/Dockerfile
  • libs/storefront-data/package.json
  • package.json
  • pnpm-workspace.yaml
  • scripts/e2e/medusa-be-http.sh

Walkthrough

Adds PayKit integrations (GoPay, Stripe, Comgate): env and dependency changes, Medusa wiring, types, runtime client, base provider, per-provider services, webhook emission/route, region seeding workflow, amount utilities, and tests.

Changes

PayKit Payment Provider Integration

Layer / File(s) Summary
Environment and Dependency Configuration
.env.docker, docker-compose.yaml, apps/medusa-be/medusa-config.ts, apps/medusa-be/package.json, apps/medusa-be/vitest.config.ts, docker/development/*/Dockerfile, .mise.toml, pnpm-workspace.yaml
PayKit feature flags and provider credentials added to environment configuration; Medusa backend configuration imports PayKit helpers and conditionally registers the payment module when providers are enabled; npm seedPaykit script added; Vitest root and test environment paths updated for CommonJS compatibility; Docker ci-dev and build stages set CI=true; Mise task for lockfile-free installs and release age exclusion list expanded.
Dependency Version Bumps
apps/medusa-be/package.json, apps/frontend-demo/package.json, apps/n1/package.json, libs/storefront-data/package.json, package.json
@medusajs/* packages bumped from 2.14.1 to 2.15.2 across backend, frontend demo, n1, and storefront data packages; peer dependency floors raised in storefront-data; Paykit SDK dependencies added for comgate, core, gopay, and stripe; plugin and test utility versions updated.
Type Definitions and Configuration Constants
apps/medusa-be/src/modules/payment-paykit/types/index.ts, apps/medusa-be/src/modules/payment-paykit/config.ts
Comprehensive PayKit type definitions for payments, customers, billing, providers, webhooks, and clients; exports provider identifiers and helper functions for feature flag checking and environment value parsing.
Currency Amount Conversion Utilities
apps/medusa-be/src/modules/payment-paykit/utils/amounts.ts
Defines zero-decimal and Stripe three-decimal currency sets; exports multiplier calculators and conversion functions for transforming between major units and smallest currency units with precision rounding.
Payment Provider Base Class
apps/medusa-be/src/modules/payment-paykit/core/base.ts
Abstract base class implementing full Medusa payment lifecycle (initiate, capture, refund, cancel, delete), account holder operations, lazy client initialisation, normalisation hooks for amounts and metadata, and webhook action routing with event filtering.
Runtime Client Factory and Option Mappers
apps/medusa-be/src/modules/payment-paykit/runtime.ts
Dynamically loads PayKit SDK and provider modules; instantiates provider-specific clients; maps Medusa provider options to PayKit format for GoPay/Stripe/Comgate; transforms and normalises webhook payloads including URL reconstruction.
Webhook Event Mapping and Routing
apps/medusa-be/src/modules/payment-paykit/utils/mappers.ts
Maps PayKit payment statuses to Medusa session states; extracts payment/session/amount from variable webhook payload shapes; determines webhook action from event type and status; conditionally includes data for processable actions.
Webhook Emission and GoPay Route Handler
apps/medusa-be/src/modules/payment-paykit/webhooks.ts, apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts
Webhook emitter resolves event bus and payment options, broadcasts events with configurable delay/retries; GoPay route reconstructs URLs from forwarded headers, validates payment ID, emits events, and handles errors gracefully.
GoPay Provider Implementation
apps/medusa-be/src/modules/payment-paykit/services/gopay.ts
Extends base provider; validates GoPay credentials; customises amount normalisation for smallest units on initiation and webhook processing; maps webhook amounts back to Medusa units.
Comgate Provider Implementation
apps/medusa-be/src/modules/payment-paykit/services/comgate.ts
Extends base provider; validates merchant/secret credentials; normalises amounts to smallest units; resolves and validates customer email from multiple sources; constructs provider metadata with configurable payment label.
Stripe Provider Implementation
apps/medusa-be/src/modules/payment-paykit/services/stripe.ts
Extends base provider; validates API key and webhook secret; customises Stripe amount normalisation including three-decimal currency handling; implements webhook fallback parsing for unhandled payment_intent.* events.
Region Seeding Workflow and Script
apps/medusa-be/src/scripts/seed-paykit.ts, apps/medusa-be/src/workflows/seed/*
Seed script discovers enabled providers, fetches regions and payment provider assignments, transforms data into workflow input; workflow orchestrates region creation and payment provider assignment across coordinated steps.
Module Documentation
apps/medusa-be/src/modules/payment-paykit/README.md
Documents PayKit module integration approach, Medusa-specific behavioural requirements, and intentional non-implementation of saved payment methods.
Test Infrastructure and Helpers
apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
Provides Vitest mock factories for PayKit client with configurable overrides for payments, refunds, and customers operations.
Currency Conversion Tests
apps/medusa-be/src/modules/payment-paykit/__tests__/amounts.unit.spec.ts
Tests multiplier functions and conversion helpers across standard, zero-decimal, and Stripe three-decimal currencies with rounding validation.
Base Provider Tests
apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
Comprehensive tests for payment initiation, capture, refund, update, deletion, account holder lifecycle, and webhook event routing.
GoPay Provider Tests
apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
Tests amount normalisation, option shape preservation, capture handling, and webhook processing.
Comgate Provider Tests
apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
Tests option validation, amount normalisation, email resolution, payment label precedence, and webhook handling.
Stripe Provider Tests
apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
Tests option validation, amount normalisation with three-decimal handling, capture processing, multiple webhook scenarios, and error fallback mapping.
Runtime Utilities Tests
apps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.ts
Tests provider option mapping and sandbox mode defaults.
GoPay Webhook Route Tests
apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts
Tests successful webhook emission, retry/delay configuration, validation of missing payment ID, and resilience to failures.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/paykit_module
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch feat/paykit_module

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 24

🤖 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 `@apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts`:
- Around line 62-80: Add an explicit return type Promise<void> to the GET
handler and wrap the call to emitPaykitPaymentWebhookEvent in a try/catch: keep
the existing validations using getRequestUrl and hasGopayPaymentId, then await
emitPaykitPaymentWebhookEvent({ req, provider: PAYKIT_GOPAY_WEBHOOK_PROVIDER_ID,
data: { fullUrl, url: req.url } }) inside a try block and on error log or
capture the error and send an appropriate response (e.g., res.status(500).json({
error: "Failed to emit webhook", details: err.message })) and return; ensure
successful paths still send res.sendStatus(200).
- Around line 29-31: The code in getRequestUrl currently asserts req as
RequestWithUrlParts without validation; replace the cast with a safe runtime
check: implement a small type guard (e.g., isRequestWithUrlParts(req): boolean)
or inline check that verifies 'originalUrl' exists and is a string (e.g., typeof
(req as any).originalUrl === 'string' or 'originalUrl' in req), then use
req.originalUrl when present, otherwise fallback to req.url; update
getRequestUrl to use that guard/conditional so no unchecked "as
RequestWithUrlParts" is used and access to originalUrl is validated before use.

In `@apps/medusa-be/src/modules/payment-paykit/base.ts`:
- Around line 437-441: The code unsafely type-asserts input.data?.amount and
input as CapturePaymentInputWithAmount; instead, in the function containing the
variables explicitAmount, paymentDataAmount and amount (base.ts), first validate
that input.data?.amount is present and has the expected shape/type (e.g., number
or string numeric) and that input actually matches CapturePaymentInputWithAmount
before casting; replace the raw "as" assertions with runtime checks (typeof
checks, Number.isFinite, non-negative check or parsing) and only assign
explicitAmount/paymentDataAmount after those checks, throwing or returning an
error when validation fails so amount is always a validated numeric value before
use.
- Line 579: The return of an empty object cast to CreateAccountHolderOutput
hides type errors; locate the function that contains "return {} as
CreateAccountHolderOutput" and either (A) construct and return a real
CreateAccountHolderOutput object with all required fields populated (matching
the CreateAccountHolderOutput type), or (B) change the function signature to
return CreateAccountHolderOutput | null/undefined (or throw an error) and update
all callers to handle the nullable/exception case; ensure the chosen fix removes
the type assertion and preserves correct runtime behavior.
- Around line 414-416: The code is unsafely casting input.data?.metadata to
Record<string, unknown> for toStringMetadata; instead validate the raw metadata
first (e.g., ensure metadata !== null, typeof metadata === 'object' and
!Array.isArray(metadata)) before converting/casting, and only pass a validated
Record to toStringMetadata (or pass undefined/{} when validation fails) to avoid
incorrect assumptions from using `as` without checks.
- Line 468: The expression "input.data?.currency as string" performs an
unchecked type assertion; update the logic in the relevant function (the code
handling input.data and currency in base.ts) to first validate that input.data
exists and that input.data.currency is a non-empty string (or matches allowed
currency codes) before casting or using it; if validation fails, throw a clear
error or fallback to a safe default. Reference the symbols input, input.data,
and input.data.currency when implementing the check (or extract to a helper like
validateCurrency) so you avoid using "as string" without prior validation.
- Line 219: The line "const billingRecord = billing as Record<string, unknown>"
unsafely asserts structure without runtime checks; replace it with a proper
runtime validation (a type guard) that verifies billing is an object and
contains the expected fields before narrowing its type—e.g., implement an
isBillingRecord(obj): boolean that checks typeof obj === 'object' and required
keys/types, use that guard to safely narrow billing and only then assign to
billingRecord (or construct a typed object from validated fields), and remove
the raw "as Record<string, unknown>" cast so no unchecked assertions remain.
- Line 450: The assignment to currencyCode uses a blind type assertion on
input.data?.currency; instead validate the runtime type before casting. Replace
the direct assertion by checking that input and input.data exist and typeof
input.data.currency === "string", and set currencyCode to that string or
undefined otherwise (update the const currencyCode assignment in base.ts). This
ensures downstream normalisation logic that reads currencyCode receives either a
real string or undefined without unsafe assertions.

In `@apps/medusa-be/src/modules/payment-paykit/comgate.ts`:
- Around line 78-93: In normalizeWebhookAmount, don't unconditionally cast
amount to InitiatePaymentInput["amount"]; add a type guard that validates amount
is an acceptable InitiatePaymentInput["amount"] shape (e.g., number | string |
BigNumber or whatever the other providers check) before calling
super.normalizeAmount; if the check fails, return undefined or handle error
consistently with GoPay/Stripe providers. Update the code around the cast in
normalizeWebhookAmount (the amount parameter and the call to
super.normalizeAmount) to perform the validation and only cast after the guard
passes.
- Around line 95-102: The getPaykitCustomer override returns customer.email
without ensuring the property exists; update getPaykitCustomer to guard the
result of super.getPaykitCustomer(input, data) — check if the returned value is
a string, or if it's an object with a defined non-empty email property, and
return that email; otherwise return a safe fallback string (e.g., empty string
or a default identifier) to guarantee a string is always returned by
getPaykitCustomer.

In `@apps/medusa-be/src/modules/payment-paykit/config.ts`:
- Around line 44-56: The requirePaykitOptions function currently treats falsy
values as missing because it uses !options[key]; update the missing detection to
only consider explicitly undefined (and optionally null) values so valid falsy
values like false, 0, or "" are accepted: change the filter in
requirePaykitOptions to check options[key] === undefined (or options[key] ==
null if you also want to treat null as missing) when computing missing. Ensure
the error message and behavior remain the same otherwise.

In `@apps/medusa-be/src/modules/payment-paykit/gopay.ts`:
- Around line 71-86: normalizeWebhookAmount casts amount to
InitiatePaymentInput["amount"] without validation; add a type guard and
normalize/conversion before calling super.normalizeAmount to avoid unsafe "as"
casting. Specifically, in normalizeWebhookAmount validate amount's runtime type
(check for number, string, or BigNumber via BigNumber.isBigNumber if using bn
library), convert BigNumber to a primitive string/number as required by
normalizeAmount, and only then call super.normalizeAmount(normalizedAmount,
currencyCode); keep the undefined early-return and continue to use
fromSmallestCurrencyUnit on the result.

In `@apps/medusa-be/src/modules/payment-paykit/mappers.ts`:
- Around line 87-92: getWebhookSessionId currently asserts metadata.session_id
as a string without validating types; update it to first check that
payment.metadata and event.metadata are plain objects and that their session_id
properties are typeof "string" before returning them (e.g., check
payment.metadata && typeof payment.metadata.session_id === "string" then return
it, otherwise check event.metadata similarly), avoiding any non-null/type
assertions; reference the getWebhookSessionId function and the payment.metadata
/ event.metadata fields when making the change.
- Around line 69-85: getWebhookPayment currently performs unsafe casts of
data.object, data.payment and returns an empty object cast to PaykitPayment; add
a runtime type guard (e.g., create an isPaykitPayment(pay: unknown): pay is
PaykitPayment that checks required payment fields like id/amount/status) and use
it inside getWebhookPayment to validate before returning data.object or
data.payment; if validation fails, return null (or throw a clear error) instead
of casting an empty object. Ensure you reference PaykitWebhookEvent and
PaykitPayment in the guard usage and update callers to handle the
nullable/exception result.

In `@apps/medusa-be/src/modules/payment-paykit/stripe.ts`:
- Around line 88-103: The normalizeWebhookAmount method casts amount to
InitiatePaymentInput["amount"] without checking its runtime shape; add a type
guard that validates amount is a numeric/string/BigNumber-compatible value
before calling super.normalizeAmount and only perform the cast when the guard
passes (otherwise return undefined or amount as originally handled). Update
normalizeWebhookAmount (referencing the amount parameter, normalizeWebhookAmount
method, the call to super.normalizeAmount, and fromStripeSmallestCurrencyUnit)
to validate the input type (e.g., typeof checks or an isInitiatePaymentAmount
helper) and avoid using "as InitiatePaymentInput['amount']" unless the guard
confirms safety. Ensure behavior mirrors existing providers (e.g., GoPay) for
invalid/undefined values.
- Around line 128-135: The current guard uses fragile substring matching on
error.message (error.message.includes("Unhandled event type: payment_intent."))
which can produce false positives; update the check in stripe.ts to use a stable
identifier from the PayKit SDK (e.g., check error.code or error.type or use an
SDK-specific error class such as PayKitError via instanceof) and fall back to a
strict pattern only if those fields are unavailable (for example use a anchored
regex like /^Unhandled event type: payment_intent\.$/); locate the conditional
around the error variable in the webhook handling logic and replace the
.includes(...) check with the SDK-specific property or a strict regex, importing
the SDK error class if needed.

In `@apps/medusa-be/src/modules/payment-paykit/webhooks.ts`:
- Around line 12-41: Wrap the eventBus.emit call inside
emitPaykitPaymentWebhookEvent with a try/catch: call eventBus.emit(...) as
before but catch any thrown error from eventBus.emit, log the error with context
(provider, payload/rawData/headers) using an available logger (resolve one from
req.scope or fallback to console.error), and do not let the exception bubble up
(do not rethrow) so webhook handlers don't crash; keep references to
paymentModule/options and PaymentWebhookEvents.WebhookReceived when assembling
the logged context.
- Around line 18-20: The code currently does an unchecked type assertion when
calling req.scope.resolve(Modules.PAYMENT) and casting to { options?:
PaymentModuleOptions }; change this to first validate the resolved value
(paymentModule) is non-null and is an object (and optionally that it has an
options property of the expected shape) before any "as" cast; if validation
fails, handle the error (throw or return a controlled error/response) so you
avoid unsafe casting. Locate the resolve call
(req.scope.resolve(Modules.PAYMENT)) and replace the direct "as { options?:
PaymentModuleOptions }" usage with a runtime check on paymentModule, then only
narrow/cast after the check (or extract options via safe property access).

In `@apps/medusa-be/src/scripts/seed-paykit.ts`:
- Around line 74-84: Remove the unsafe double-cast and runtime cast: construct
`query` with the correct type instead of `as unknown as
Parameters<RemoteQueryFunction>[0]` (declare it as
`Parameters<RemoteQueryFunction>[0]` or build via a typed factory) and call
`remoteQuery(query)` without forcing the result to
`RegionPaymentProviderLink[]`; then validate the response at runtime (e.g.,
ensure it's an array and each item contains `region_id` and
`payment_provider_id`) using a small type guard or schema (zod/io-ts) and return
the validated array or throw a clear error—apply these changes around the
`query` variable, the `remoteQuery` call, and the final return so
`RegionPaymentProviderLink` is only used after successful validation.
- Around line 130-136: The current call to regionService.listRegions uses a
hardcoded pagination limit (take: 1000) which can silently omit regions; update
the seeding logic around existingRegions/regionService.listRegions to either
implement proper pagination (looping requests with take and offset/page until no
more results) or remove the hard limit and document the 1k assumption, or at
minimum emit a warning when the returned count equals the limit; reference the
existingRegions variable and the regionService.listRegions call when making the
change so the seed code reliably processes all regions instead of truncating at
1000.

In `@apps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.ts`:
- Line 34: The assignment setting is_tax_inclusive: region.isTaxInclusive ??
true in create-missing-paykit-regions.ts defaults to true without explanation;
add a short inline comment above that assignment (near the
createMissingPaykitRegions / region object construction) explaining why true is
chosen as the fallback (or state that it mirrors PayKit defaults/regional
requirements) and, if necessary, validate/adjust the default value to match
actual regional tax behavior or link to documentation/tests that assert this
choice.

In `@apps/medusa-be/vitest.config.ts`:
- Line 24: Replace process.cwd() used for the vitest config root with a
file-anchored directory: import and use fileURLToPath and dirname to derive
__dirname from import.meta.url, then set the defineConfig root property to that
__dirname (instead of process.cwd()). Update the top of the vitest config to
import fileURLToPath from 'node:url' and dirname from 'node:path', compute const
__dirname = dirname(fileURLToPath(import.meta.url)), and use that __dirname in
the exported defineConfig root field so the config no longer depends on the
current working directory.

In `@apps/n1/src/services/cart-service.ts`:
- Around line 378-386: The function validatePaymentCollectionInput currently
lacks an explicit return type; update its signature to declare a void return
type (e.g., validatePaymentCollectionInput(cartId: string, providerId: string):
void) so TypeScript knows it returns nothing, leaving the body and thrown
CartServiceError calls unchanged; ensure the function name
validatePaymentCollectionInput is updated accordingly wherever referenced.
- Around line 363-376: The function getPaymentSessionData lacks an explicit
return type; define a GoPay payment session data type (e.g., PaymentSessionData)
that matches the returned shape (customer, item_id, capture_method, metadata)
and update the function signature to return PaymentSessionData | undefined (or
typeof PaymentSessionData | undefined). Ensure the Cart type usage remains the
same and only return the typed object when providerId === "pp_paykit_gopay",
otherwise return undefined; adjust any callers if needed to accept the new
explicit return type.
🪄 Autofix (Beta)

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

Run ID: 2229a4c0-46bb-4401-a06f-e554a0dd77db

📥 Commits

Reviewing files that changed from the base of the PR and between 0db0694 and b38be5f.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (31)
  • .env.docker
  • apps/medusa-be/medusa-config.ts
  • apps/medusa-be/package.json
  • apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts
  • apps/medusa-be/src/modules/payment-paykit/README.md
  • apps/medusa-be/src/modules/payment-paykit/__tests__/amounts.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/amounts.ts
  • apps/medusa-be/src/modules/payment-paykit/base.ts
  • apps/medusa-be/src/modules/payment-paykit/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/config.ts
  • apps/medusa-be/src/modules/payment-paykit/gopay.ts
  • apps/medusa-be/src/modules/payment-paykit/mappers.ts
  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
  • apps/medusa-be/src/modules/payment-paykit/stripe.ts
  • apps/medusa-be/src/modules/payment-paykit/types.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/scripts/seed-paykit.ts
  • apps/medusa-be/src/workflows/seed/paykit-payment-providers.ts
  • apps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.ts
  • apps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.ts
  • apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts
  • apps/medusa-be/vitest.config.ts
  • apps/n1/src/data/static/categories.ts
  • apps/n1/src/services/cart-service.ts
  • docker-compose.yaml
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: main
🧰 Additional context used
📓 Path-based instructions (19)
apps/medusa-be/src/modules/**/*

📄 CodeRabbit inference engine (CLAUDE.md)

Place custom Medusa modules under apps/medusa-be/src/modules

Module directories use hyphens (my-module/), but module keys in config use underscores (my_module)

Files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/amounts.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/README.md
  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/modules/payment-paykit/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/stripe.ts
  • apps/medusa-be/src/modules/payment-paykit/gopay.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/config.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/amounts.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
  • apps/medusa-be/src/modules/payment-paykit/types.ts
  • apps/medusa-be/src/modules/payment-paykit/mappers.ts
  • apps/medusa-be/src/modules/payment-paykit/base.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Import UI components using the pattern import { ComponentName } from '@libs/ui/atoms/component-name' or '@libs/ui/molecules/component-name'

Files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/amounts.unit.spec.ts
  • apps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.ts
  • apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/workflows/seed/paykit-payment-providers.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/scripts/seed-paykit.ts
  • apps/medusa-be/src/modules/payment-paykit/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/stripe.ts
  • apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts
  • apps/n1/src/services/cart-service.ts
  • apps/medusa-be/src/modules/payment-paykit/gopay.ts
  • apps/medusa-be/vitest.config.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/config.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.ts
  • apps/medusa-be/medusa-config.ts
  • apps/medusa-be/src/modules/payment-paykit/amounts.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
  • apps/medusa-be/src/modules/payment-paykit/types.ts
  • apps/medusa-be/src/modules/payment-paykit/mappers.ts
  • apps/medusa-be/src/modules/payment-paykit/base.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use Vitest for running tests in backend and UI library projects

Files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/amounts.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
apps/medusa-be/src/{api,modules,workflows,admin,subscribers,jobs}/**

📄 CodeRabbit inference engine (AGENTS.md)

In Medusa backend applications, organize custom code using the directory structure: api/, modules/, workflows/, admin/, subscribers/, jobs/

Files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/amounts.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/README.md
  • apps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.ts
  • apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/workflows/seed/paykit-payment-providers.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/modules/payment-paykit/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/stripe.ts
  • apps/medusa-be/src/modules/payment-paykit/gopay.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/config.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.ts
  • apps/medusa-be/src/modules/payment-paykit/amounts.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
  • apps/medusa-be/src/modules/payment-paykit/types.ts
  • apps/medusa-be/src/modules/payment-paykit/mappers.ts
  • apps/medusa-be/src/modules/payment-paykit/base.ts
apps/medusa-be/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/**/*.{ts,tsx}: Run npx tsc --noEmit for typechecking before committing
Always use braces around conditional blocks, even for single statements; Biome will expand them
Declare one variable per const/let statement, not multiple on one line
Use nullish coalescing operator (??) instead of logical OR (||) for default values
Do not use non-null assertions (!); use type guards or validation instead
Annotate type as unknown when accessing dynamic object properties before applying type guards
Use comments only to explain 'why', never 'what'; self-document code with clear naming
Extract pure functions to separate files for testability without runtime dependencies
Use Modules.* and ContainerRegistrationKeys.* constants instead of hardcoding module/key strings
Do not use non-null assertions in TypeScript code; validate or use type guards instead
Validate data before type casting; never use as Type without prior validation

Files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/amounts.unit.spec.ts
  • apps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.ts
  • apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/workflows/seed/paykit-payment-providers.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/scripts/seed-paykit.ts
  • apps/medusa-be/src/modules/payment-paykit/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/stripe.ts
  • apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/gopay.ts
  • apps/medusa-be/vitest.config.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/config.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.ts
  • apps/medusa-be/medusa-config.ts
  • apps/medusa-be/src/modules/payment-paykit/amounts.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
  • apps/medusa-be/src/modules/payment-paykit/types.ts
  • apps/medusa-be/src/modules/payment-paykit/mappers.ts
  • apps/medusa-be/src/modules/payment-paykit/base.ts
apps/medusa-be/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

Run bunx biome check --write . to lint and auto-format code

Files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/amounts.unit.spec.ts
  • apps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.ts
  • apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/workflows/seed/paykit-payment-providers.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/scripts/seed-paykit.ts
  • apps/medusa-be/src/modules/payment-paykit/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/stripe.ts
  • apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/gopay.ts
  • apps/medusa-be/vitest.config.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/config.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.ts
  • apps/medusa-be/medusa-config.ts
  • apps/medusa-be/src/modules/payment-paykit/amounts.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
  • apps/medusa-be/src/modules/payment-paykit/types.ts
  • apps/medusa-be/src/modules/payment-paykit/mappers.ts
  • apps/medusa-be/src/modules/payment-paykit/base.ts
apps/medusa-be/src/**/*.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/src/**/*.ts: Use const and explicit typing with dbService.sqlRaw<Type>() for SQL query results
Resolve logger using container.resolve<Logger>(ContainerRegistrationKeys.LOGGER)
Resolve Query using container.resolve<Query>(ContainerRegistrationKeys.QUERY)
Use Modules.LOCKING (not Modules.LOCK) to resolve locking services
Use Modules.CACHING (not Modules.CACHE) to resolve caching services
Throw MedusaError with appropriate type and message for error responses
Use MedusaError.Types.INVALID_DATA for 400 validation errors
Use MedusaError.Types.NOT_FOUND for 404 errors
Use MedusaError.Types.UNAUTHORIZED for 401 authentication errors
Use MedusaError.Types.NOT_ALLOWED for 400 permission errors
Use MedusaError.Types.DUPLICATE_ERROR for 422 duplicate entry errors
Use MedusaError.Types.CONFLICT for 409 conflict errors
Use caching module's computeKey() to generate stable cache keys from filters and pagination
Use caching module's get() with type assertion for cache retrieval
Use caching module's set() with TTL and tags for cache storage and bulk invalidation
Use caching module's clear() with tags to bulk-invalidate related cache entries
Always use Redis for caching in multi-container deployments instead of local variables
Batch operations using CHUNK_SIZE constant instead of unbounded loops

Files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/amounts.unit.spec.ts
  • apps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.ts
  • apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/workflows/seed/paykit-payment-providers.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/scripts/seed-paykit.ts
  • apps/medusa-be/src/modules/payment-paykit/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/stripe.ts
  • apps/medusa-be/src/modules/payment-paykit/gopay.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/config.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.ts
  • apps/medusa-be/src/modules/payment-paykit/amounts.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
  • apps/medusa-be/src/modules/payment-paykit/types.ts
  • apps/medusa-be/src/modules/payment-paykit/mappers.ts
  • apps/medusa-be/src/modules/payment-paykit/base.ts
apps/medusa-be/src/modules/*/__tests__/*.spec.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/src/modules/*/__tests__/*.spec.ts: Use moduleIntegrationTestRunner() for module tests with real DB instead of mocking MedusaService methods
Mock loaders in tests using vi.mock() to prevent actual initialization during testing
Wrap missing dependency resolution in try/catch in integration tests; Awilix throws even with nullish coalescing

Files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/amounts.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
apps/medusa-be/src/modules/**/*.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

Modules use isolated containers; Query/Link unavailable during service initialization, defer to onApplicationStart

Files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/amounts.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/modules/payment-paykit/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/stripe.ts
  • apps/medusa-be/src/modules/payment-paykit/gopay.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/config.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/amounts.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
  • apps/medusa-be/src/modules/payment-paykit/types.ts
  • apps/medusa-be/src/modules/payment-paykit/mappers.ts
  • apps/medusa-be/src/modules/payment-paykit/base.ts
apps/medusa-be/src/workflows/**/*

📄 CodeRabbit inference engine (CLAUDE.md)

Place business logic workflows under apps/medusa-be/src/workflows

Files:

  • apps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.ts
  • apps/medusa-be/src/workflows/seed/paykit-payment-providers.ts
  • apps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.ts
apps/medusa-be/src/workflows/**/*.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/src/workflows/**/*.ts: Use the second parameter { container } object to access container in workflow steps
Use createStep() to define workflow steps with input validation and response wrapping
Use createWorkflow() to define multi-step business logic with rollback support
Return new StepResponse() from workflow steps to pass data to next steps
Return new WorkflowResponse() from workflows to pass final result to caller
Use transform() in workflows for data manipulation only; cannot contain side effects
Use when().then() for conditional logic in workflows instead of if statements
Do not reassign or iterate workflow variables; variable definitions are static at definition time
Use useQueryGraphStep() for Query operations within workflows
Use acquireLockStep(), releaseLockStep() for workflow-level locking instead of manual job locking

Files:

  • apps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.ts
  • apps/medusa-be/src/workflows/seed/paykit-payment-providers.ts
  • apps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.ts
apps/medusa-be/src/api/**/*

📄 CodeRabbit inference engine (CLAUDE.md)

Place custom Medusa backend API endpoints under apps/medusa-be/src/api

Files:

  • apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts
apps/medusa-be/src/api/**/*.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/src/api/**/*.ts: Use req.scope.resolve() to access container in routes
Colocate validators.ts and middlewares.ts with each route file in the same directory
Use validateAndTransformBody(Schema) middleware for POST/PUT request validation
Use validateAndTransformQuery(Schema) middleware for GET request query parameter validation
Use req.validatedBody in route handlers for type-safe access to validated request body

Files:

  • apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts
apps/medusa-be/src/scripts/**/*.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/src/scripts/**/*.ts: Use medusa exec ./path/to/script.ts [args] to run one-off scripts instead of creating HTTP endpoints
Use script pattern npx medusa exec ./src/scripts/startup.ts in startup hooks
Use destructive operations in medusa exec scripts, never in unprotected GET endpoints

Files:

  • apps/medusa-be/src/scripts/seed-paykit.ts
apps/medusa-be/tests/unit/**/*.unit.spec.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/tests/unit/**/*.unit.spec.ts: Focus unit tests on critical paths: validation, money calculations, and core business logic
Skip unit tests for: getters, static arrays, trivial transforms, constants, and pass-through methods
Do not test mocked methods; test real behavior instead
Do not test query.graph() pass-through calls in unit tests
Do not test logging calls; they are implementation details
Use factory functions like createMockEntity(overrides) for test data generation
Use it.each() to test multiple error cases and boundary conditions
Use vi.useFakeTimers() for deterministic time-based testing; use vi.setSystemTime() for absolute time
Clear mocks with mockFn.mockReset() instead of vi.clearAllMocks() for mockResolvedValueOnce chains

Files:

  • apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts
apps/n1/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (apps/n1/CLAUDE.md)

apps/n1/**/*.{js,jsx,ts,tsx}: Use spacing tokens 50-950 (e.g., p-400, gap-600, m-200) in Tailwind classes - NEVER use small/medium/large tokens (sm, md, lg)
Use semantic color tokens (primary, secondary, success, warning, danger, info, fg-primary, fg-secondary, bg-surface, border-primary, etc.) - NEVER use arbitrary color names like bg-gray-100 or text-blue-500
Do NOT use arbitrary Tailwind values like p-[20px] or bg-[#fff] - use predefined spacing and color tokens only
Use ref as a prop pattern in React 19 components instead of forwardRef
Do NOT use useCallback hook (React 19 has automatic memoization via the React Compiler)
Import UI components from @libs/ui with the appropriate directory path: @libs/ui/atoms/<component> for atoms, @libs/ui/molecules/<component> for molecules
Import hooks with the use- naming convention from @/hooks/<hook-name> directory (e.g., useCart, useAuth, useOrders)
Import services from @/services/<service-name> directory following the <noun>-service naming pattern (e.g., product-service)

Files:

  • apps/n1/src/services/cart-service.ts
apps/n1/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/n1/AGENTS.md)

No barrel files or re-export-only index.ts files. Import from source files directly (e.g., import { formatDate } from '@/utils/date/format-date'). This improves traceability, reduces circular dependency risk, and supports Nx module boundary enforcement.

Files:

  • apps/n1/src/services/cart-service.ts
**/package.json

📄 CodeRabbit inference engine (CLAUDE.md)

Use pnpm CLI to add dependencies; never edit package.json directly

Files:

  • apps/medusa-be/package.json
apps/medusa-be/**/medusa-config.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

Use feature flag env vars in medusa-config.ts evaluated at BUILD time, not runtime

Files:

  • apps/medusa-be/medusa-config.ts
🧠 Learnings (6)
📚 Learning: 2026-02-25T14:46:02.729Z
Learnt from: redeyecz
Repo: TechsioCZ/new-engine PR: 335
File: apps/zane-operator/src/db.ts:205-207
Timestamp: 2026-02-25T14:46:02.729Z
Learning: Enforce PostgreSQL 18+ as the minimum version across docker-compose files. Since the repo uses postgres:18.1-alpine (evidence in docker-compose.yaml), ensure all docker-compose service images for PostgreSQL use 18.1-alpine or newer. When reviewing, look for postgres images with a tag below 18 (e.g., postgres:<older-version>) and update to 18.1-alpine or a newer compatible tag. This guideline applies to all docker-compose YAML files that define PostgreSQL services.

Applied to files:

  • docker-compose.yaml
📚 Learning: 2025-12-18T13:14:43.887Z
Learnt from: BleedingDev
Repo: NMIT-WR/new-engine PR: 241
File: apps/n1/src/services/category-service.ts:174-214
Timestamp: 2025-12-18T13:14:43.887Z
Learning: In apps/n1/src/services/ and similar files under this directory, prefer relying on React Query's built-in retry/backoff and AbortSignal cancellation instead of implementing custom timeout/retry logic at the service layer. This avoids duplicating retry policy and keeps behavior consistent across runtimes. Ensure you do not add independent timeout/retry logic in services; configure retries and delays via React Query (e.g., retry, retryDelay) and propagate AbortSignal to fetch/requests as needed. This guideline applies broadly to all service files under apps/n1/src/services.

Applied to files:

  • apps/n1/src/services/cart-service.ts
📚 Learning: 2026-03-20T08:17:59.136Z
Learnt from: KaiUweCZE
Repo: TechsioCZ/new-engine PR: 353
File: apps/n1/src/hooks/use-prefetch-category-children.ts:24-25
Timestamp: 2026-03-20T08:17:59.136Z
Learning: In TechsioCZ/new-engine’s Next.js app under apps/n1, the app-level Suspense boundary is already provided by the root layout via the Providers component (apps/n1/src/components/provider.tsx). Therefore, hooks that use useSuspenseQuery (and functions/hooks called within the app tree, e.g., hooks like useSuspenseCategoryRegistry) are already covered for correctness and should not require additional local Suspense boundaries at the page/layout level. Adding additional Suspense boundaries is only an optional UX decision for more granular fallback UI, not something required to make the Suspense-enabled queries work.

Applied to files:

  • apps/n1/src/services/cart-service.ts
📚 Learning: 2026-04-16T08:11:11.954Z
Learnt from: KaiUweCZE
Repo: TechsioCZ/new-engine PR: 352
File: apps/n1/src/app/pokladna/_components/checkout-review.tsx:4-5
Timestamp: 2026-04-16T08:11:11.954Z
Learning: In `apps/n1`, UI components must be imported using the real `techsio/ui-kit` package entrypoints: `techsio/ui-kit/atoms/<component>` and `techsio/ui-kit/molecules/<component>`. Do not flag `techsio/ui-kit/*` imports as incorrect in `apps/n1`—they are the mandated import pattern. (Legacy aliases like `ui/atoms/*` and `ui/molecules/*` are removed for `apps/n1` via its `tsconfig.json`.)

Applied to files:

  • apps/n1/src/services/cart-service.ts
📚 Learning: 2026-02-05T14:43:17.404Z
Learnt from: KaiUweCZE
Repo: NMIT-WR/new-engine PR: 324
File: apps/medusa-be/package.json:0-0
Timestamp: 2026-02-05T14:43:17.404Z
Learning: Validate and enforce React 19 compatibility across monorepo workspaces. Since Medusa UI supports React 19 via root package.json overrides and Medusa Cloud prerequisites show React 19 overrides for npm workspaces, ensure workspace root and all relevant package.json files align with React 19 (18+ requirement is satisfied). When reviewing, verify that overrides exist in the root package.json and that dependent packages in apps or packages directories declare React 19 (or compatible) in their peerDependencies or dependencies as appropriate for workspace usage.

Applied to files:

  • apps/medusa-be/package.json
📚 Learning: 2026-05-07T19:05:58.339Z
Learnt from: redeyecz
Repo: TechsioCZ/new-engine PR: 390
File: apps/medusa-be/package.json:78-81
Timestamp: 2026-05-07T19:05:58.339Z
Learning: When reviewing changes to `package.json`, do not automatically flag dependency additions/removals as "manually edited" or as "bypassing the pnpm lockfile" just because the `package.json` diff shows only that file changed. First verify whether `pnpm-lock.yaml` is missing the corresponding entries. Since `pnpm add` updates both `package.json` and `pnpm-lock.yaml` together, legitimate changes can appear in the `package.json` diff while still being properly tracked in the lockfile.

Applied to files:

  • apps/medusa-be/package.json
🪛 dotenv-linter (4.0.0)
.env.docker

[warning] 50-50: [UnorderedKey] The DC_FEATURE_PAYKIT_COMGATE_ENABLED key should go before the DC_FEATURE_PAYKIT_ENABLED key

(UnorderedKey)


[warning] 52-52: [UnorderedKey] The DC_PAYKIT_CLOUD_API_KEY key should go before the DC_PAYKIT_DEBUG key

(UnorderedKey)


[warning] 64-64: [UnorderedKey] The DC_COMGATE_SANDBOX key should go before the DC_COMGATE_SECRET key

(UnorderedKey)

🪛 LanguageTool
apps/medusa-be/src/modules/payment-paykit/README.md

[grammar] ~20-~20: A determiner may be missing.
Context: ...tween Medusa major units and provider smallest units. - Webhook data is only returned ...

(THE_SUPERLATIVE)

🔇 Additional comments (45)
apps/medusa-be/src/modules/payment-paykit/README.md (1)

1-38: LGTM!

apps/medusa-be/src/modules/payment-paykit/runtime.ts (3)

28-30: Dynamic import pattern is appropriate for runtime module loading.

The Function constructor pattern for dynamic import is intentional for runtime module loading and is properly constrained to loading PayKit SDK packages. The subsequent loadExport function validates exports exist before returning them.


56-56: Type assertion after export validation is acceptable.

The code validates that the export exists (lines 48-54) before casting to T. This is acceptable given the dynamic nature of module loading, though runtime type validation would be ideal if PayKit exports are predictable.


176-204: Webhook URL resolution with proper fallback handling.

The getWebhookFullUrl helper properly checks for multiple field variants (fullUrl, full_url, url) and provides sensible fallbacks including protocol detection and host+path construction.

apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts (1)

13-71: Well-structured test helper with proper override support.

The mock helper provides comprehensive default implementations for all PayKit client methods whilst allowing granular overrides. The structure supports both success and error scenarios in tests.

apps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.ts (1)

9-92: Comprehensive test coverage for option mappers.

The test suite validates that provider-specific options are correctly mapped to PayKit SDK requirements, including proper separation of webhook secrets for Stripe and default value handling for sandbox modes.

apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts (3)

33-79: Thorough test of payment initiation and ID persistence.

The test validates the critical requirement that the provider payment ID is persisted in data.id, ensuring Medusa can reference the payment in subsequent operations.


216-248: Excellent coverage of Medusa rollback semantics.

The tests properly validate that deletePayment handles early rollback scenarios where no provider ID has been persisted yet, avoiding unnecessary API calls and preventing client initialisation.


312-351: Proper ProviderNotSupportedError handling pattern.

The tests validate that optional provider features gracefully degrade when not supported, treating ProviderNotSupportedError as a signal to return empty/fallback data rather than propagating the error.

apps/n1/src/services/cart-service.ts (2)

393-393: LGTM!

Also applies to: 418-419, 423-423


364-364: ⚡ Quick win

Extract provider ID to a named constant.

The provider ID "pp_paykit_gopay" should be defined as a constant to ensure consistency and prevent typos. This follows the existing pattern in the codebase, such as CASH_ON_DELIVERY_PROVIDER = "pp_system_default" defined in payment-form-section.tsx.

apps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.ts (1)

31-75: LGTM!

apps/medusa-be/src/workflows/seed/paykit-payment-providers.ts (1)

8-8: ⚡ Quick win

The constant pp_system_default is a valid Medusa payment provider identifier confirmed through consistent usage across test suites and production code throughout the repository. No action needed.

apps/medusa-be/src/modules/payment-paykit/gopay.ts (2)

22-45: LGTM!


47-53: LGTM!

apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts (1)

1-134: LGTM!

apps/medusa-be/src/modules/payment-paykit/stripe.ts (3)

43-70: LGTM!


105-122: LGTM!


174-241: LGTM!

apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts (1)

1-271: LGTM!

apps/medusa-be/src/modules/payment-paykit/comgate.ts (3)

22-32: LGTM!


34-60: LGTM!


104-130: LGTM!

apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts (1)

1-110: LGTM!

apps/medusa-be/src/modules/payment-paykit/mappers.ts (5)

21-44: LGTM!


46-67: LGTM!


94-124: LGTM!


126-164: LGTM!


166-202: LGTM!

apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts (2)

11-52: LGTM!


54-60: LGTM!

apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts (2)

9-52: LGTM!


54-100: LGTM!

apps/medusa-be/medusa-config.ts (3)

8-32: LGTM!


33-80: LGTM!


418-427: LGTM!

apps/medusa-be/src/modules/payment-paykit/types.ts (3)

1-64: LGTM!


66-135: LGTM!


136-172: LGTM!

apps/medusa-be/src/modules/payment-paykit/config.ts (2)

1-31: LGTM!


33-42: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add explicit false return for non-truthy values.

The function signature promises a boolean return, but when the value is neither "1" nor "true" (e.g., "false", "0"), the function implicitly returns undefined, violating the type contract.

🔧 Proposed fix
 export const parseBooleanEnv = (
   value: string | undefined,
   defaultValue: boolean
 ): boolean => {
   if (value === undefined || value === "") {
     return defaultValue
   }
 
-  return value === "1" || value.toLowerCase() === "true"
+  if (value === "1" || value.toLowerCase() === "true") {
+    return true
+  }
+
+  return false
 }
			> Likely an incorrect or invalid review comment.
apps/medusa-be/src/modules/payment-paykit/amounts.ts (4)

3-44: LGTM!


46-54: LGTM!


56-71: LGTM!


73-99: LGTM!

Comment thread apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts Outdated
Comment thread apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts Outdated
Comment thread apps/medusa-be/src/modules/payment-paykit/base.ts Outdated
Comment thread apps/medusa-be/src/modules/payment-paykit/base.ts Outdated
Comment thread apps/medusa-be/src/modules/payment-paykit/base.ts Outdated
Comment thread apps/medusa-be/src/scripts/seed-paykit.ts Outdated
Comment thread apps/medusa-be/vitest.config.ts Outdated
Comment thread apps/n1/src/services/cart-service.ts Outdated
Comment thread apps/n1/src/services/cart-service.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 5

♻️ Duplicate comments (1)
apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts (1)

21-21: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Consider creating a typed mock container helper to avoid unsafe type casts.

The tests use {} as any to create minimal container fixtures, which violates the guideline against type casting without validation. This pattern appears throughout both Comgate and Stripe test files. As per coding guidelines, "Validate data before type casting; never use as Type without prior validation".

Consider creating a shared typed mock container helper (see the Comgate file review comment for an example implementation) that can be reused across all PayKit provider tests.

Also applies to: 47-47, 87-87, 113-113, 144-144, 179-179, 210-210, 257-257

🤖 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 `@apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts` at
line 21, Tests create PaykitStripePaymentProvider with unsafe casts (e.g., new
PaykitStripePaymentProvider({} as any))—replace these with a reusable typed mock
container helper: implement a function (e.g., createMockContainer or
MockContainerFactory) that returns a properly typed minimal Container/Module
dependencies object matching the provider constructor signature, use that helper
across stripe.unit.spec.ts (and other PayKit provider tests) instead of {} as
any, and update tests that call new PaykitStripePaymentProvider(...) to pass the
typed mock so you remove all "as any" casts and satisfy type validation.
🤖 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 `@apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts`:
- Line 31: Tests instantiate PaykitComgatePaymentProvider with unsafe casts ({}
as any); create a typed mock container helper (e.g., createMockContainer) that
returns a minimal object satisfying Partial<MedusaContainer> (include only
methods used by PaykitComgatePaymentProvider such as resolve or any other
required props) and replace all occurrences of "{} as any" in this test file
(and at the other noted locations) with calls to that helper when constructing
new PaykitComgatePaymentProvider to avoid unsafe type casts and satisfy the
project's validation guideline.

In `@apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts`:
- Line 26: The test is reaching into the provider's private implementation via
(provider as any).getClient(); instead, update the spec to exercise the public
contract: remove the type assertion and direct call to getClient(), and either
assert behavior via public methods such as provider.initiatePayment (mocking
Stripe responses) or add a small public accessor (e.g., getStripeClient()) to
the provider if exposing the client is necessary for testing; adjust mocks and
expectations to verify the constructed client's behavior through the public API
rather than calling the private getClient() method.

In `@apps/medusa-be/src/modules/payment-paykit/comgate.ts`:
- Line 106: The current line unconditionally casts data.customer to "{ email?:
unknown } | string | undefined"; remove the unsafe type assertion and instead
read data.customer without casting (e.g., const customer = data.customer) and
perform runtime validation before treating it as an object: check customer !==
null && typeof customer === "object" and, when accessing email, verify 'email'
in customer and typeof customer.email === "string"; keep the existing string
branch for when typeof customer === "string" and ensure any downstream uses of
customer.email use the validated value or a fallback.

In `@apps/medusa-be/src/modules/payment-paykit/README.md`:
- Around line 19-20: Update the README sentence "Provider amounts are normalized
explicitly between Medusa major units and provider smallest units." to use
possessive wording for clarity: change it to "Provider amounts are normalized
explicitly between Medusa major units and the provider’s smallest units." Locate
and replace that exact line in the README content (the line beginning with
"Provider amounts are normalized...") to apply the suggested wording
improvement.

In `@apps/medusa-be/src/modules/payment-paykit/stripe.ts`:
- Around line 176-179: The current cast "const paykitError = error as Error & {
code?: unknown; provider?: unknown }" uses a type assertion; instead remove the
assertion and check properties at runtime: treat error as unknown, use
instanceof Error to access message/stack, and use 'in' or typeof checks (e.g.,
if ("code" in error) and if ("provider" in error)) before reading code/provider;
update the code paths that reference paykitError.code or paykitError.provider to
only run inside those guards so no non-null assertions or casts are needed.

---

Duplicate comments:
In `@apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts`:
- Line 21: Tests create PaykitStripePaymentProvider with unsafe casts (e.g., new
PaykitStripePaymentProvider({} as any))—replace these with a reusable typed mock
container helper: implement a function (e.g., createMockContainer or
MockContainerFactory) that returns a properly typed minimal Container/Module
dependencies object matching the provider constructor signature, use that helper
across stripe.unit.spec.ts (and other PayKit provider tests) instead of {} as
any, and update tests that call new PaykitStripePaymentProvider(...) to pass the
typed mock so you remove all "as any" casts and satisfy type validation.
🪄 Autofix (Beta)

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

Run ID: f2fdb125-1bab-45bc-85ba-6259546c183b

📥 Commits

Reviewing files that changed from the base of the PR and between b38be5f and e87ff17.

📒 Files selected for processing (17)
  • .env.docker
  • apps/medusa-be/medusa-config.ts
  • apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts
  • apps/medusa-be/src/modules/payment-paykit/README.md
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/base.ts
  • apps/medusa-be/src/modules/payment-paykit/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/config.ts
  • apps/medusa-be/src/modules/payment-paykit/gopay.ts
  • apps/medusa-be/src/modules/payment-paykit/mappers.ts
  • apps/medusa-be/src/modules/payment-paykit/stripe.ts
  • apps/medusa-be/src/modules/payment-paykit/types.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/scripts/seed-paykit.ts
  • apps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.ts
  • docker-compose.yaml
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: main
🧰 Additional context used
📓 Path-based instructions (15)
apps/medusa-be/src/modules/**/*

📄 CodeRabbit inference engine (CLAUDE.md)

Place custom Medusa modules under apps/medusa-be/src/modules

Module directories use hyphens (my-module/), but module keys in config use underscores (my_module)

Files:

  • apps/medusa-be/src/modules/payment-paykit/README.md
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/config.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/gopay.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/mappers.ts
  • apps/medusa-be/src/modules/payment-paykit/stripe.ts
  • apps/medusa-be/src/modules/payment-paykit/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/types.ts
  • apps/medusa-be/src/modules/payment-paykit/base.ts
apps/medusa-be/src/{api,modules,workflows,admin,subscribers,jobs}/**

📄 CodeRabbit inference engine (AGENTS.md)

In Medusa backend applications, organize custom code using the directory structure: api/, modules/, workflows/, admin/, subscribers/, jobs/

Files:

  • apps/medusa-be/src/modules/payment-paykit/README.md
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts
  • apps/medusa-be/src/modules/payment-paykit/config.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.ts
  • apps/medusa-be/src/modules/payment-paykit/gopay.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/mappers.ts
  • apps/medusa-be/src/modules/payment-paykit/stripe.ts
  • apps/medusa-be/src/modules/payment-paykit/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/types.ts
  • apps/medusa-be/src/modules/payment-paykit/base.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Import UI components using the pattern import { ComponentName } from '@libs/ui/atoms/component-name' or '@libs/ui/molecules/component-name'

Files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts
  • apps/medusa-be/src/modules/payment-paykit/config.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.ts
  • apps/medusa-be/medusa-config.ts
  • apps/medusa-be/src/modules/payment-paykit/gopay.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/mappers.ts
  • apps/medusa-be/src/modules/payment-paykit/stripe.ts
  • apps/medusa-be/src/modules/payment-paykit/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/types.ts
  • apps/medusa-be/src/scripts/seed-paykit.ts
  • apps/medusa-be/src/modules/payment-paykit/base.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use Vitest for running tests in backend and UI library projects

Files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
apps/medusa-be/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/**/*.{ts,tsx}: Run npx tsc --noEmit for typechecking before committing
Always use braces around conditional blocks, even for single statements; Biome will expand them
Declare one variable per const/let statement, not multiple on one line
Use nullish coalescing operator (??) instead of logical OR (||) for default values
Do not use non-null assertions (!); use type guards or validation instead
Annotate type as unknown when accessing dynamic object properties before applying type guards
Use comments only to explain 'why', never 'what'; self-document code with clear naming
Extract pure functions to separate files for testability without runtime dependencies
Use Modules.* and ContainerRegistrationKeys.* constants instead of hardcoding module/key strings
Do not use non-null assertions in TypeScript code; validate or use type guards instead
Validate data before type casting; never use as Type without prior validation

Files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts
  • apps/medusa-be/src/modules/payment-paykit/config.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.ts
  • apps/medusa-be/medusa-config.ts
  • apps/medusa-be/src/modules/payment-paykit/gopay.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/mappers.ts
  • apps/medusa-be/src/modules/payment-paykit/stripe.ts
  • apps/medusa-be/src/modules/payment-paykit/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/types.ts
  • apps/medusa-be/src/scripts/seed-paykit.ts
  • apps/medusa-be/src/modules/payment-paykit/base.ts
apps/medusa-be/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

Run bunx biome check --write . to lint and auto-format code

Files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts
  • apps/medusa-be/src/modules/payment-paykit/config.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.ts
  • apps/medusa-be/medusa-config.ts
  • apps/medusa-be/src/modules/payment-paykit/gopay.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/mappers.ts
  • apps/medusa-be/src/modules/payment-paykit/stripe.ts
  • apps/medusa-be/src/modules/payment-paykit/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/types.ts
  • apps/medusa-be/src/scripts/seed-paykit.ts
  • apps/medusa-be/src/modules/payment-paykit/base.ts
apps/medusa-be/src/**/*.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/src/**/*.ts: Use const and explicit typing with dbService.sqlRaw<Type>() for SQL query results
Resolve logger using container.resolve<Logger>(ContainerRegistrationKeys.LOGGER)
Resolve Query using container.resolve<Query>(ContainerRegistrationKeys.QUERY)
Use Modules.LOCKING (not Modules.LOCK) to resolve locking services
Use Modules.CACHING (not Modules.CACHE) to resolve caching services
Throw MedusaError with appropriate type and message for error responses
Use MedusaError.Types.INVALID_DATA for 400 validation errors
Use MedusaError.Types.NOT_FOUND for 404 errors
Use MedusaError.Types.UNAUTHORIZED for 401 authentication errors
Use MedusaError.Types.NOT_ALLOWED for 400 permission errors
Use MedusaError.Types.DUPLICATE_ERROR for 422 duplicate entry errors
Use MedusaError.Types.CONFLICT for 409 conflict errors
Use caching module's computeKey() to generate stable cache keys from filters and pagination
Use caching module's get() with type assertion for cache retrieval
Use caching module's set() with TTL and tags for cache storage and bulk invalidation
Use caching module's clear() with tags to bulk-invalidate related cache entries
Always use Redis for caching in multi-container deployments instead of local variables
Batch operations using CHUNK_SIZE constant instead of unbounded loops

Files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts
  • apps/medusa-be/src/modules/payment-paykit/config.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.ts
  • apps/medusa-be/src/modules/payment-paykit/gopay.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/mappers.ts
  • apps/medusa-be/src/modules/payment-paykit/stripe.ts
  • apps/medusa-be/src/modules/payment-paykit/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/types.ts
  • apps/medusa-be/src/scripts/seed-paykit.ts
  • apps/medusa-be/src/modules/payment-paykit/base.ts
apps/medusa-be/src/modules/*/__tests__/*.spec.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/src/modules/*/__tests__/*.spec.ts: Use moduleIntegrationTestRunner() for module tests with real DB instead of mocking MedusaService methods
Mock loaders in tests using vi.mock() to prevent actual initialization during testing
Wrap missing dependency resolution in try/catch in integration tests; Awilix throws even with nullish coalescing

Files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
apps/medusa-be/src/modules/**/*.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

Modules use isolated containers; Query/Link unavailable during service initialization, defer to onApplicationStart

Files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/config.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/gopay.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/mappers.ts
  • apps/medusa-be/src/modules/payment-paykit/stripe.ts
  • apps/medusa-be/src/modules/payment-paykit/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/types.ts
  • apps/medusa-be/src/modules/payment-paykit/base.ts
apps/medusa-be/src/api/**/*

📄 CodeRabbit inference engine (CLAUDE.md)

Place custom Medusa backend API endpoints under apps/medusa-be/src/api

Files:

  • apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts
apps/medusa-be/src/api/**/*.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/src/api/**/*.ts: Use req.scope.resolve() to access container in routes
Colocate validators.ts and middlewares.ts with each route file in the same directory
Use validateAndTransformBody(Schema) middleware for POST/PUT request validation
Use validateAndTransformQuery(Schema) middleware for GET request query parameter validation
Use req.validatedBody in route handlers for type-safe access to validated request body

Files:

  • apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts
apps/medusa-be/src/workflows/**/*

📄 CodeRabbit inference engine (CLAUDE.md)

Place business logic workflows under apps/medusa-be/src/workflows

Files:

  • apps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.ts
apps/medusa-be/src/workflows/**/*.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/src/workflows/**/*.ts: Use the second parameter { container } object to access container in workflow steps
Use createStep() to define workflow steps with input validation and response wrapping
Use createWorkflow() to define multi-step business logic with rollback support
Return new StepResponse() from workflow steps to pass data to next steps
Return new WorkflowResponse() from workflows to pass final result to caller
Use transform() in workflows for data manipulation only; cannot contain side effects
Use when().then() for conditional logic in workflows instead of if statements
Do not reassign or iterate workflow variables; variable definitions are static at definition time
Use useQueryGraphStep() for Query operations within workflows
Use acquireLockStep(), releaseLockStep() for workflow-level locking instead of manual job locking

Files:

  • apps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.ts
apps/medusa-be/**/medusa-config.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

Use feature flag env vars in medusa-config.ts evaluated at BUILD time, not runtime

Files:

  • apps/medusa-be/medusa-config.ts
apps/medusa-be/src/scripts/**/*.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/src/scripts/**/*.ts: Use medusa exec ./path/to/script.ts [args] to run one-off scripts instead of creating HTTP endpoints
Use script pattern npx medusa exec ./src/scripts/startup.ts in startup hooks
Use destructive operations in medusa exec scripts, never in unprotected GET endpoints

Files:

  • apps/medusa-be/src/scripts/seed-paykit.ts
🧠 Learnings (1)
📚 Learning: 2026-02-25T14:46:02.729Z
Learnt from: redeyecz
Repo: TechsioCZ/new-engine PR: 335
File: apps/zane-operator/src/db.ts:205-207
Timestamp: 2026-02-25T14:46:02.729Z
Learning: Enforce PostgreSQL 18+ as the minimum version across docker-compose files. Since the repo uses postgres:18.1-alpine (evidence in docker-compose.yaml), ensure all docker-compose service images for PostgreSQL use 18.1-alpine or newer. When reviewing, look for postgres images with a tag below 18 (e.g., postgres:<older-version>) and update to 18.1-alpine or a newer compatible tag. This guideline applies to all docker-compose YAML files that define PostgreSQL services.

Applied to files:

  • docker-compose.yaml
🪛 dotenv-linter (4.0.0)
.env.docker

[warning] 50-50: [UnorderedKey] The DC_FEATURE_PAYKIT_COMGATE_ENABLED key should go before the DC_FEATURE_PAYKIT_ENABLED key

(UnorderedKey)


[warning] 52-52: [UnorderedKey] The DC_PAYKIT_CLOUD_API_KEY key should go before the DC_PAYKIT_DEBUG key

(UnorderedKey)


[warning] 64-64: [UnorderedKey] The DC_COMGATE_SANDBOX key should go before the DC_COMGATE_SECRET key

(UnorderedKey)


[warning] 66-66: [UnorderedKey] The DC_COMGATE_PAYMENT_LABEL key should go before the DC_COMGATE_SANDBOX key

(UnorderedKey)

🪛 LanguageTool
apps/medusa-be/src/modules/payment-paykit/README.md

[grammar] ~20-~20: A determiner may be missing.
Context: ...tween Medusa major units and provider smallest units. - Webhook data is only returned ...

(THE_SUPERLATIVE)

🔇 Additional comments (39)
apps/medusa-be/src/modules/payment-paykit/README.md (1)

1-18: LGTM!

Also applies to: 21-42

.env.docker (1)

46-71: LGTM!

apps/medusa-be/medusa-config.ts (4)

8-14: LGTM!


27-32: LGTM!


33-81: LGTM!


419-428: LGTM!

docker-compose.yaml (1)

67-85: LGTM!

apps/medusa-be/src/modules/payment-paykit/types.ts (3)

6-20: LGTM!


22-39: LGTM!


85-130: LGTM!

apps/medusa-be/src/modules/payment-paykit/config.ts (4)

1-8: LGTM!


17-31: LGTM!


33-42: LGTM!


44-60: LGTM!

apps/medusa-be/src/modules/payment-paykit/mappers.ts (8)

21-30: LGTM!


32-55: LGTM!


57-78: LGTM!


80-100: LGTM!


102-121: LGTM!


123-153: LGTM!


155-193: LGTM!


195-236: LGTM!

apps/medusa-be/src/modules/payment-paykit/webhooks.ts (3)

16-29: LGTM!


31-56: LGTM!


58-96: LGTM!

apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts (5)

5-14: LGTM!


16-32: LGTM!


34-54: LGTM!


56-62: LGTM!


64-98: LGTM!

apps/medusa-be/src/scripts/seed-paykit.ts (1)

74-84: fix(seed-paykit): replace assertion-based query typing with a typed declaration

Line 82 still relies on a direct type assertion for query. Please keep this as a typed variable declaration instead of asserting at the end, so the compiler validates the object shape directly.

Proposed minimal change
-  const query = {
+  const query: Parameters<RemoteQueryFunction>[0] = {
     service: LINKS.RegionPaymentProvider,
     variables: {
       filters: {
         region_id: regionIds,
       },
     },
     fields: ["region_id", "payment_provider_id"],
-  } as Parameters<RemoteQueryFunction>[0]
+  }

As per coding guidelines, "Validate data before type casting; never use as Type without prior validation".

apps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.ts (1)

16-42: LGTM!

apps/medusa-be/src/modules/payment-paykit/base.ts (2)

57-97: LGTM!


269-271: LGTM!

Also applies to: 390-390, 466-466, 510-510, 526-528

apps/medusa-be/src/modules/payment-paykit/gopay.ts (1)

71-83: LGTM!

apps/medusa-be/src/modules/payment-paykit/comgate.ts (2)

78-90: LGTM!


92-99: LGTM!

apps/medusa-be/src/modules/payment-paykit/stripe.ts (2)

90-102: LGTM!


171-186: LGTM!

Comment thread apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts Outdated
Comment thread apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts Outdated
Comment thread apps/medusa-be/src/modules/payment-paykit/comgate.ts Outdated
Comment thread apps/medusa-be/src/modules/payment-paykit/README.md Outdated
Comment thread apps/medusa-be/src/modules/payment-paykit/stripe.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

♻️ Duplicate comments (1)
apps/medusa-be/src/scripts/seed-paykit.ts (1)

74-83: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Avoid unchecked query type assertion

The query object is force-cast with as Parameters<RemoteQueryFunction>[0] without validation. Prefer a typed declaration so shape mismatches are caught at compile time without assertion.

Proposed diff
-  const query = {
+  const query: Parameters<RemoteQueryFunction>[0] = {
     service: LINKS.RegionPaymentProvider,
     variables: {
       filters: {
         region_id: regionIds,
       },
     },
     fields: ["region_id", "payment_provider_id"],
-  } as Parameters<RemoteQueryFunction>[0]
+  }

As per coding guidelines, "Validate data before type casting; never use as Type without prior validation".

🤖 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 `@apps/medusa-be/src/scripts/seed-paykit.ts` around lines 74 - 83, The query
object is being force-cast with "as Parameters<RemoteQueryFunction>[0]" which
bypasses compile-time checks; change to a proper typed declaration so the shape
is validated: declare the variable as "const query:
Parameters<RemoteQueryFunction>[0]" (instead of using "as") and ensure the
properties (service using LINKS.RegionPaymentProvider,
variables.filters.region_id, and fields array) match the expected type
signatures of RemoteQueryFunction; adjust any property names/types to satisfy
the compiler rather than using an unchecked assertion.
🤖 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 `@apps/medusa-be/src/modules/payment-paykit/base.ts`:
- Around line 757-761: The code must guard against client.handleWebhook
returning undefined/null so we don't call mapPaykitWebhookEvent on a non-event;
modify the block around client.handleWebhook / events / eventList to treat falsy
results as an empty array (or filter out falsy entries) and short-circuit to
return NOT_SUPPORTED when there are no valid events to process. In practice
update the logic that builds eventList (from client.handleWebhook) to: const
events = await client.handleWebhook(payload); const eventList =
Array.isArray(events) ? events.filter(Boolean) : (events ? [events] : []); and
if eventList.length === 0 then return NOT_SUPPORTED instead of proceeding to
call mapPaykitWebhookEvent.

In `@apps/medusa-be/src/modules/payment-paykit/comgate.ts`:
- Around line 34-37: The helper getCustomerEmail is treating any non-empty
string as a valid email; instead validate the value returned for a proper email
format and return undefined for non-emails so Comgate won't receive an ID as an
email. Update getCustomerEmail to: if customer is a string, run it through a
strict email check (e.g. RFC-like regex or an existing validator) and only
return it when valid; if customer is an object, extract and validate its email
property the same way; otherwise return undefined. Also apply the same
validation logic to the other customer-email extraction code paths referenced in
the file (the similar block around the later customer handling) so all places
only send validated emails to Comgate.

In `@apps/medusa-be/src/modules/payment-paykit/webhooks.ts`:
- Around line 82-83: The webhook configuration currently uses logical OR which
overrides explicit zero values; update the assignments that set delay and
attempts (using options.webhook_delay and options.webhook_retries in
webhooks.ts) to use the nullish coalescing operator (??) for their defaults
instead of || so that explicit 0 values are preserved (e.g., replace occurrences
of "options.webhook_delay || 5000" and "options.webhook_retries || 3" with
nullish-default equivalents).

In `@apps/medusa-be/src/scripts/seed-paykit.ts`:
- Around line 145-147: The current currencyCode assignment uses || which treats
empty strings as falsy; change it to explicitly trim first and then fallback
using nullish-safe logic: compute a local trimmed variable (e.g., const
trimmedCurrency = region.currency_code?.trim()), then set currencyCode =
trimmedCurrency !== '' ? trimmedCurrency : defaultRegion?.currencyCode so
empty-string is handled explicitly and the fallback uses a nullish-safe value.

---

Duplicate comments:
In `@apps/medusa-be/src/scripts/seed-paykit.ts`:
- Around line 74-83: The query object is being force-cast with "as
Parameters<RemoteQueryFunction>[0]" which bypasses compile-time checks; change
to a proper typed declaration so the shape is validated: declare the variable as
"const query: Parameters<RemoteQueryFunction>[0]" (instead of using "as") and
ensure the properties (service using LINKS.RegionPaymentProvider,
variables.filters.region_id, and fields array) match the expected type
signatures of RemoteQueryFunction; adjust any property names/types to satisfy
the compiler rather than using an unchecked assertion.
🪄 Autofix (Beta)

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

Run ID: 47c9bc5f-76e0-4af1-bdef-ed72cc6319f6

📥 Commits

Reviewing files that changed from the base of the PR and between e87ff17 and 80731d3.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (16)
  • apps/medusa-be/package.json
  • apps/medusa-be/src/modules/payment-paykit/README.md
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/base.ts
  • apps/medusa-be/src/modules/payment-paykit/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/stripe.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/scripts/seed-paykit.ts
  • apps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.ts
  • apps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.ts
  • apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts
  • apps/medusa-be/vitest.config.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (14)
**/package.json

📄 CodeRabbit inference engine (CLAUDE.md)

Use pnpm CLI to add dependencies; never edit package.json directly

Files:

  • apps/medusa-be/package.json
apps/medusa-be/src/modules/**/*

📄 CodeRabbit inference engine (CLAUDE.md)

Place custom Medusa modules under apps/medusa-be/src/modules

Module directories use hyphens (my-module/), but module keys in config use underscores (my_module)

Files:

  • apps/medusa-be/src/modules/payment-paykit/README.md
  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/stripe.ts
  • apps/medusa-be/src/modules/payment-paykit/base.ts
apps/medusa-be/src/{api,modules,workflows,admin,subscribers,jobs}/**

📄 CodeRabbit inference engine (AGENTS.md)

In Medusa backend applications, organize custom code using the directory structure: api/, modules/, workflows/, admin/, subscribers/, jobs/

Files:

  • apps/medusa-be/src/modules/payment-paykit/README.md
  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.ts
  • apps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/stripe.ts
  • apps/medusa-be/src/modules/payment-paykit/base.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Import UI components using the pattern import { ComponentName } from '@libs/ui/atoms/component-name' or '@libs/ui/molecules/component-name'

Files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.ts
  • apps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/vitest.config.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/scripts/seed-paykit.ts
  • apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/stripe.ts
  • apps/medusa-be/src/modules/payment-paykit/base.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use Vitest for running tests in backend and UI library projects

Files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts
apps/medusa-be/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/**/*.{ts,tsx}: Run npx tsc --noEmit for typechecking before committing
Always use braces around conditional blocks, even for single statements; Biome will expand them
Declare one variable per const/let statement, not multiple on one line
Use nullish coalescing operator (??) instead of logical OR (||) for default values
Do not use non-null assertions (!); use type guards or validation instead
Annotate type as unknown when accessing dynamic object properties before applying type guards
Use comments only to explain 'why', never 'what'; self-document code with clear naming
Extract pure functions to separate files for testability without runtime dependencies
Use Modules.* and ContainerRegistrationKeys.* constants instead of hardcoding module/key strings
Do not use non-null assertions in TypeScript code; validate or use type guards instead
Validate data before type casting; never use as Type without prior validation

Files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.ts
  • apps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/vitest.config.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/scripts/seed-paykit.ts
  • apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/stripe.ts
  • apps/medusa-be/src/modules/payment-paykit/base.ts
apps/medusa-be/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

Run bunx biome check --write . to lint and auto-format code

Files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.ts
  • apps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/vitest.config.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/scripts/seed-paykit.ts
  • apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/stripe.ts
  • apps/medusa-be/src/modules/payment-paykit/base.ts
apps/medusa-be/src/**/*.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/src/**/*.ts: Use const and explicit typing with dbService.sqlRaw<Type>() for SQL query results
Resolve logger using container.resolve<Logger>(ContainerRegistrationKeys.LOGGER)
Resolve Query using container.resolve<Query>(ContainerRegistrationKeys.QUERY)
Use Modules.LOCKING (not Modules.LOCK) to resolve locking services
Use Modules.CACHING (not Modules.CACHE) to resolve caching services
Throw MedusaError with appropriate type and message for error responses
Use MedusaError.Types.INVALID_DATA for 400 validation errors
Use MedusaError.Types.NOT_FOUND for 404 errors
Use MedusaError.Types.UNAUTHORIZED for 401 authentication errors
Use MedusaError.Types.NOT_ALLOWED for 400 permission errors
Use MedusaError.Types.DUPLICATE_ERROR for 422 duplicate entry errors
Use MedusaError.Types.CONFLICT for 409 conflict errors
Use caching module's computeKey() to generate stable cache keys from filters and pagination
Use caching module's get() with type assertion for cache retrieval
Use caching module's set() with TTL and tags for cache storage and bulk invalidation
Use caching module's clear() with tags to bulk-invalidate related cache entries
Always use Redis for caching in multi-container deployments instead of local variables
Batch operations using CHUNK_SIZE constant instead of unbounded loops

Files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.ts
  • apps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/scripts/seed-paykit.ts
  • apps/medusa-be/src/modules/payment-paykit/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/stripe.ts
  • apps/medusa-be/src/modules/payment-paykit/base.ts
apps/medusa-be/src/modules/*/__tests__/*.spec.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/src/modules/*/__tests__/*.spec.ts: Use moduleIntegrationTestRunner() for module tests with real DB instead of mocking MedusaService methods
Mock loaders in tests using vi.mock() to prevent actual initialization during testing
Wrap missing dependency resolution in try/catch in integration tests; Awilix throws even with nullish coalescing

Files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
apps/medusa-be/src/modules/**/*.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

Modules use isolated containers; Query/Link unavailable during service initialization, defer to onApplicationStart

Files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/stripe.ts
  • apps/medusa-be/src/modules/payment-paykit/base.ts
apps/medusa-be/src/workflows/**/*

📄 CodeRabbit inference engine (CLAUDE.md)

Place business logic workflows under apps/medusa-be/src/workflows

Files:

  • apps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.ts
  • apps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.ts
apps/medusa-be/src/workflows/**/*.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/src/workflows/**/*.ts: Use the second parameter { container } object to access container in workflow steps
Use createStep() to define workflow steps with input validation and response wrapping
Use createWorkflow() to define multi-step business logic with rollback support
Return new StepResponse() from workflow steps to pass data to next steps
Return new WorkflowResponse() from workflows to pass final result to caller
Use transform() in workflows for data manipulation only; cannot contain side effects
Use when().then() for conditional logic in workflows instead of if statements
Do not reassign or iterate workflow variables; variable definitions are static at definition time
Use useQueryGraphStep() for Query operations within workflows
Use acquireLockStep(), releaseLockStep() for workflow-level locking instead of manual job locking

Files:

  • apps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.ts
  • apps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.ts
apps/medusa-be/src/scripts/**/*.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/src/scripts/**/*.ts: Use medusa exec ./path/to/script.ts [args] to run one-off scripts instead of creating HTTP endpoints
Use script pattern npx medusa exec ./src/scripts/startup.ts in startup hooks
Use destructive operations in medusa exec scripts, never in unprotected GET endpoints

Files:

  • apps/medusa-be/src/scripts/seed-paykit.ts
apps/medusa-be/tests/unit/**/*.unit.spec.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/tests/unit/**/*.unit.spec.ts: Focus unit tests on critical paths: validation, money calculations, and core business logic
Skip unit tests for: getters, static arrays, trivial transforms, constants, and pass-through methods
Do not test mocked methods; test real behavior instead
Do not test query.graph() pass-through calls in unit tests
Do not test logging calls; they are implementation details
Use factory functions like createMockEntity(overrides) for test data generation
Use it.each() to test multiple error cases and boundary conditions
Use vi.useFakeTimers() for deterministic time-based testing; use vi.setSystemTime() for absolute time
Clear mocks with mockFn.mockReset() instead of vi.clearAllMocks() for mockResolvedValueOnce chains

Files:

  • apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts
🧠 Learnings (2)
📚 Learning: 2026-02-05T14:43:17.404Z
Learnt from: KaiUweCZE
Repo: NMIT-WR/new-engine PR: 324
File: apps/medusa-be/package.json:0-0
Timestamp: 2026-02-05T14:43:17.404Z
Learning: Validate and enforce React 19 compatibility across monorepo workspaces. Since Medusa UI supports React 19 via root package.json overrides and Medusa Cloud prerequisites show React 19 overrides for npm workspaces, ensure workspace root and all relevant package.json files align with React 19 (18+ requirement is satisfied). When reviewing, verify that overrides exist in the root package.json and that dependent packages in apps or packages directories declare React 19 (or compatible) in their peerDependencies or dependencies as appropriate for workspace usage.

Applied to files:

  • apps/medusa-be/package.json
📚 Learning: 2026-05-07T19:05:58.339Z
Learnt from: redeyecz
Repo: TechsioCZ/new-engine PR: 390
File: apps/medusa-be/package.json:78-81
Timestamp: 2026-05-07T19:05:58.339Z
Learning: When reviewing changes to `package.json`, do not automatically flag dependency additions/removals as "manually edited" or as "bypassing the pnpm lockfile" just because the `package.json` diff shows only that file changed. First verify whether `pnpm-lock.yaml` is missing the corresponding entries. Since `pnpm add` updates both `package.json` and `pnpm-lock.yaml` together, legitimate changes can appear in the `package.json` diff while still being properly tracked in the lockfile.

Applied to files:

  • apps/medusa-be/package.json
🔇 Additional comments (12)
apps/medusa-be/package.json (1)

36-36: LGTM!

Also applies to: 72-75

apps/medusa-be/vitest.config.ts (1)

4-7: LGTM!

Also applies to: 14-14, 28-28

apps/medusa-be/src/modules/payment-paykit/README.md (1)

1-41: LGTM!

apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts (1)

1-76: LGTM!

apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts (1)

1-141: LGTM!

apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts (1)

1-418: LGTM!

apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts (1)

6-180: LGTM!

apps/medusa-be/src/modules/payment-paykit/stripe.ts (1)

45-258: LGTM!

apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts (1)

6-303: LGTM!

apps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.ts (1)

16-49: LGTM!

apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts (1)

54-122: LGTM!

apps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.ts (1)

35-100: LGTM!

Comment thread apps/medusa-be/src/modules/payment-paykit/core/base.ts
Comment thread apps/medusa-be/src/modules/payment-paykit/comgate.ts Outdated
Comment thread apps/medusa-be/src/modules/payment-paykit/webhooks.ts Outdated
Comment thread apps/medusa-be/src/scripts/seed-paykit.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

♻️ Duplicate comments (1)
apps/medusa-be/src/modules/payment-paykit/base.ts (1)

673-673: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Use noAccountHolderCreated() helper for consistency.

Same issue as line 667 – use the dedicated helper instead of the direct cast.

♻️ Proposed fix for consistency
-        return {} as CreateAccountHolderOutput
+        return noAccountHolderCreated()
🤖 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 `@apps/medusa-be/src/modules/payment-paykit/base.ts` at line 673, Replace the
direct cast return "return {} as CreateAccountHolderOutput" with the shared
helper noAccountHolderCreated() to keep behavior consistent; locate the return
inside the same function that currently returns CreateAccountHolderOutput and
swap the casted empty object for a call to noAccountHolderCreated() so the
standard sentinel response is used throughout.
🤖 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 @.mise.toml:
- Around line 82-84: Update the task description for the toml task named
"dev:install:no-lock" to accurately reflect its behavior: it runs pnpm install
allowing the lockfile to be updated (uses --no-frozen-lockfile) rather than
performing a lockfile repair; change the description text to indicate it
installs dependencies while permitting lockfile updates (e.g., "Install
dependencies allowing pnpm to update the lockfile") and avoid suggesting it
"repairs" the lockfile; you can reference the existing "dev:install:fix-lock"
task (which uses --fix-lockfile) to ensure the descriptions are distinct and
correct.

In `@apps/medusa-be/src/modules/payment-paykit/base.ts`:
- Line 667: The code returns an empty object cast to CreateAccountHolderOutput;
replace that cast with the existing helper noAccountHolderCreated() to keep
behavior and documentation consistent. Locate the return statement that
currently does "return {} as CreateAccountHolderOutput" and change it to "return
noAccountHolderCreated()", ensuring noAccountHolderCreated is in scope (import
or reference the helper defined at lines 102-105).

In `@apps/medusa-be/src/modules/payment-paykit/webhooks.ts`:
- Around line 64-66: The call to getPaymentModuleOptions(paymentModule) (after
resolving paymentModule via req.scope.resolve(Modules.PAYMENT)) can throw and is
currently executed outside the webhook handler's try-catch; move the payment
module resolution and options extraction (the paymentModule and options
assignments) inside the existing try block that handles webhook processing
(where eventBus is used) so resolution errors are caught, logged via the same
error logging path, and the handler still returns HTTP 200 on failure; ensure
you still resolve eventBus (req.scope.resolve(Modules.EVENT_BUS)) where needed
inside the try/catch and preserve existing error logging/emission behaviour.

In `@libs/storefront-data/package.json`:
- Around line 289-290: The peerDependencies for "@medusajs/js-sdk" and
"@medusajs/types" were raised from ">=2.12.0" to ">=2.15.2" which is a breaking
change; either revert these entries in package.json back to ">=2.12.0" if the
bump was accidental, or if intentional, update the package version (bump major),
add migration notes explaining required changes for consumers, and document the
change in the changelog referencing the two peer dependency entries
("@medusajs/js-sdk" and "@medusajs/types") so downstream users know why the
minimum was increased.

---

Duplicate comments:
In `@apps/medusa-be/src/modules/payment-paykit/base.ts`:
- Line 673: Replace the direct cast return "return {} as
CreateAccountHolderOutput" with the shared helper noAccountHolderCreated() to
keep behavior consistent; locate the return inside the same function that
currently returns CreateAccountHolderOutput and swap the casted empty object for
a call to noAccountHolderCreated() so the standard sentinel response is used
throughout.
🪄 Autofix (Beta)

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

Run ID: 8b37a9a6-4a3a-4bc0-b255-169149363b2a

📥 Commits

Reviewing files that changed from the base of the PR and between 80731d3 and 978fa70.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (14)
  • .mise.toml
  • apps/frontend-demo/package.json
  • apps/medusa-be/package.json
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/base.ts
  • apps/medusa-be/src/modules/payment-paykit/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/scripts/seed-paykit.ts
  • apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts
  • apps/n1/package.json
  • libs/storefront-data/package.json
  • package.json
  • pnpm-workspace.yaml
📜 Review details
🧰 Additional context used
📓 Path-based instructions (13)
**/package.json

📄 CodeRabbit inference engine (CLAUDE.md)

Use pnpm CLI to add dependencies; never edit package.json directly

Files:

  • apps/n1/package.json
  • apps/frontend-demo/package.json
  • package.json
  • apps/medusa-be/package.json
  • libs/storefront-data/package.json
apps/n1/**/package.json

📄 CodeRabbit inference engine (apps/n1/CLAUDE.md)

Do NOT manually edit package.json - use pnpm add <pkg> or pnpm add -D <pkg> commands instead

Files:

  • apps/n1/package.json
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Import UI components using the pattern import { ComponentName } from '@libs/ui/atoms/component-name' or '@libs/ui/molecules/component-name'

Files:

  • apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/comgate.ts
  • apps/medusa-be/src/scripts/seed-paykit.ts
  • apps/medusa-be/src/modules/payment-paykit/base.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use Vitest for running tests in backend and UI library projects

Files:

  • apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
apps/medusa-be/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/**/*.{ts,tsx}: Run npx tsc --noEmit for typechecking before committing
Always use braces around conditional blocks, even for single statements; Biome will expand them
Declare one variable per const/let statement, not multiple on one line
Use nullish coalescing operator (??) instead of logical OR (||) for default values
Do not use non-null assertions (!); use type guards or validation instead
Annotate type as unknown when accessing dynamic object properties before applying type guards
Use comments only to explain 'why', never 'what'; self-document code with clear naming
Extract pure functions to separate files for testability without runtime dependencies
Use Modules.* and ContainerRegistrationKeys.* constants instead of hardcoding module/key strings
Do not use non-null assertions in TypeScript code; validate or use type guards instead
Validate data before type casting; never use as Type without prior validation

Files:

  • apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/comgate.ts
  • apps/medusa-be/src/scripts/seed-paykit.ts
  • apps/medusa-be/src/modules/payment-paykit/base.ts
apps/medusa-be/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

Run bunx biome check --write . to lint and auto-format code

Files:

  • apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/comgate.ts
  • apps/medusa-be/src/scripts/seed-paykit.ts
  • apps/medusa-be/src/modules/payment-paykit/base.ts
apps/medusa-be/tests/unit/**/*.unit.spec.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/tests/unit/**/*.unit.spec.ts: Focus unit tests on critical paths: validation, money calculations, and core business logic
Skip unit tests for: getters, static arrays, trivial transforms, constants, and pass-through methods
Do not test mocked methods; test real behavior instead
Do not test query.graph() pass-through calls in unit tests
Do not test logging calls; they are implementation details
Use factory functions like createMockEntity(overrides) for test data generation
Use it.each() to test multiple error cases and boundary conditions
Use vi.useFakeTimers() for deterministic time-based testing; use vi.setSystemTime() for absolute time
Clear mocks with mockFn.mockReset() instead of vi.clearAllMocks() for mockResolvedValueOnce chains

Files:

  • apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts
apps/medusa-be/src/modules/**/*

📄 CodeRabbit inference engine (CLAUDE.md)

Place custom Medusa modules under apps/medusa-be/src/modules

Module directories use hyphens (my-module/), but module keys in config use underscores (my_module)

Files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/base.ts
apps/medusa-be/src/{api,modules,workflows,admin,subscribers,jobs}/**

📄 CodeRabbit inference engine (AGENTS.md)

In Medusa backend applications, organize custom code using the directory structure: api/, modules/, workflows/, admin/, subscribers/, jobs/

Files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/base.ts
apps/medusa-be/src/**/*.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/src/**/*.ts: Use const and explicit typing with dbService.sqlRaw<Type>() for SQL query results
Resolve logger using container.resolve<Logger>(ContainerRegistrationKeys.LOGGER)
Resolve Query using container.resolve<Query>(ContainerRegistrationKeys.QUERY)
Use Modules.LOCKING (not Modules.LOCK) to resolve locking services
Use Modules.CACHING (not Modules.CACHE) to resolve caching services
Throw MedusaError with appropriate type and message for error responses
Use MedusaError.Types.INVALID_DATA for 400 validation errors
Use MedusaError.Types.NOT_FOUND for 404 errors
Use MedusaError.Types.UNAUTHORIZED for 401 authentication errors
Use MedusaError.Types.NOT_ALLOWED for 400 permission errors
Use MedusaError.Types.DUPLICATE_ERROR for 422 duplicate entry errors
Use MedusaError.Types.CONFLICT for 409 conflict errors
Use caching module's computeKey() to generate stable cache keys from filters and pagination
Use caching module's get() with type assertion for cache retrieval
Use caching module's set() with TTL and tags for cache storage and bulk invalidation
Use caching module's clear() with tags to bulk-invalidate related cache entries
Always use Redis for caching in multi-container deployments instead of local variables
Batch operations using CHUNK_SIZE constant instead of unbounded loops

Files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/comgate.ts
  • apps/medusa-be/src/scripts/seed-paykit.ts
  • apps/medusa-be/src/modules/payment-paykit/base.ts
apps/medusa-be/src/modules/*/__tests__/*.spec.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/src/modules/*/__tests__/*.spec.ts: Use moduleIntegrationTestRunner() for module tests with real DB instead of mocking MedusaService methods
Mock loaders in tests using vi.mock() to prevent actual initialization during testing
Wrap missing dependency resolution in try/catch in integration tests; Awilix throws even with nullish coalescing

Files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
apps/medusa-be/src/modules/**/*.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

Modules use isolated containers; Query/Link unavailable during service initialization, defer to onApplicationStart

Files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/base.ts
apps/medusa-be/src/scripts/**/*.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/src/scripts/**/*.ts: Use medusa exec ./path/to/script.ts [args] to run one-off scripts instead of creating HTTP endpoints
Use script pattern npx medusa exec ./src/scripts/startup.ts in startup hooks
Use destructive operations in medusa exec scripts, never in unprotected GET endpoints

Files:

  • apps/medusa-be/src/scripts/seed-paykit.ts
🧠 Learnings (2)
📚 Learning: 2026-02-05T14:43:17.404Z
Learnt from: KaiUweCZE
Repo: NMIT-WR/new-engine PR: 324
File: apps/medusa-be/package.json:0-0
Timestamp: 2026-02-05T14:43:17.404Z
Learning: Validate and enforce React 19 compatibility across monorepo workspaces. Since Medusa UI supports React 19 via root package.json overrides and Medusa Cloud prerequisites show React 19 overrides for npm workspaces, ensure workspace root and all relevant package.json files align with React 19 (18+ requirement is satisfied). When reviewing, verify that overrides exist in the root package.json and that dependent packages in apps or packages directories declare React 19 (or compatible) in their peerDependencies or dependencies as appropriate for workspace usage.

Applied to files:

  • apps/n1/package.json
  • apps/frontend-demo/package.json
  • package.json
  • apps/medusa-be/package.json
  • libs/storefront-data/package.json
📚 Learning: 2026-05-07T19:05:58.339Z
Learnt from: redeyecz
Repo: TechsioCZ/new-engine PR: 390
File: apps/medusa-be/package.json:78-81
Timestamp: 2026-05-07T19:05:58.339Z
Learning: When reviewing changes to `package.json`, do not automatically flag dependency additions/removals as "manually edited" or as "bypassing the pnpm lockfile" just because the `package.json` diff shows only that file changed. First verify whether `pnpm-lock.yaml` is missing the corresponding entries. Since `pnpm add` updates both `package.json` and `pnpm-lock.yaml` together, legitimate changes can appear in the `package.json` diff while still being properly tracked in the lockfile.

Applied to files:

  • apps/n1/package.json
  • apps/frontend-demo/package.json
  • package.json
  • apps/medusa-be/package.json
  • libs/storefront-data/package.json
🔇 Additional comments (21)
apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts (1)

1-144: LGTM!

apps/medusa-be/src/modules/payment-paykit/base.ts (4)

57-113: LGTM!


115-299: LGTM!


301-596: LGTM!


748-781: LGTM!

apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts (3)

1-128: LGTM!


130-274: LGTM!


276-434: LGTM!

apps/medusa-be/src/modules/payment-paykit/comgate.ts (4)

1-44: LGTM!


46-72: LGTM!


74-102: LGTM!


104-153: LGTM!

apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts (2)

1-173: LGTM!


175-228: LGTM!

pnpm-workspace.yaml (1)

5-5: LGTM!

package.json (1)

89-89: LGTM!

apps/frontend-demo/package.json (1)

17-18: LGTM!

apps/n1/package.json (1)

23-24: LGTM!

libs/storefront-data/package.json (1)

285-286: LGTM!

apps/medusa-be/package.json (1)

36-36: LGTM!

Also applies to: 52-76, 101-101

apps/medusa-be/src/scripts/seed-paykit.ts (1)

1-198: LGTM!

Comment thread .mise.toml
Comment thread apps/medusa-be/src/modules/payment-paykit/base.ts Outdated
Comment thread apps/medusa-be/src/modules/payment-paykit/webhooks.ts Outdated
Comment thread libs/storefront-data/package.json

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 12

🤖 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 `@apps/frontend-demo/package.json`:
- Around line 17-18: The pnpm lockfile is out of sync with package.json: update
the lock to match the declared versions (e.g., "@medusajs/js-sdk": "2.15.2" and
"@medusajs/types": "2.15.2") by running the pnpm CLI in the frontend-demo
workspace; run `pnpm install` (or `pnpm install --filter ./apps/frontend-demo`
if using workspace filters) to regenerate pnpm-lock.yaml so it reflects the
package.json versions and commit the updated lockfile.

In `@apps/medusa-be/medusa-config.ts`:
- Around line 419-428: The current diff conditionally omits the entire
"@medusajs/medusa/payment" module when PAYKIT_PAYMENT_PROVIDERS is empty;
instead always register the payment module and only change its providers list.
Update the plugins/config assembly so that the entry with resolve:
"@medusajs/medusa/payment" is always included, and set its options.providers to
PAYKIT_PAYMENT_PROVIDERS (which may be an empty array), removing the outer
conditional that gates the whole module.
- Around line 109-113: Replace the unchecked type assertion for
MEDUSA_COOKIE_SAME_SITE with a validated assignment: read
process.env.MEDUSA_COOKIE_SAME_SITE into a temporary string, check it against
the allowed literals "lax", "none", and "strict" (e.g., via an
if/Set/array.includes), and only then assign it to the typed constant
MEDUSA_COOKIE_SAME_SITE (or set it to undefined/default if invalid); update any
code that consumes MEDUSA_COOKIE_SAME_SITE to rely on the validated union type
instead of casting.

In `@apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts`:
- Around line 85-94: The handler currently includes internal error details in
the HTTP response via the variable message and returns res.status(500).json({
error: "Failed to emit webhook", details: message }); remove the details field
from the response so callers only receive a generic payload (e.g.
res.status(500).json({ error: "Failed to emit webhook" })), and ensure the full
error is still logged server-side using the existing console.error call that
includes error, fullUrl and PAYKIT_GOPAY_WEBHOOK_PROVIDER_ID so diagnostics
remain in logs but are not exposed to callers.
- Around line 88-92: Replace the direct console.error call in the PayKit GoPay
webhook handler with the Medusa scoped logger: resolve the logger from the
request scope using req.scope.resolve<Logger>(ContainerRegistrationKeys.LOGGER)
and call logger.error(...) instead of console.error, passing the same structured
payload (error, fullUrl, provider: PAYKIT_GOPAY_WEBHOOK_PROVIDER_ID) so the
failure is recorded via Medusa’s structured logging; update the code around the
console.error invocation in route.ts accordingly.

In `@apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts`:
- Around line 92-99: The test is using an unchecked cast for the capturePayment
call which bypasses type safety; update the test to pass a correctly typed
object to provider.capturePayment instead of using "as any": either remove the
extraneous amount property if CapturePaymentInput does not include it or create
a typed fixture/helper (e.g., a makeCapturePaymentInput() or
capturePaymentFixture) that returns a valid CapturePaymentInput with fields id
and currency, then use that fixture in the test when calling
provider.capturePayment to ensure proper typing and validation.

In `@apps/medusa-be/src/modules/payment-paykit/runtime.ts`:
- Line 138: The assignment to webhookSecret uses an unchecked type assertion on
providerOptions.webhookSecret; instead validate its runtime type before
casting—e.g., check typeof providerOptions.webhookSecret === "string" (or other
expected shape) and only then assign that value to webhookSecret, otherwise fall
back to "" or throw; update the runtime.ts initializer that reads
providerOptions.webhookSecret to perform this check rather than using "as string
| undefined".
- Line 200: The URL builder currently always prepends "https://" via the
expression `return \`https://${host}${path}\``, which breaks local HTTP setups;
change it to determine the protocol dynamically by checking (in order) the
`x-forwarded-proto` header, the request's protocol (e.g. `req.protocol`), an
explicit config/env override, and then defaulting to "http" for local hosts,
then build the URL using that protocol and the existing `host` and `path`
variables so the returned value adapts to local development and proxied
deployments.

In `@apps/medusa-be/src/modules/payment-paykit/utils/mappers.ts`:
- Around line 132-140: The current runtime check for `amount` only verifies
`toJSON` and `valueOf` and then unsafely asserts `return amount as
BigNumberValue`; create a proper type guard `isBigNumberValue(obj: unknown): obj
is BigNumberValue` in the same module that verifies the full BigNumberValue
shape (check methods exist and return types, and any required properties) and
replace the inline check to `if (isBigNumberValue(amount)) { return amount }`;
alternatively, if you prefer not to assert, change the branch to return
`unknown` (or throw) and document the assumption in the function comment —
update usages of this mapper accordingly to rely on the new guard.

In `@apps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.ts`:
- Line 39: The currency_code is currently set with
region.currencyCode.toLowerCase(), which can persist values with surrounding
whitespace; change the assignment for currency_code in
sync-existing-paykit-regions.ts to use region.currencyCode.trim().toLowerCase()
so leading/trailing spaces are removed before lowercasing and saving.

In `@apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts`:
- Around line 9-15: The test helper createResponse currently ends with a broad
type cast "as any"; replace this with a proper typed stub using TypeScript's
satisfies so the object conforms to the Express Response type (e.g. change the
return to an object of functions followed by "satisfies Response"), and import
the Response type from "express"; apply the same change to other test doubles in
this file that use "as any" (the other response/request stubs) so all mocks use
"satisfies Response" (or the appropriate interface) instead of casting to any.

In `@libs/storefront-data/package.json`:
- Around line 285-286: package.json lists `@medusajs/js-sdk` and `@medusajs/types`
at ^2.15.2 (devDependencies / peerDependencies) but pnpm-lock.yaml wasn’t
updated; run pnpm install to regenerate the lockfile so those versions are
recorded, verify the new pnpm-lock.yaml includes `@medusajs/js-sdk` and
`@medusajs/types` at ^2.15.2, and commit the updated pnpm-lock.yaml alongside the
package.json change to ensure reproducible installs.
🪄 Autofix (Beta)

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

Run ID: 3b99eb68-fd19-4ece-bfa5-b4a8d33227f6

📥 Commits

Reviewing files that changed from the base of the PR and between 978fa70 and 83f921e.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (39)
  • .env.docker
  • .mise.toml
  • apps/frontend-demo/package.json
  • apps/medusa-be/medusa-config.ts
  • apps/medusa-be/package.json
  • apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts
  • apps/medusa-be/src/modules/payment-paykit/README.md
  • apps/medusa-be/src/modules/payment-paykit/__tests__/amounts.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/config.ts
  • apps/medusa-be/src/modules/payment-paykit/core/base.ts
  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
  • apps/medusa-be/src/modules/payment-paykit/services/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/services/gopay.ts
  • apps/medusa-be/src/modules/payment-paykit/services/stripe.ts
  • apps/medusa-be/src/modules/payment-paykit/types/index.ts
  • apps/medusa-be/src/modules/payment-paykit/utils/amounts.ts
  • apps/medusa-be/src/modules/payment-paykit/utils/mappers.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/scripts/seed-paykit.ts
  • apps/medusa-be/src/workflows/seed/paykit-payment-providers.ts
  • apps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.ts
  • apps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.ts
  • apps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.ts
  • apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts
  • apps/medusa-be/vitest.config.ts
  • apps/n1/package.json
  • docker-compose.yaml
  • docker/development/medusa-be/Dockerfile
  • docker/development/n1/Dockerfile
  • docker/development/payload/Dockerfile
  • libs/storefront-data/package.json
  • package.json
  • pnpm-workspace.yaml
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: main
🧰 Additional context used
📓 Path-based instructions (18)
**/package.json

📄 CodeRabbit inference engine (CLAUDE.md)

Use pnpm CLI to add dependencies; never edit package.json directly

Files:

  • libs/storefront-data/package.json
  • apps/n1/package.json
  • apps/frontend-demo/package.json
  • package.json
  • apps/medusa-be/package.json
apps/n1/**/package.json

📄 CodeRabbit inference engine (apps/n1/CLAUDE.md)

Do NOT manually edit package.json - use pnpm add <pkg> or pnpm add -D <pkg> commands instead

Files:

  • apps/n1/package.json
apps/medusa-be/src/modules/**/*

📄 CodeRabbit inference engine (CLAUDE.md)

Place custom Medusa modules under apps/medusa-be/src/modules

Module directories use hyphens (my-module/), but module keys in config use underscores (my_module)

Files:

  • apps/medusa-be/src/modules/payment-paykit/services/gopay.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/README.md
  • apps/medusa-be/src/modules/payment-paykit/utils/amounts.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/config.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/services/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/services/stripe.ts
  • apps/medusa-be/src/modules/payment-paykit/utils/mappers.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/amounts.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/types/index.ts
  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
  • apps/medusa-be/src/modules/payment-paykit/core/base.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Import UI components using the pattern import { ComponentName } from '@libs/ui/atoms/component-name' or '@libs/ui/molecules/component-name'

Files:

  • apps/medusa-be/src/modules/payment-paykit/services/gopay.ts
  • apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts
  • apps/medusa-be/vitest.config.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/utils/amounts.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/scripts/seed-paykit.ts
  • apps/medusa-be/medusa-config.ts
  • apps/medusa-be/src/modules/payment-paykit/config.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/services/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/services/stripe.ts
  • apps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.ts
  • apps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.ts
  • apps/medusa-be/src/modules/payment-paykit/utils/mappers.ts
  • apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts
  • apps/medusa-be/src/workflows/seed/paykit-payment-providers.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/amounts.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/types/index.ts
  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
  • apps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.ts
  • apps/medusa-be/src/modules/payment-paykit/core/base.ts
apps/medusa-be/src/{api,modules,workflows,admin,subscribers,jobs}/**

📄 CodeRabbit inference engine (AGENTS.md)

In Medusa backend applications, organize custom code using the directory structure: api/, modules/, workflows/, admin/, subscribers/, jobs/

Files:

  • apps/medusa-be/src/modules/payment-paykit/services/gopay.ts
  • apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/README.md
  • apps/medusa-be/src/modules/payment-paykit/utils/amounts.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/config.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/services/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/services/stripe.ts
  • apps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.ts
  • apps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.ts
  • apps/medusa-be/src/modules/payment-paykit/utils/mappers.ts
  • apps/medusa-be/src/workflows/seed/paykit-payment-providers.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/amounts.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/types/index.ts
  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
  • apps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.ts
  • apps/medusa-be/src/modules/payment-paykit/core/base.ts
apps/medusa-be/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/**/*.{ts,tsx}: Run npx tsc --noEmit for typechecking before committing
Always use braces around conditional blocks, even for single statements; Biome will expand them
Declare one variable per const/let statement, not multiple on one line
Use nullish coalescing operator (??) instead of logical OR (||) for default values
Do not use non-null assertions (!); use type guards or validation instead
Annotate type as unknown when accessing dynamic object properties before applying type guards
Use comments only to explain 'why', never 'what'; self-document code with clear naming
Extract pure functions to separate files for testability without runtime dependencies
Use Modules.* and ContainerRegistrationKeys.* constants instead of hardcoding module/key strings
Do not use non-null assertions in TypeScript code; validate or use type guards instead
Validate data before type casting; never use as Type without prior validation

Files:

  • apps/medusa-be/src/modules/payment-paykit/services/gopay.ts
  • apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts
  • apps/medusa-be/vitest.config.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/utils/amounts.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/scripts/seed-paykit.ts
  • apps/medusa-be/medusa-config.ts
  • apps/medusa-be/src/modules/payment-paykit/config.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/services/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/services/stripe.ts
  • apps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.ts
  • apps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.ts
  • apps/medusa-be/src/modules/payment-paykit/utils/mappers.ts
  • apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts
  • apps/medusa-be/src/workflows/seed/paykit-payment-providers.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/amounts.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/types/index.ts
  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
  • apps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.ts
  • apps/medusa-be/src/modules/payment-paykit/core/base.ts
apps/medusa-be/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

Run bunx biome check --write . to lint and auto-format code

Files:

  • apps/medusa-be/src/modules/payment-paykit/services/gopay.ts
  • apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts
  • apps/medusa-be/vitest.config.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/utils/amounts.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/scripts/seed-paykit.ts
  • apps/medusa-be/medusa-config.ts
  • apps/medusa-be/src/modules/payment-paykit/config.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/services/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/services/stripe.ts
  • apps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.ts
  • apps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.ts
  • apps/medusa-be/src/modules/payment-paykit/utils/mappers.ts
  • apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts
  • apps/medusa-be/src/workflows/seed/paykit-payment-providers.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/amounts.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/types/index.ts
  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
  • apps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.ts
  • apps/medusa-be/src/modules/payment-paykit/core/base.ts
apps/medusa-be/src/**/*.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/src/**/*.ts: Use const and explicit typing with dbService.sqlRaw<Type>() for SQL query results
Resolve logger using container.resolve<Logger>(ContainerRegistrationKeys.LOGGER)
Resolve Query using container.resolve<Query>(ContainerRegistrationKeys.QUERY)
Use Modules.LOCKING (not Modules.LOCK) to resolve locking services
Use Modules.CACHING (not Modules.CACHE) to resolve caching services
Throw MedusaError with appropriate type and message for error responses
Use MedusaError.Types.INVALID_DATA for 400 validation errors
Use MedusaError.Types.NOT_FOUND for 404 errors
Use MedusaError.Types.UNAUTHORIZED for 401 authentication errors
Use MedusaError.Types.NOT_ALLOWED for 400 permission errors
Use MedusaError.Types.DUPLICATE_ERROR for 422 duplicate entry errors
Use MedusaError.Types.CONFLICT for 409 conflict errors
Use caching module's computeKey() to generate stable cache keys from filters and pagination
Use caching module's get() with type assertion for cache retrieval
Use caching module's set() with TTL and tags for cache storage and bulk invalidation
Use caching module's clear() with tags to bulk-invalidate related cache entries
Always use Redis for caching in multi-container deployments instead of local variables
Batch operations using CHUNK_SIZE constant instead of unbounded loops

Files:

  • apps/medusa-be/src/modules/payment-paykit/services/gopay.ts
  • apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/utils/amounts.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/scripts/seed-paykit.ts
  • apps/medusa-be/src/modules/payment-paykit/config.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/services/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/services/stripe.ts
  • apps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.ts
  • apps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.ts
  • apps/medusa-be/src/modules/payment-paykit/utils/mappers.ts
  • apps/medusa-be/src/workflows/seed/paykit-payment-providers.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/amounts.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/types/index.ts
  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
  • apps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.ts
  • apps/medusa-be/src/modules/payment-paykit/core/base.ts
apps/medusa-be/src/modules/**/*.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

Modules use isolated containers; Query/Link unavailable during service initialization, defer to onApplicationStart

Files:

  • apps/medusa-be/src/modules/payment-paykit/services/gopay.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/utils/amounts.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/config.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/services/comgate.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/services/stripe.ts
  • apps/medusa-be/src/modules/payment-paykit/utils/mappers.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/amounts.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/types/index.ts
  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
  • apps/medusa-be/src/modules/payment-paykit/core/base.ts
apps/medusa-be/src/api/**/*

📄 CodeRabbit inference engine (CLAUDE.md)

Place custom Medusa backend API endpoints under apps/medusa-be/src/api

Files:

  • apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts
apps/medusa-be/src/api/**/*.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/src/api/**/*.ts: Use req.scope.resolve() to access container in routes
Colocate validators.ts and middlewares.ts with each route file in the same directory
Use validateAndTransformBody(Schema) middleware for POST/PUT request validation
Use validateAndTransformQuery(Schema) middleware for GET request query parameter validation
Use req.validatedBody in route handlers for type-safe access to validated request body

Files:

  • apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use Vitest for running tests in backend and UI library projects

Files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.ts
  • apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/amounts.unit.spec.ts
apps/medusa-be/src/modules/*/__tests__/*.spec.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/src/modules/*/__tests__/*.spec.ts: Use moduleIntegrationTestRunner() for module tests with real DB instead of mocking MedusaService methods
Mock loaders in tests using vi.mock() to prevent actual initialization during testing
Wrap missing dependency resolution in try/catch in integration tests; Awilix throws even with nullish coalescing

Files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/amounts.unit.spec.ts
apps/medusa-be/src/scripts/**/*.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/src/scripts/**/*.ts: Use medusa exec ./path/to/script.ts [args] to run one-off scripts instead of creating HTTP endpoints
Use script pattern npx medusa exec ./src/scripts/startup.ts in startup hooks
Use destructive operations in medusa exec scripts, never in unprotected GET endpoints

Files:

  • apps/medusa-be/src/scripts/seed-paykit.ts
apps/medusa-be/**/medusa-config.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

Use feature flag env vars in medusa-config.ts evaluated at BUILD time, not runtime

Files:

  • apps/medusa-be/medusa-config.ts
apps/medusa-be/src/workflows/**/*

📄 CodeRabbit inference engine (CLAUDE.md)

Place business logic workflows under apps/medusa-be/src/workflows

Files:

  • apps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.ts
  • apps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.ts
  • apps/medusa-be/src/workflows/seed/paykit-payment-providers.ts
  • apps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.ts
apps/medusa-be/src/workflows/**/*.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/src/workflows/**/*.ts: Use the second parameter { container } object to access container in workflow steps
Use createStep() to define workflow steps with input validation and response wrapping
Use createWorkflow() to define multi-step business logic with rollback support
Return new StepResponse() from workflow steps to pass data to next steps
Return new WorkflowResponse() from workflows to pass final result to caller
Use transform() in workflows for data manipulation only; cannot contain side effects
Use when().then() for conditional logic in workflows instead of if statements
Do not reassign or iterate workflow variables; variable definitions are static at definition time
Use useQueryGraphStep() for Query operations within workflows
Use acquireLockStep(), releaseLockStep() for workflow-level locking instead of manual job locking

Files:

  • apps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.ts
  • apps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.ts
  • apps/medusa-be/src/workflows/seed/paykit-payment-providers.ts
  • apps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.ts
apps/medusa-be/tests/unit/**/*.unit.spec.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/tests/unit/**/*.unit.spec.ts: Focus unit tests on critical paths: validation, money calculations, and core business logic
Skip unit tests for: getters, static arrays, trivial transforms, constants, and pass-through methods
Do not test mocked methods; test real behavior instead
Do not test query.graph() pass-through calls in unit tests
Do not test logging calls; they are implementation details
Use factory functions like createMockEntity(overrides) for test data generation
Use it.each() to test multiple error cases and boundary conditions
Use vi.useFakeTimers() for deterministic time-based testing; use vi.setSystemTime() for absolute time
Clear mocks with mockFn.mockReset() instead of vi.clearAllMocks() for mockResolvedValueOnce chains

Files:

  • apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts
🧠 Learnings (5)
📚 Learning: 2026-05-07T22:45:20.745Z
Learnt from: BleedingDev
Repo: TechsioCZ/new-engine PR: 397
File: docker/development/medusa-be/Dockerfile:34-38
Timestamp: 2026-05-07T22:45:20.745Z
Learning: For pnpm-based monorepo Dockerfiles that run `pnpm fetch --frozen-lockfile`, ensure the `patches/` directory is copied into the image (e.g., `COPY patches ./patches`) before running `pnpm fetch`. pnpm’s `fetch` reads `patchedDependencies` from the lockfile/workspace configuration and will fail (e.g., `ERR_PNPM_PATCH_NOT_FOUND`) if patch files aren’t present yet—do not move the `COPY patches` step to after `pnpm fetch`.

Applied to files:

  • docker/development/payload/Dockerfile
  • docker/development/medusa-be/Dockerfile
  • docker/development/n1/Dockerfile
📚 Learning: 2026-05-07T22:45:38.566Z
Learnt from: BleedingDev
Repo: TechsioCZ/new-engine PR: 397
File: docker/development/n1/Dockerfile:40-44
Timestamp: 2026-05-07T22:45:38.566Z
Learning: When building this repo in Docker, ensure the `patches/` directory is copied into the image (e.g., `COPY patches ./patches`) before running `pnpm fetch --frozen-lockfile`. `pnpm fetch` validates `patchedDependencies` patch file paths from `pnpm-workspace.yaml`/`package.json`, and if `./patches` doesn’t exist yet it will fail with `ERR_PNPM_PATCH_NOT_FOUND`. Place the `COPY patches` step before the `RUN pnpm fetch` step in the relevant service Dockerfiles; this ordering is intentional and should not be flagged as an unnecessary cache-busting change.

Applied to files:

  • docker/development/payload/Dockerfile
  • docker/development/medusa-be/Dockerfile
  • docker/development/n1/Dockerfile
📚 Learning: 2026-02-05T14:43:17.404Z
Learnt from: KaiUweCZE
Repo: NMIT-WR/new-engine PR: 324
File: apps/medusa-be/package.json:0-0
Timestamp: 2026-02-05T14:43:17.404Z
Learning: Validate and enforce React 19 compatibility across monorepo workspaces. Since Medusa UI supports React 19 via root package.json overrides and Medusa Cloud prerequisites show React 19 overrides for npm workspaces, ensure workspace root and all relevant package.json files align with React 19 (18+ requirement is satisfied). When reviewing, verify that overrides exist in the root package.json and that dependent packages in apps or packages directories declare React 19 (or compatible) in their peerDependencies or dependencies as appropriate for workspace usage.

Applied to files:

  • libs/storefront-data/package.json
  • apps/n1/package.json
  • apps/frontend-demo/package.json
  • package.json
  • apps/medusa-be/package.json
📚 Learning: 2026-05-07T19:05:58.339Z
Learnt from: redeyecz
Repo: TechsioCZ/new-engine PR: 390
File: apps/medusa-be/package.json:78-81
Timestamp: 2026-05-07T19:05:58.339Z
Learning: When reviewing changes to `package.json`, do not automatically flag dependency additions/removals as "manually edited" or as "bypassing the pnpm lockfile" just because the `package.json` diff shows only that file changed. First verify whether `pnpm-lock.yaml` is missing the corresponding entries. Since `pnpm add` updates both `package.json` and `pnpm-lock.yaml` together, legitimate changes can appear in the `package.json` diff while still being properly tracked in the lockfile.

Applied to files:

  • libs/storefront-data/package.json
  • apps/n1/package.json
  • apps/frontend-demo/package.json
  • package.json
  • apps/medusa-be/package.json
📚 Learning: 2026-02-25T14:46:02.729Z
Learnt from: redeyecz
Repo: TechsioCZ/new-engine PR: 335
File: apps/zane-operator/src/db.ts:205-207
Timestamp: 2026-02-25T14:46:02.729Z
Learning: Enforce PostgreSQL 18+ as the minimum version across docker-compose files. Since the repo uses postgres:18.1-alpine (evidence in docker-compose.yaml), ensure all docker-compose service images for PostgreSQL use 18.1-alpine or newer. When reviewing, look for postgres images with a tag below 18 (e.g., postgres:<older-version>) and update to 18.1-alpine or a newer compatible tag. This guideline applies to all docker-compose YAML files that define PostgreSQL services.

Applied to files:

  • docker-compose.yaml
🪛 dotenv-linter (4.0.0)
.env.docker

[warning] 50-50: [UnorderedKey] The DC_FEATURE_PAYKIT_COMGATE_ENABLED key should go before the DC_FEATURE_PAYKIT_ENABLED key

(UnorderedKey)


[warning] 52-52: [UnorderedKey] The DC_PAYKIT_CLOUD_API_KEY key should go before the DC_PAYKIT_DEBUG key

(UnorderedKey)


[warning] 64-64: [UnorderedKey] The DC_COMGATE_SANDBOX key should go before the DC_COMGATE_SECRET key

(UnorderedKey)


[warning] 66-66: [UnorderedKey] The DC_COMGATE_PAYMENT_LABEL key should go before the DC_COMGATE_SANDBOX key

(UnorderedKey)

🔇 Additional comments (27)
apps/medusa-be/src/modules/payment-paykit/README.md (1)

1-42: LGTM!

pnpm-workspace.yaml (1)

5-5: LGTM!

package.json (1)

89-89: LGTM!

docker/development/medusa-be/Dockerfile (1)

33-33: LGTM!

Also applies to: 56-56

docker/development/payload/Dockerfile (1)

32-32: LGTM!

Also applies to: 50-50

docker/development/n1/Dockerfile (1)

39-39: LGTM!

Also applies to: 68-68

apps/n1/package.json (1)

23-24: ⚡ Quick win

Lockfile is correctly updated with the dependency versions.

Both @medusajs/js-sdk and @medusajs/types are present in pnpm-lock.yaml at version 2.15.2 with specifiers matching package.json. No further action required.

.mise.toml (1)

82-84: LGTM!

apps/medusa-be/vitest.config.ts (1)

4-28: LGTM!

apps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.ts (1)

1-42: LGTM!

apps/medusa-be/src/modules/payment-paykit/utils/amounts.ts (1)

1-99: LGTM!

.env.docker (1)

46-70: LGTM!

apps/medusa-be/src/modules/payment-paykit/config.ts (1)

1-60: LGTM!

apps/medusa-be/src/workflows/seed/paykit-payment-providers.ts (1)

1-46: LGTM!

apps/medusa-be/src/modules/payment-paykit/types/index.ts (1)

1-173: LGTM!

apps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.ts (1)

1-93: LGTM!

apps/medusa-be/src/modules/payment-paykit/core/base.ts (1)

748-780: LGTM!

apps/medusa-be/src/modules/payment-paykit/__tests__/helpers.ts (1)

1-76: LGTM!

apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.ts (1)

1-434: LGTM!

docker-compose.yaml (1)

67-84: LGTM!

apps/medusa-be/src/modules/payment-paykit/__tests__/amounts.unit.spec.ts (1)

1-51: LGTM!

apps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.ts (1)

1-101: LGTM!

apps/medusa-be/src/modules/payment-paykit/webhooks.ts (1)

1-97: LGTM!

apps/medusa-be/src/scripts/seed-paykit.ts (1)

1-199: LGTM!

apps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.ts (1)

1-304: LGTM!

apps/medusa-be/src/modules/payment-paykit/services/comgate.ts (1)

1-157: LGTM!

apps/medusa-be/src/modules/payment-paykit/services/stripe.ts (1)

1-259: LGTM!

Comment thread apps/frontend-demo/package.json
Comment thread apps/medusa-be/medusa-config.ts Outdated
Comment thread apps/medusa-be/medusa-config.ts Outdated
Comment thread apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts Outdated
Comment thread apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts Outdated
Comment thread apps/medusa-be/src/modules/payment-paykit/runtime.ts Outdated
Comment thread apps/medusa-be/src/modules/payment-paykit/utils/mappers.ts Outdated
Comment thread apps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.ts Outdated
Comment thread apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts Outdated
Comment thread libs/storefront-data/package.json
@greptile-apps

greptile-apps Bot commented May 14, 2026

Copy link
Copy Markdown

Greptile Summary

This PR introduces a local Medusa v2 PayKit payment module with three providers (GoPay, Stripe, Comgate), a dedicated GET webhook bridge for GoPay, feature-flag-driven configuration, a seed workflow for region/provider wiring, and focused unit tests.

  • Payment providers: A shared PaykitPaymentProviderBase handles initiation, capture, refund, cancel, account holders, and webhook dispatch; each provider subclass overrides amount normalisation and webhook amount denormalisation.
  • GoPay webhook bridge: A custom GET /hooks/payment/paykit_gopay route reconstructs the full URL from forwarded headers and emits a PaymentWebhookEvents.WebhookReceived event; errors are absorbed internally so the callback always acknowledges with 200.
  • Stripe fallback: PaykitStripePaymentProvider catches WEBHOOK_ERROR for unhandled payment_intent.* events that PayKit Stripe has already verified, maps them to PayKit event types, and routes them through mapPaykitWebhookEvent.

Confidence Score: 5/5

Safe to merge; the payment flow is well-guarded end-to-end with two minor, low-impact issues in utility helpers.

The provider logic is thoroughly unit-tested and all critical paths behave correctly for the supported currencies and providers. The two noted issues only affect edge cases unlikely to arise in production with the current provider set.

core/base.ts (getCurrencyCode helper) and utils/amounts.ts (toStripeSmallestCurrencyUnit) deserve a second look before enabling three-decimal Stripe currencies or PayKit providers that return currency_code rather than currency.

Important Files Changed

Filename Overview
apps/medusa-be/src/modules/payment-paykit/core/base.ts Core abstract payment provider — well-structured with good error handling. Minor: getCurrencyCode checks only data.currency, missing data.currency_code; inconsistent with webhook normalization overrides.
apps/medusa-be/src/modules/payment-paykit/utils/amounts.ts Currency unit conversion utilities. toStripeSmallestCurrencyUnit uses Math.ceil for three-decimal Stripe currencies; Stripe's spec requires truncation (Math.floor).
apps/medusa-be/src/modules/payment-paykit/utils/mappers.ts Webhook event mapping and status translation. Correctly handles all PayKit event types and guards invoice.generated against missing session/amount.
apps/medusa-be/src/modules/payment-paykit/services/stripe.ts Stripe provider with fallback for unhandled payment_intent events — well-guarded with verified-signature-only fallback and correct status mapping.
apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts GoPay GET webhook bridge that validates the payment id query parameter before forwarding to the event bus.
apps/medusa-be/src/modules/payment-paykit/runtime.ts Dynamic PayKit SDK loader using new Function to bypass bundler tree-shaking; constructs webhook payloads with correct protocol/host resolution.
apps/medusa-be/src/scripts/seed-paykit.ts Idempotent seed script that wires enabled PayKit providers to Medusa regions, merging with existing payment providers.
apps/medusa-be/medusa-config.ts Adds the first explicit @medusajs/medusa/payment module registration, wiring PayKit providers. MEDUSA_COOKIE_SAME_SITE is now narrowed to a typed union instead of a cast.

Sequence Diagram

sequenceDiagram
    participant SF as Storefront
    participant MB as Medusa BE
    participant PK as PayKit SDK
    participant GP as GoPay / Stripe / Comgate

    SF->>MB: initiatePayment (session_id, amount, customer)
    MB->>PK: payments.create(normalizedAmount, metadata)
    PK->>GP: Create payment
    GP-->>PK: payment (id, payment_url)
    PK-->>MB: PaykitPayment
    MB-->>SF: payment_url + session data

    SF->>SF: Customer completes payment

    GP-->>MB: POST /hooks/payment/provider or GET /hooks/payment/paykit_gopay
    MB->>MB: emitPaykitPaymentWebhookEvent
    MB->>MB: EventBus.emit(WebhookReceived)
    MB->>PK: handleWebhook(body, headers, fullUrl)
    PK-->>MB: PaykitWebhookEvent[]
    MB->>MB: mapPaykitWebhookEvent to WebhookActionResult
    MB->>MB: Medusa session update AUTHORIZED or SUCCESSFUL
Loading

Fix All in Codex

Reviews (2): Last reviewed commit: "fix(paykit): rabbit code & greptile revi..." | Re-trigger Greptile

Comment thread apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts Outdated
Comment thread apps/medusa-be/src/modules/payment-paykit/core/base.ts
Comment thread apps/medusa-be/src/modules/payment-paykit/config.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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 `@apps/medusa-be/medusa-config.ts`:
- Around line 33-81: The config currently registers providers with potentially
undefined credentials; update the PAYKIT_PAYMENT_PROVIDERS assembly so that when
FEATURE_PAYKIT_GOPAY_ENABLED, FEATURE_PAYKIT_STRIPE_ENABLED, or
FEATURE_PAYKIT_COMGATE_ENABLED is true you validate the required env vars and
PAYKIT_CLOUD_API_KEY up front and throw a clear Error listing any missing
variables instead of registering the provider. Locate the
PAYKIT_PAYMENT_PROVIDERS constant and, for each provider block (identify by
PAYKIT_GOPAY_PROVIDER_ID, PAYKIT_STRIPE_PROVIDER_ID,
PAYKIT_COMGATE_PROVIDER_ID), check the specific required keys (e.g.
GOPAY_CLIENT_ID, GOPAY_CLIENT_SECRET, GOPAY_GO_ID for GoPay; STRIPE_API_KEY,
STRIPE_WEBHOOK_SECRET for Stripe; COMGATE_MERCHANT, COMGATE_SECRET for Comgate)
plus PAYKIT_CLOUD_API_KEY and isSandbox flags, collect any missing names and
throw a startup Error if any are missing; only push the provider entry when
validation passes.

In `@apps/medusa-be/src/modules/payment-paykit/runtime.ts`:
- Around line 182-185: Replace the unchecked cast of payload.data with a guarded
narrowing: assign payload.data to an unknown (e.g., rawData) and use an isRecord
type guard (or implement one) to ensure it's an object before reading/renaming
properties; inside the guarded branch narrow to the expected shape and then read
fullUrl / full_url / url. Update references to the original local variable
(currently named data) so all downstream usage occurs only inside the
isRecord-validated block.
- Around line 73-82: The code casts createProvider(providerOptions) to
PaykitProviderRuntime and immediately uses provider.handleWebhook, which can
throw if the provider lacks that function; add a runtime guard after creating
provider (created via createProvider) to verify typeof provider.handleWebhook
=== "function" before wiring handleWebhook in the returned object, and if the
check fails throw a clear Error (e.g. "Provider does not implement
handleWebhook") so callers fail fast; keep the rest of the return object
(customers/payments/refunds) unchanged and still call
toPaykitWebhookPayload(payload, webhookOptions) only when the guard passes.

In `@apps/medusa-be/src/modules/payment-paykit/utils/mappers.ts`:
- Around line 37-47: The toBigNumberValue function currently uses an unchecked
cast (value as BigNumberInput) before constructing BigNumber; instead add a
runtime guard: first handle typeof value === "number" || typeof value ===
"string" (return as now), then check if value is already a BigNumber instance
(e.g., value instanceof BigNumber) and return it, and only then call new
BigNumber(value) without any type assertion; ensure the try/catch wraps only the
new BigNumber call and remove the "as" cast so the value passed is the
runtime-validated variable.

In `@apps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.ts`:
- Around line 19-21: The filter creating regionsToSync uses runtime truthiness
but doesn't narrow types for TypeScript; replace the predicate with a proper
type guard (e.g., a function like hasIdAndCurrency(region): region is Region & {
id: string }) or an inline type predicate ((region): region is Region & { id:
string } => !!region.id && region.currencyCode.trim()) so that regionsToSync
elements are guaranteed to have a non-optional id (and non-empty currencyCode),
then use that narrowed type where region.id is accessed later (e.g., in the code
that reads region.id).
🪄 Autofix (Beta)

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

Run ID: c3128286-9f93-44c8-85fb-a096f705d94c

📥 Commits

Reviewing files that changed from the base of the PR and between 83f921e and 4066c82.

📒 Files selected for processing (9)
  • apps/medusa-be/medusa-config.ts
  • apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
  • apps/medusa-be/src/modules/payment-paykit/utils/mappers.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.ts
  • apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts
  • apps/medusa-be/vitest.config.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Greptile Review
  • GitHub Check: main
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Kilo Code Review
🧰 Additional context used
📓 Path-based instructions (15)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Import UI components using the pattern import { ComponentName } from '@libs/ui/atoms/component-name' or '@libs/ui/molecules/component-name'

Files:

  • apps/medusa-be/vitest.config.ts
  • apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts
  • apps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts
  • apps/medusa-be/medusa-config.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/utils/mappers.ts
  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
apps/medusa-be/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/**/*.{ts,tsx}: Run npx tsc --noEmit for typechecking before committing
Always use braces around conditional blocks, even for single statements; Biome will expand them
Declare one variable per const/let statement, not multiple on one line
Use nullish coalescing operator (??) instead of logical OR (||) for default values
Do not use non-null assertions (!); use type guards or validation instead
Annotate type as unknown when accessing dynamic object properties before applying type guards
Use comments only to explain 'why', never 'what'; self-document code with clear naming
Extract pure functions to separate files for testability without runtime dependencies
Use Modules.* and ContainerRegistrationKeys.* constants instead of hardcoding module/key strings
Do not use non-null assertions in TypeScript code; validate or use type guards instead
Validate data before type casting; never use as Type without prior validation

Files:

  • apps/medusa-be/vitest.config.ts
  • apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts
  • apps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts
  • apps/medusa-be/medusa-config.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/utils/mappers.ts
  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
apps/medusa-be/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

Run bunx biome check --write . to lint and auto-format code

Files:

  • apps/medusa-be/vitest.config.ts
  • apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts
  • apps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts
  • apps/medusa-be/medusa-config.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/utils/mappers.ts
  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use Vitest for running tests in backend and UI library projects

Files:

  • apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
apps/medusa-be/tests/unit/**/*.unit.spec.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/tests/unit/**/*.unit.spec.ts: Focus unit tests on critical paths: validation, money calculations, and core business logic
Skip unit tests for: getters, static arrays, trivial transforms, constants, and pass-through methods
Do not test mocked methods; test real behavior instead
Do not test query.graph() pass-through calls in unit tests
Do not test logging calls; they are implementation details
Use factory functions like createMockEntity(overrides) for test data generation
Use it.each() to test multiple error cases and boundary conditions
Use vi.useFakeTimers() for deterministic time-based testing; use vi.setSystemTime() for absolute time
Clear mocks with mockFn.mockReset() instead of vi.clearAllMocks() for mockResolvedValueOnce chains

Files:

  • apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts
apps/medusa-be/src/workflows/**/*

📄 CodeRabbit inference engine (CLAUDE.md)

Place business logic workflows under apps/medusa-be/src/workflows

Files:

  • apps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.ts
apps/medusa-be/src/{api,modules,workflows,admin,subscribers,jobs}/**

📄 CodeRabbit inference engine (AGENTS.md)

In Medusa backend applications, organize custom code using the directory structure: api/, modules/, workflows/, admin/, subscribers/, jobs/

Files:

  • apps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/utils/mappers.ts
  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
apps/medusa-be/src/**/*.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/src/**/*.ts: Use const and explicit typing with dbService.sqlRaw<Type>() for SQL query results
Resolve logger using container.resolve<Logger>(ContainerRegistrationKeys.LOGGER)
Resolve Query using container.resolve<Query>(ContainerRegistrationKeys.QUERY)
Use Modules.LOCKING (not Modules.LOCK) to resolve locking services
Use Modules.CACHING (not Modules.CACHE) to resolve caching services
Throw MedusaError with appropriate type and message for error responses
Use MedusaError.Types.INVALID_DATA for 400 validation errors
Use MedusaError.Types.NOT_FOUND for 404 errors
Use MedusaError.Types.UNAUTHORIZED for 401 authentication errors
Use MedusaError.Types.NOT_ALLOWED for 400 permission errors
Use MedusaError.Types.DUPLICATE_ERROR for 422 duplicate entry errors
Use MedusaError.Types.CONFLICT for 409 conflict errors
Use caching module's computeKey() to generate stable cache keys from filters and pagination
Use caching module's get() with type assertion for cache retrieval
Use caching module's set() with TTL and tags for cache storage and bulk invalidation
Use caching module's clear() with tags to bulk-invalidate related cache entries
Always use Redis for caching in multi-container deployments instead of local variables
Batch operations using CHUNK_SIZE constant instead of unbounded loops

Files:

  • apps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.ts
  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/utils/mappers.ts
  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
apps/medusa-be/src/workflows/**/*.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/src/workflows/**/*.ts: Use the second parameter { container } object to access container in workflow steps
Use createStep() to define workflow steps with input validation and response wrapping
Use createWorkflow() to define multi-step business logic with rollback support
Return new StepResponse() from workflow steps to pass data to next steps
Return new WorkflowResponse() from workflows to pass final result to caller
Use transform() in workflows for data manipulation only; cannot contain side effects
Use when().then() for conditional logic in workflows instead of if statements
Do not reassign or iterate workflow variables; variable definitions are static at definition time
Use useQueryGraphStep() for Query operations within workflows
Use acquireLockStep(), releaseLockStep() for workflow-level locking instead of manual job locking

Files:

  • apps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.ts
apps/medusa-be/src/modules/**/*

📄 CodeRabbit inference engine (CLAUDE.md)

Place custom Medusa modules under apps/medusa-be/src/modules

Module directories use hyphens (my-module/), but module keys in config use underscores (my_module)

Files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/utils/mappers.ts
  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
apps/medusa-be/src/modules/*/__tests__/*.spec.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/src/modules/*/__tests__/*.spec.ts: Use moduleIntegrationTestRunner() for module tests with real DB instead of mocking MedusaService methods
Mock loaders in tests using vi.mock() to prevent actual initialization during testing
Wrap missing dependency resolution in try/catch in integration tests; Awilix throws even with nullish coalescing

Files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
apps/medusa-be/src/modules/**/*.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

Modules use isolated containers; Query/Link unavailable during service initialization, defer to onApplicationStart

Files:

  • apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts
  • apps/medusa-be/src/modules/payment-paykit/webhooks.ts
  • apps/medusa-be/src/modules/payment-paykit/utils/mappers.ts
  • apps/medusa-be/src/modules/payment-paykit/runtime.ts
apps/medusa-be/src/api/**/*

📄 CodeRabbit inference engine (CLAUDE.md)

Place custom Medusa backend API endpoints under apps/medusa-be/src/api

Files:

  • apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts
apps/medusa-be/src/api/**/*.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

apps/medusa-be/src/api/**/*.ts: Use req.scope.resolve() to access container in routes
Colocate validators.ts and middlewares.ts with each route file in the same directory
Use validateAndTransformBody(Schema) middleware for POST/PUT request validation
Use validateAndTransformQuery(Schema) middleware for GET request query parameter validation
Use req.validatedBody in route handlers for type-safe access to validated request body

Files:

  • apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts
apps/medusa-be/**/medusa-config.ts

📄 CodeRabbit inference engine (apps/medusa-be/CLAUDE.md)

Use feature flag env vars in medusa-config.ts evaluated at BUILD time, not runtime

Files:

  • apps/medusa-be/medusa-config.ts
🔇 Additional comments (8)
apps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.ts (3)

1-15: LGTM!


19-25: LGTM!


27-34: LGTM!

apps/medusa-be/vitest.config.ts (1)

4-7: LGTM!

Also applies to: 14-20, 31-31

apps/medusa-be/src/modules/payment-paykit/webhooks.ts (1)

48-87: LGTM!

apps/medusa-be/src/api/hooks/payment/paykit_gopay/route.ts (1)

66-107: LGTM!

apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.ts (1)

83-200: LGTM!

apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.ts (1)

21-148: LGTM!

Comment thread apps/medusa-be/medusa-config.ts Outdated
Comment thread apps/medusa-be/src/modules/payment-paykit/runtime.ts Outdated
Comment thread apps/medusa-be/src/modules/payment-paykit/runtime.ts Outdated
Comment thread apps/medusa-be/src/modules/payment-paykit/utils/mappers.ts
Comment thread apps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.ts Outdated
redeyecz added 24 commits May 14, 2026 12:14
…ly, split delete/cancelPayment due to medusa rollback behaviour
… paykit <> medusa handling, stricter type definitions for paykit types
…dded Readme to document why we're not using paykit medusa adapter
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant