Add Medusa PayKit payment providers - #406
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Blacksmith Account SuspendedThis 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. |
|
Warning Rate limit exceeded
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 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 configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (43)
WalkthroughAdds 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. ChangesPayKit Payment Provider Integration
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes ✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
|
There was a problem hiding this comment.
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
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (31)
.env.dockerapps/medusa-be/medusa-config.tsapps/medusa-be/package.jsonapps/medusa-be/src/api/hooks/payment/paykit_gopay/route.tsapps/medusa-be/src/modules/payment-paykit/README.mdapps/medusa-be/src/modules/payment-paykit/__tests__/amounts.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/helpers.tsapps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/amounts.tsapps/medusa-be/src/modules/payment-paykit/base.tsapps/medusa-be/src/modules/payment-paykit/comgate.tsapps/medusa-be/src/modules/payment-paykit/config.tsapps/medusa-be/src/modules/payment-paykit/gopay.tsapps/medusa-be/src/modules/payment-paykit/mappers.tsapps/medusa-be/src/modules/payment-paykit/runtime.tsapps/medusa-be/src/modules/payment-paykit/stripe.tsapps/medusa-be/src/modules/payment-paykit/types.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/scripts/seed-paykit.tsapps/medusa-be/src/workflows/seed/paykit-payment-providers.tsapps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.tsapps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.tsapps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.tsapps/medusa-be/vitest.config.tsapps/n1/src/data/static/categories.tsapps/n1/src/services/cart-service.tsdocker-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.tsapps/medusa-be/src/modules/payment-paykit/README.mdapps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/__tests__/helpers.tsapps/medusa-be/src/modules/payment-paykit/comgate.tsapps/medusa-be/src/modules/payment-paykit/stripe.tsapps/medusa-be/src/modules/payment-paykit/gopay.tsapps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/config.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/amounts.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/runtime.tsapps/medusa-be/src/modules/payment-paykit/types.tsapps/medusa-be/src/modules/payment-paykit/mappers.tsapps/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.tsapps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.tsapps/medusa-be/src/api/hooks/payment/paykit_gopay/route.tsapps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.tsapps/medusa-be/src/workflows/seed/paykit-payment-providers.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/__tests__/helpers.tsapps/medusa-be/src/scripts/seed-paykit.tsapps/medusa-be/src/modules/payment-paykit/comgate.tsapps/medusa-be/src/modules/payment-paykit/stripe.tsapps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.tsapps/n1/src/services/cart-service.tsapps/medusa-be/src/modules/payment-paykit/gopay.tsapps/medusa-be/vitest.config.tsapps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/config.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.tsapps/medusa-be/medusa-config.tsapps/medusa-be/src/modules/payment-paykit/amounts.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/runtime.tsapps/medusa-be/src/modules/payment-paykit/types.tsapps/medusa-be/src/modules/payment-paykit/mappers.tsapps/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.tsapps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.tsapps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/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.tsapps/medusa-be/src/modules/payment-paykit/README.mdapps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.tsapps/medusa-be/src/api/hooks/payment/paykit_gopay/route.tsapps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.tsapps/medusa-be/src/workflows/seed/paykit-payment-providers.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/__tests__/helpers.tsapps/medusa-be/src/modules/payment-paykit/comgate.tsapps/medusa-be/src/modules/payment-paykit/stripe.tsapps/medusa-be/src/modules/payment-paykit/gopay.tsapps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/config.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.tsapps/medusa-be/src/modules/payment-paykit/amounts.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/runtime.tsapps/medusa-be/src/modules/payment-paykit/types.tsapps/medusa-be/src/modules/payment-paykit/mappers.tsapps/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}: Runnpx tsc --noEmitfor typechecking before committing
Always use braces around conditional blocks, even for single statements; Biome will expand them
Declare one variable perconst/letstatement, 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 asunknownwhen 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
UseModules.*andContainerRegistrationKeys.*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 useas Typewithout prior validation
Files:
apps/medusa-be/src/modules/payment-paykit/__tests__/amounts.unit.spec.tsapps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.tsapps/medusa-be/src/api/hooks/payment/paykit_gopay/route.tsapps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.tsapps/medusa-be/src/workflows/seed/paykit-payment-providers.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/__tests__/helpers.tsapps/medusa-be/src/scripts/seed-paykit.tsapps/medusa-be/src/modules/payment-paykit/comgate.tsapps/medusa-be/src/modules/payment-paykit/stripe.tsapps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/gopay.tsapps/medusa-be/vitest.config.tsapps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/config.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.tsapps/medusa-be/medusa-config.tsapps/medusa-be/src/modules/payment-paykit/amounts.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/runtime.tsapps/medusa-be/src/modules/payment-paykit/types.tsapps/medusa-be/src/modules/payment-paykit/mappers.tsapps/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.tsapps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.tsapps/medusa-be/src/api/hooks/payment/paykit_gopay/route.tsapps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.tsapps/medusa-be/src/workflows/seed/paykit-payment-providers.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/__tests__/helpers.tsapps/medusa-be/src/scripts/seed-paykit.tsapps/medusa-be/src/modules/payment-paykit/comgate.tsapps/medusa-be/src/modules/payment-paykit/stripe.tsapps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/gopay.tsapps/medusa-be/vitest.config.tsapps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/config.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.tsapps/medusa-be/medusa-config.tsapps/medusa-be/src/modules/payment-paykit/amounts.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/runtime.tsapps/medusa-be/src/modules/payment-paykit/types.tsapps/medusa-be/src/modules/payment-paykit/mappers.tsapps/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: Useconstand explicit typing withdbService.sqlRaw<Type>()for SQL query results
Resolve logger usingcontainer.resolve<Logger>(ContainerRegistrationKeys.LOGGER)
Resolve Query usingcontainer.resolve<Query>(ContainerRegistrationKeys.QUERY)
UseModules.LOCKING(notModules.LOCK) to resolve locking services
UseModules.CACHING(notModules.CACHE) to resolve caching services
ThrowMedusaErrorwith appropriate type and message for error responses
UseMedusaError.Types.INVALID_DATAfor 400 validation errors
UseMedusaError.Types.NOT_FOUNDfor 404 errors
UseMedusaError.Types.UNAUTHORIZEDfor 401 authentication errors
UseMedusaError.Types.NOT_ALLOWEDfor 400 permission errors
UseMedusaError.Types.DUPLICATE_ERRORfor 422 duplicate entry errors
UseMedusaError.Types.CONFLICTfor 409 conflict errors
Use caching module'scomputeKey()to generate stable cache keys from filters and pagination
Use caching module'sget()with type assertion for cache retrieval
Use caching module'sset()with TTL and tags for cache storage and bulk invalidation
Use caching module'sclear()with tags to bulk-invalidate related cache entries
Always use Redis for caching in multi-container deployments instead of local variables
Batch operations usingCHUNK_SIZEconstant instead of unbounded loops
Files:
apps/medusa-be/src/modules/payment-paykit/__tests__/amounts.unit.spec.tsapps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.tsapps/medusa-be/src/api/hooks/payment/paykit_gopay/route.tsapps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.tsapps/medusa-be/src/workflows/seed/paykit-payment-providers.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/__tests__/helpers.tsapps/medusa-be/src/scripts/seed-paykit.tsapps/medusa-be/src/modules/payment-paykit/comgate.tsapps/medusa-be/src/modules/payment-paykit/stripe.tsapps/medusa-be/src/modules/payment-paykit/gopay.tsapps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/config.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.tsapps/medusa-be/src/modules/payment-paykit/amounts.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/runtime.tsapps/medusa-be/src/modules/payment-paykit/types.tsapps/medusa-be/src/modules/payment-paykit/mappers.tsapps/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: UsemoduleIntegrationTestRunner()for module tests with real DB instead of mocking MedusaService methods
Mock loaders in tests usingvi.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.tsapps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/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.tsapps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/__tests__/helpers.tsapps/medusa-be/src/modules/payment-paykit/comgate.tsapps/medusa-be/src/modules/payment-paykit/stripe.tsapps/medusa-be/src/modules/payment-paykit/gopay.tsapps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/config.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/amounts.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/runtime.tsapps/medusa-be/src/modules/payment-paykit/types.tsapps/medusa-be/src/modules/payment-paykit/mappers.tsapps/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.tsapps/medusa-be/src/workflows/seed/paykit-payment-providers.tsapps/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
UsecreateStep()to define workflow steps with input validation and response wrapping
UsecreateWorkflow()to define multi-step business logic with rollback support
Returnnew StepResponse()from workflow steps to pass data to next steps
Returnnew WorkflowResponse()from workflows to pass final result to caller
Usetransform()in workflows for data manipulation only; cannot contain side effects
Usewhen().then()for conditional logic in workflows instead of if statements
Do not reassign or iterate workflow variables; variable definitions are static at definition time
UseuseQueryGraphStep()for Query operations within workflows
UseacquireLockStep(),releaseLockStep()for workflow-level locking instead of manual job locking
Files:
apps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.tsapps/medusa-be/src/workflows/seed/paykit-payment-providers.tsapps/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: Usereq.scope.resolve()to access container in routes
Colocatevalidators.tsandmiddlewares.tswith each route file in the same directory
UsevalidateAndTransformBody(Schema)middleware for POST/PUT request validation
UsevalidateAndTransformQuery(Schema)middleware for GET request query parameter validation
Usereq.validatedBodyin 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: Usemedusa exec ./path/to/script.ts [args]to run one-off scripts instead of creating HTTP endpoints
Use script patternnpx medusa exec ./src/scripts/startup.tsin startup hooks
Use destructive operations inmedusa execscripts, 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 testquery.graph()pass-through calls in unit tests
Do not test logging calls; they are implementation details
Use factory functions likecreateMockEntity(overrides)for test data generation
Useit.each()to test multiple error cases and boundary conditions
Usevi.useFakeTimers()for deterministic time-based testing; usevi.setSystemTime()for absolute time
Clear mocks withmockFn.mockReset()instead ofvi.clearAllMocks()formockResolvedValueOncechains
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 tokens50-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 likebg-gray-100ortext-blue-500
Do NOT use arbitrary Tailwind values likep-[20px]orbg-[#fff]- use predefined spacing and color tokens only
Userefas a prop pattern in React 19 components instead offorwardRef
Do NOT useuseCallbackhook (React 19 has automatic memoization via the React Compiler)
Import UI components from@libs/uiwith the appropriate directory path:@libs/ui/atoms/<component>for atoms,@libs/ui/molecules/<component>for molecules
Import hooks with theuse-naming convention from@/hooks/<hook-name>directory (e.g.,useCart,useAuth,useOrders)
Import services from@/services/<service-name>directory following the<noun>-servicenaming 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.tsfiles. 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.tsevaluated 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
loadExportfunction 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
getWebhookFullUrlhelper 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
deletePaymenthandles 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
ProviderNotSupportedErroras 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 winExtract 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 asCASH_ON_DELIVERY_PROVIDER = "pp_system_default"defined inpayment-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 winThe constant
pp_system_defaultis 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 winAdd explicit
falsereturn for non-truthy values.The function signature promises a
booleanreturn, but when the value is neither"1"nor"true"(e.g.,"false","0"), the function implicitly returnsundefined, 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!
There was a problem hiding this comment.
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 winConsider creating a typed mock container helper to avoid unsafe type casts.
The tests use
{} as anyto 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 useas Typewithout 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
📒 Files selected for processing (17)
.env.dockerapps/medusa-be/medusa-config.tsapps/medusa-be/src/api/hooks/payment/paykit_gopay/route.tsapps/medusa-be/src/modules/payment-paykit/README.mdapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/base.tsapps/medusa-be/src/modules/payment-paykit/comgate.tsapps/medusa-be/src/modules/payment-paykit/config.tsapps/medusa-be/src/modules/payment-paykit/gopay.tsapps/medusa-be/src/modules/payment-paykit/mappers.tsapps/medusa-be/src/modules/payment-paykit/stripe.tsapps/medusa-be/src/modules/payment-paykit/types.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/scripts/seed-paykit.tsapps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.tsdocker-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.mdapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/config.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/gopay.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/mappers.tsapps/medusa-be/src/modules/payment-paykit/stripe.tsapps/medusa-be/src/modules/payment-paykit/comgate.tsapps/medusa-be/src/modules/payment-paykit/types.tsapps/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.mdapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/api/hooks/payment/paykit_gopay/route.tsapps/medusa-be/src/modules/payment-paykit/config.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.tsapps/medusa-be/src/modules/payment-paykit/gopay.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/mappers.tsapps/medusa-be/src/modules/payment-paykit/stripe.tsapps/medusa-be/src/modules/payment-paykit/comgate.tsapps/medusa-be/src/modules/payment-paykit/types.tsapps/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.tsapps/medusa-be/src/api/hooks/payment/paykit_gopay/route.tsapps/medusa-be/src/modules/payment-paykit/config.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.tsapps/medusa-be/medusa-config.tsapps/medusa-be/src/modules/payment-paykit/gopay.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/mappers.tsapps/medusa-be/src/modules/payment-paykit/stripe.tsapps/medusa-be/src/modules/payment-paykit/comgate.tsapps/medusa-be/src/modules/payment-paykit/types.tsapps/medusa-be/src/scripts/seed-paykit.tsapps/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.tsapps/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}: Runnpx tsc --noEmitfor typechecking before committing
Always use braces around conditional blocks, even for single statements; Biome will expand them
Declare one variable perconst/letstatement, 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 asunknownwhen 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
UseModules.*andContainerRegistrationKeys.*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 useas Typewithout prior validation
Files:
apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/api/hooks/payment/paykit_gopay/route.tsapps/medusa-be/src/modules/payment-paykit/config.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.tsapps/medusa-be/medusa-config.tsapps/medusa-be/src/modules/payment-paykit/gopay.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/mappers.tsapps/medusa-be/src/modules/payment-paykit/stripe.tsapps/medusa-be/src/modules/payment-paykit/comgate.tsapps/medusa-be/src/modules/payment-paykit/types.tsapps/medusa-be/src/scripts/seed-paykit.tsapps/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.tsapps/medusa-be/src/api/hooks/payment/paykit_gopay/route.tsapps/medusa-be/src/modules/payment-paykit/config.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.tsapps/medusa-be/medusa-config.tsapps/medusa-be/src/modules/payment-paykit/gopay.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/mappers.tsapps/medusa-be/src/modules/payment-paykit/stripe.tsapps/medusa-be/src/modules/payment-paykit/comgate.tsapps/medusa-be/src/modules/payment-paykit/types.tsapps/medusa-be/src/scripts/seed-paykit.tsapps/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: Useconstand explicit typing withdbService.sqlRaw<Type>()for SQL query results
Resolve logger usingcontainer.resolve<Logger>(ContainerRegistrationKeys.LOGGER)
Resolve Query usingcontainer.resolve<Query>(ContainerRegistrationKeys.QUERY)
UseModules.LOCKING(notModules.LOCK) to resolve locking services
UseModules.CACHING(notModules.CACHE) to resolve caching services
ThrowMedusaErrorwith appropriate type and message for error responses
UseMedusaError.Types.INVALID_DATAfor 400 validation errors
UseMedusaError.Types.NOT_FOUNDfor 404 errors
UseMedusaError.Types.UNAUTHORIZEDfor 401 authentication errors
UseMedusaError.Types.NOT_ALLOWEDfor 400 permission errors
UseMedusaError.Types.DUPLICATE_ERRORfor 422 duplicate entry errors
UseMedusaError.Types.CONFLICTfor 409 conflict errors
Use caching module'scomputeKey()to generate stable cache keys from filters and pagination
Use caching module'sget()with type assertion for cache retrieval
Use caching module'sset()with TTL and tags for cache storage and bulk invalidation
Use caching module'sclear()with tags to bulk-invalidate related cache entries
Always use Redis for caching in multi-container deployments instead of local variables
Batch operations usingCHUNK_SIZEconstant instead of unbounded loops
Files:
apps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/api/hooks/payment/paykit_gopay/route.tsapps/medusa-be/src/modules/payment-paykit/config.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.tsapps/medusa-be/src/modules/payment-paykit/gopay.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/mappers.tsapps/medusa-be/src/modules/payment-paykit/stripe.tsapps/medusa-be/src/modules/payment-paykit/comgate.tsapps/medusa-be/src/modules/payment-paykit/types.tsapps/medusa-be/src/scripts/seed-paykit.tsapps/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: UsemoduleIntegrationTestRunner()for module tests with real DB instead of mocking MedusaService methods
Mock loaders in tests usingvi.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.tsapps/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.tsapps/medusa-be/src/modules/payment-paykit/config.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/gopay.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/mappers.tsapps/medusa-be/src/modules/payment-paykit/stripe.tsapps/medusa-be/src/modules/payment-paykit/comgate.tsapps/medusa-be/src/modules/payment-paykit/types.tsapps/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: Usereq.scope.resolve()to access container in routes
Colocatevalidators.tsandmiddlewares.tswith each route file in the same directory
UsevalidateAndTransformBody(Schema)middleware for POST/PUT request validation
UsevalidateAndTransformQuery(Schema)middleware for GET request query parameter validation
Usereq.validatedBodyin 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
UsecreateStep()to define workflow steps with input validation and response wrapping
UsecreateWorkflow()to define multi-step business logic with rollback support
Returnnew StepResponse()from workflow steps to pass data to next steps
Returnnew WorkflowResponse()from workflows to pass final result to caller
Usetransform()in workflows for data manipulation only; cannot contain side effects
Usewhen().then()for conditional logic in workflows instead of if statements
Do not reassign or iterate workflow variables; variable definitions are static at definition time
UseuseQueryGraphStep()for Query operations within workflows
UseacquireLockStep(),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.tsevaluated 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: Usemedusa exec ./path/to/script.ts [args]to run one-off scripts instead of creating HTTP endpoints
Use script patternnpx medusa exec ./src/scripts/startup.tsin startup hooks
Use destructive operations inmedusa execscripts, 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 declarationLine 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 Typewithout 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!
There was a problem hiding this comment.
Actionable comments posted: 4
♻️ Duplicate comments (1)
apps/medusa-be/src/scripts/seed-paykit.ts (1)
74-83: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick winAvoid unchecked query type assertion
The
queryobject is force-cast withas 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 Typewithout 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
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (16)
apps/medusa-be/package.jsonapps/medusa-be/src/modules/payment-paykit/README.mdapps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/helpers.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/base.tsapps/medusa-be/src/modules/payment-paykit/comgate.tsapps/medusa-be/src/modules/payment-paykit/stripe.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/scripts/seed-paykit.tsapps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.tsapps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.tsapps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.tsapps/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.mdapps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/helpers.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/comgate.tsapps/medusa-be/src/modules/payment-paykit/stripe.tsapps/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.mdapps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/helpers.tsapps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.tsapps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/comgate.tsapps/medusa-be/src/modules/payment-paykit/stripe.tsapps/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.tsapps/medusa-be/src/modules/payment-paykit/__tests__/helpers.tsapps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.tsapps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/vitest.config.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.tsapps/medusa-be/src/scripts/seed-paykit.tsapps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/comgate.tsapps/medusa-be/src/modules/payment-paykit/stripe.tsapps/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.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.tsapps/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}: Runnpx tsc --noEmitfor typechecking before committing
Always use braces around conditional blocks, even for single statements; Biome will expand them
Declare one variable perconst/letstatement, 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 asunknownwhen 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
UseModules.*andContainerRegistrationKeys.*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 useas Typewithout prior validation
Files:
apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/helpers.tsapps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.tsapps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/vitest.config.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.tsapps/medusa-be/src/scripts/seed-paykit.tsapps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/comgate.tsapps/medusa-be/src/modules/payment-paykit/stripe.tsapps/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.tsapps/medusa-be/src/modules/payment-paykit/__tests__/helpers.tsapps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.tsapps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/vitest.config.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.tsapps/medusa-be/src/scripts/seed-paykit.tsapps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/comgate.tsapps/medusa-be/src/modules/payment-paykit/stripe.tsapps/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: Useconstand explicit typing withdbService.sqlRaw<Type>()for SQL query results
Resolve logger usingcontainer.resolve<Logger>(ContainerRegistrationKeys.LOGGER)
Resolve Query usingcontainer.resolve<Query>(ContainerRegistrationKeys.QUERY)
UseModules.LOCKING(notModules.LOCK) to resolve locking services
UseModules.CACHING(notModules.CACHE) to resolve caching services
ThrowMedusaErrorwith appropriate type and message for error responses
UseMedusaError.Types.INVALID_DATAfor 400 validation errors
UseMedusaError.Types.NOT_FOUNDfor 404 errors
UseMedusaError.Types.UNAUTHORIZEDfor 401 authentication errors
UseMedusaError.Types.NOT_ALLOWEDfor 400 permission errors
UseMedusaError.Types.DUPLICATE_ERRORfor 422 duplicate entry errors
UseMedusaError.Types.CONFLICTfor 409 conflict errors
Use caching module'scomputeKey()to generate stable cache keys from filters and pagination
Use caching module'sget()with type assertion for cache retrieval
Use caching module'sset()with TTL and tags for cache storage and bulk invalidation
Use caching module'sclear()with tags to bulk-invalidate related cache entries
Always use Redis for caching in multi-container deployments instead of local variables
Batch operations usingCHUNK_SIZEconstant instead of unbounded loops
Files:
apps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/helpers.tsapps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.tsapps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.tsapps/medusa-be/src/scripts/seed-paykit.tsapps/medusa-be/src/modules/payment-paykit/comgate.tsapps/medusa-be/src/modules/payment-paykit/stripe.tsapps/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: UsemoduleIntegrationTestRunner()for module tests with real DB instead of mocking MedusaService methods
Mock loaders in tests usingvi.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.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/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.tsapps/medusa-be/src/modules/payment-paykit/__tests__/helpers.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/comgate.tsapps/medusa-be/src/modules/payment-paykit/stripe.tsapps/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.tsapps/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
UsecreateStep()to define workflow steps with input validation and response wrapping
UsecreateWorkflow()to define multi-step business logic with rollback support
Returnnew StepResponse()from workflow steps to pass data to next steps
Returnnew WorkflowResponse()from workflows to pass final result to caller
Usetransform()in workflows for data manipulation only; cannot contain side effects
Usewhen().then()for conditional logic in workflows instead of if statements
Do not reassign or iterate workflow variables; variable definitions are static at definition time
UseuseQueryGraphStep()for Query operations within workflows
UseacquireLockStep(),releaseLockStep()for workflow-level locking instead of manual job locking
Files:
apps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.tsapps/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: Usemedusa exec ./path/to/script.ts [args]to run one-off scripts instead of creating HTTP endpoints
Use script patternnpx medusa exec ./src/scripts/startup.tsin startup hooks
Use destructive operations inmedusa execscripts, 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 testquery.graph()pass-through calls in unit tests
Do not test logging calls; they are implementation details
Use factory functions likecreateMockEntity(overrides)for test data generation
Useit.each()to test multiple error cases and boundary conditions
Usevi.useFakeTimers()for deterministic time-based testing; usevi.setSystemTime()for absolute time
Clear mocks withmockFn.mockReset()instead ofvi.clearAllMocks()formockResolvedValueOncechains
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!
There was a problem hiding this comment.
Actionable comments posted: 4
♻️ Duplicate comments (1)
apps/medusa-be/src/modules/payment-paykit/base.ts (1)
673-673: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick winUse
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
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (14)
.mise.tomlapps/frontend-demo/package.jsonapps/medusa-be/package.jsonapps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/base.tsapps/medusa-be/src/modules/payment-paykit/comgate.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/scripts/seed-paykit.tsapps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.tsapps/n1/package.jsonlibs/storefront-data/package.jsonpackage.jsonpnpm-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.jsonapps/frontend-demo/package.jsonpackage.jsonapps/medusa-be/package.jsonlibs/storefront-data/package.json
apps/n1/**/package.json
📄 CodeRabbit inference engine (apps/n1/CLAUDE.md)
Do NOT manually edit
package.json- usepnpm add <pkg>orpnpm 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.tsapps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/comgate.tsapps/medusa-be/src/scripts/seed-paykit.tsapps/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.tsapps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.tsapps/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}: Runnpx tsc --noEmitfor typechecking before committing
Always use braces around conditional blocks, even for single statements; Biome will expand them
Declare one variable perconst/letstatement, 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 asunknownwhen 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
UseModules.*andContainerRegistrationKeys.*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 useas Typewithout prior validation
Files:
apps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/comgate.tsapps/medusa-be/src/scripts/seed-paykit.tsapps/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.tsapps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/comgate.tsapps/medusa-be/src/scripts/seed-paykit.tsapps/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 testquery.graph()pass-through calls in unit tests
Do not test logging calls; they are implementation details
Use factory functions likecreateMockEntity(overrides)for test data generation
Useit.each()to test multiple error cases and boundary conditions
Usevi.useFakeTimers()for deterministic time-based testing; usevi.setSystemTime()for absolute time
Clear mocks withmockFn.mockReset()instead ofvi.clearAllMocks()formockResolvedValueOncechains
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.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/comgate.tsapps/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.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/comgate.tsapps/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: Useconstand explicit typing withdbService.sqlRaw<Type>()for SQL query results
Resolve logger usingcontainer.resolve<Logger>(ContainerRegistrationKeys.LOGGER)
Resolve Query usingcontainer.resolve<Query>(ContainerRegistrationKeys.QUERY)
UseModules.LOCKING(notModules.LOCK) to resolve locking services
UseModules.CACHING(notModules.CACHE) to resolve caching services
ThrowMedusaErrorwith appropriate type and message for error responses
UseMedusaError.Types.INVALID_DATAfor 400 validation errors
UseMedusaError.Types.NOT_FOUNDfor 404 errors
UseMedusaError.Types.UNAUTHORIZEDfor 401 authentication errors
UseMedusaError.Types.NOT_ALLOWEDfor 400 permission errors
UseMedusaError.Types.DUPLICATE_ERRORfor 422 duplicate entry errors
UseMedusaError.Types.CONFLICTfor 409 conflict errors
Use caching module'scomputeKey()to generate stable cache keys from filters and pagination
Use caching module'sget()with type assertion for cache retrieval
Use caching module'sset()with TTL and tags for cache storage and bulk invalidation
Use caching module'sclear()with tags to bulk-invalidate related cache entries
Always use Redis for caching in multi-container deployments instead of local variables
Batch operations usingCHUNK_SIZEconstant instead of unbounded loops
Files:
apps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/comgate.tsapps/medusa-be/src/scripts/seed-paykit.tsapps/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: UsemoduleIntegrationTestRunner()for module tests with real DB instead of mocking MedusaService methods
Mock loaders in tests usingvi.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.tsapps/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.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/comgate.tsapps/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: Usemedusa exec ./path/to/script.ts [args]to run one-off scripts instead of creating HTTP endpoints
Use script patternnpx medusa exec ./src/scripts/startup.tsin startup hooks
Use destructive operations inmedusa execscripts, 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.jsonapps/frontend-demo/package.jsonpackage.jsonapps/medusa-be/package.jsonlibs/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.jsonapps/frontend-demo/package.jsonpackage.jsonapps/medusa-be/package.jsonlibs/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!
1ade6b9 to
149b528
Compare
There was a problem hiding this comment.
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
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (39)
.env.docker.mise.tomlapps/frontend-demo/package.jsonapps/medusa-be/medusa-config.tsapps/medusa-be/package.jsonapps/medusa-be/src/api/hooks/payment/paykit_gopay/route.tsapps/medusa-be/src/modules/payment-paykit/README.mdapps/medusa-be/src/modules/payment-paykit/__tests__/amounts.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/helpers.tsapps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/config.tsapps/medusa-be/src/modules/payment-paykit/core/base.tsapps/medusa-be/src/modules/payment-paykit/runtime.tsapps/medusa-be/src/modules/payment-paykit/services/comgate.tsapps/medusa-be/src/modules/payment-paykit/services/gopay.tsapps/medusa-be/src/modules/payment-paykit/services/stripe.tsapps/medusa-be/src/modules/payment-paykit/types/index.tsapps/medusa-be/src/modules/payment-paykit/utils/amounts.tsapps/medusa-be/src/modules/payment-paykit/utils/mappers.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/scripts/seed-paykit.tsapps/medusa-be/src/workflows/seed/paykit-payment-providers.tsapps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.tsapps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.tsapps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.tsapps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.tsapps/medusa-be/vitest.config.tsapps/n1/package.jsondocker-compose.yamldocker/development/medusa-be/Dockerfiledocker/development/n1/Dockerfiledocker/development/payload/Dockerfilelibs/storefront-data/package.jsonpackage.jsonpnpm-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.jsonapps/n1/package.jsonapps/frontend-demo/package.jsonpackage.jsonapps/medusa-be/package.json
apps/n1/**/package.json
📄 CodeRabbit inference engine (apps/n1/CLAUDE.md)
Do NOT manually edit
package.json- usepnpm add <pkg>orpnpm 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.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/README.mdapps/medusa-be/src/modules/payment-paykit/utils/amounts.tsapps/medusa-be/src/modules/payment-paykit/__tests__/helpers.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/config.tsapps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/services/comgate.tsapps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/services/stripe.tsapps/medusa-be/src/modules/payment-paykit/utils/mappers.tsapps/medusa-be/src/modules/payment-paykit/__tests__/amounts.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/types/index.tsapps/medusa-be/src/modules/payment-paykit/runtime.tsapps/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.tsapps/medusa-be/src/api/hooks/payment/paykit_gopay/route.tsapps/medusa-be/vitest.config.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/utils/amounts.tsapps/medusa-be/src/modules/payment-paykit/__tests__/helpers.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/scripts/seed-paykit.tsapps/medusa-be/medusa-config.tsapps/medusa-be/src/modules/payment-paykit/config.tsapps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/services/comgate.tsapps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/services/stripe.tsapps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.tsapps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.tsapps/medusa-be/src/modules/payment-paykit/utils/mappers.tsapps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.tsapps/medusa-be/src/workflows/seed/paykit-payment-providers.tsapps/medusa-be/src/modules/payment-paykit/__tests__/amounts.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/types/index.tsapps/medusa-be/src/modules/payment-paykit/runtime.tsapps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.tsapps/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.tsapps/medusa-be/src/api/hooks/payment/paykit_gopay/route.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/README.mdapps/medusa-be/src/modules/payment-paykit/utils/amounts.tsapps/medusa-be/src/modules/payment-paykit/__tests__/helpers.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/config.tsapps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/services/comgate.tsapps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/services/stripe.tsapps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.tsapps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.tsapps/medusa-be/src/modules/payment-paykit/utils/mappers.tsapps/medusa-be/src/workflows/seed/paykit-payment-providers.tsapps/medusa-be/src/modules/payment-paykit/__tests__/amounts.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/types/index.tsapps/medusa-be/src/modules/payment-paykit/runtime.tsapps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.tsapps/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}: Runnpx tsc --noEmitfor typechecking before committing
Always use braces around conditional blocks, even for single statements; Biome will expand them
Declare one variable perconst/letstatement, 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 asunknownwhen 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
UseModules.*andContainerRegistrationKeys.*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 useas Typewithout prior validation
Files:
apps/medusa-be/src/modules/payment-paykit/services/gopay.tsapps/medusa-be/src/api/hooks/payment/paykit_gopay/route.tsapps/medusa-be/vitest.config.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/utils/amounts.tsapps/medusa-be/src/modules/payment-paykit/__tests__/helpers.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/scripts/seed-paykit.tsapps/medusa-be/medusa-config.tsapps/medusa-be/src/modules/payment-paykit/config.tsapps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/services/comgate.tsapps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/services/stripe.tsapps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.tsapps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.tsapps/medusa-be/src/modules/payment-paykit/utils/mappers.tsapps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.tsapps/medusa-be/src/workflows/seed/paykit-payment-providers.tsapps/medusa-be/src/modules/payment-paykit/__tests__/amounts.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/types/index.tsapps/medusa-be/src/modules/payment-paykit/runtime.tsapps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.tsapps/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.tsapps/medusa-be/src/api/hooks/payment/paykit_gopay/route.tsapps/medusa-be/vitest.config.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/utils/amounts.tsapps/medusa-be/src/modules/payment-paykit/__tests__/helpers.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/scripts/seed-paykit.tsapps/medusa-be/medusa-config.tsapps/medusa-be/src/modules/payment-paykit/config.tsapps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/services/comgate.tsapps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/services/stripe.tsapps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.tsapps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.tsapps/medusa-be/src/modules/payment-paykit/utils/mappers.tsapps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.tsapps/medusa-be/src/workflows/seed/paykit-payment-providers.tsapps/medusa-be/src/modules/payment-paykit/__tests__/amounts.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/types/index.tsapps/medusa-be/src/modules/payment-paykit/runtime.tsapps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.tsapps/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: Useconstand explicit typing withdbService.sqlRaw<Type>()for SQL query results
Resolve logger usingcontainer.resolve<Logger>(ContainerRegistrationKeys.LOGGER)
Resolve Query usingcontainer.resolve<Query>(ContainerRegistrationKeys.QUERY)
UseModules.LOCKING(notModules.LOCK) to resolve locking services
UseModules.CACHING(notModules.CACHE) to resolve caching services
ThrowMedusaErrorwith appropriate type and message for error responses
UseMedusaError.Types.INVALID_DATAfor 400 validation errors
UseMedusaError.Types.NOT_FOUNDfor 404 errors
UseMedusaError.Types.UNAUTHORIZEDfor 401 authentication errors
UseMedusaError.Types.NOT_ALLOWEDfor 400 permission errors
UseMedusaError.Types.DUPLICATE_ERRORfor 422 duplicate entry errors
UseMedusaError.Types.CONFLICTfor 409 conflict errors
Use caching module'scomputeKey()to generate stable cache keys from filters and pagination
Use caching module'sget()with type assertion for cache retrieval
Use caching module'sset()with TTL and tags for cache storage and bulk invalidation
Use caching module'sclear()with tags to bulk-invalidate related cache entries
Always use Redis for caching in multi-container deployments instead of local variables
Batch operations usingCHUNK_SIZEconstant instead of unbounded loops
Files:
apps/medusa-be/src/modules/payment-paykit/services/gopay.tsapps/medusa-be/src/api/hooks/payment/paykit_gopay/route.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/utils/amounts.tsapps/medusa-be/src/modules/payment-paykit/__tests__/helpers.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/scripts/seed-paykit.tsapps/medusa-be/src/modules/payment-paykit/config.tsapps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/services/comgate.tsapps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/services/stripe.tsapps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.tsapps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.tsapps/medusa-be/src/modules/payment-paykit/utils/mappers.tsapps/medusa-be/src/workflows/seed/paykit-payment-providers.tsapps/medusa-be/src/modules/payment-paykit/__tests__/amounts.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/types/index.tsapps/medusa-be/src/modules/payment-paykit/runtime.tsapps/medusa-be/src/workflows/seed/workflows/seed-paykit-regions.tsapps/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.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/utils/amounts.tsapps/medusa-be/src/modules/payment-paykit/__tests__/helpers.tsapps/medusa-be/src/modules/payment-paykit/__tests__/comgate.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/config.tsapps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/services/comgate.tsapps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/services/stripe.tsapps/medusa-be/src/modules/payment-paykit/utils/mappers.tsapps/medusa-be/src/modules/payment-paykit/__tests__/amounts.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/types/index.tsapps/medusa-be/src/modules/payment-paykit/runtime.tsapps/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: Usereq.scope.resolve()to access container in routes
Colocatevalidators.tsandmiddlewares.tswith each route file in the same directory
UsevalidateAndTransformBody(Schema)middleware for POST/PUT request validation
UsevalidateAndTransformQuery(Schema)middleware for GET request query parameter validation
Usereq.validatedBodyin 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.tsapps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.tsapps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.tsapps/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: UsemoduleIntegrationTestRunner()for module tests with real DB instead of mocking MedusaService methods
Mock loaders in tests usingvi.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.tsapps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/base.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/stripe.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/__tests__/runtime.unit.spec.tsapps/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: Usemedusa exec ./path/to/script.ts [args]to run one-off scripts instead of creating HTTP endpoints
Use script patternnpx medusa exec ./src/scripts/startup.tsin startup hooks
Use destructive operations inmedusa execscripts, 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.tsevaluated 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.tsapps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.tsapps/medusa-be/src/workflows/seed/paykit-payment-providers.tsapps/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
UsecreateStep()to define workflow steps with input validation and response wrapping
UsecreateWorkflow()to define multi-step business logic with rollback support
Returnnew StepResponse()from workflow steps to pass data to next steps
Returnnew WorkflowResponse()from workflows to pass final result to caller
Usetransform()in workflows for data manipulation only; cannot contain side effects
Usewhen().then()for conditional logic in workflows instead of if statements
Do not reassign or iterate workflow variables; variable definitions are static at definition time
UseuseQueryGraphStep()for Query operations within workflows
UseacquireLockStep(),releaseLockStep()for workflow-level locking instead of manual job locking
Files:
apps/medusa-be/src/workflows/seed/steps/create-missing-paykit-regions.tsapps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.tsapps/medusa-be/src/workflows/seed/paykit-payment-providers.tsapps/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 testquery.graph()pass-through calls in unit tests
Do not test logging calls; they are implementation details
Use factory functions likecreateMockEntity(overrides)for test data generation
Useit.each()to test multiple error cases and boundary conditions
Usevi.useFakeTimers()for deterministic time-based testing; usevi.setSystemTime()for absolute time
Clear mocks withmockFn.mockReset()instead ofvi.clearAllMocks()formockResolvedValueOncechains
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/Dockerfiledocker/development/medusa-be/Dockerfiledocker/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/Dockerfiledocker/development/medusa-be/Dockerfiledocker/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.jsonapps/n1/package.jsonapps/frontend-demo/package.jsonpackage.jsonapps/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.jsonapps/n1/package.jsonapps/frontend-demo/package.jsonpackage.jsonapps/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 winLockfile is correctly updated with the dependency versions.
Both
@medusajs/js-sdkand@medusajs/typesare 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!
Greptile SummaryThis 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.
Confidence Score: 5/5Safe 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.
Important Files Changed
Sequence DiagramsequenceDiagram
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
Reviews (2): Last reviewed commit: "fix(paykit): rabbit code & greptile revi..." | Re-trigger Greptile |
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@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
📒 Files selected for processing (9)
apps/medusa-be/medusa-config.tsapps/medusa-be/src/api/hooks/payment/paykit_gopay/route.tsapps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.tsapps/medusa-be/src/modules/payment-paykit/runtime.tsapps/medusa-be/src/modules/payment-paykit/utils/mappers.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.tsapps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.tsapps/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.tsapps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.tsapps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.tsapps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.tsapps/medusa-be/src/api/hooks/payment/paykit_gopay/route.tsapps/medusa-be/medusa-config.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/utils/mappers.tsapps/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}: Runnpx tsc --noEmitfor typechecking before committing
Always use braces around conditional blocks, even for single statements; Biome will expand them
Declare one variable perconst/letstatement, 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 asunknownwhen 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
UseModules.*andContainerRegistrationKeys.*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 useas Typewithout prior validation
Files:
apps/medusa-be/vitest.config.tsapps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.tsapps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.tsapps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.tsapps/medusa-be/src/api/hooks/payment/paykit_gopay/route.tsapps/medusa-be/medusa-config.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/utils/mappers.tsapps/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.tsapps/medusa-be/tests/unit/payment-paykit/gopay-webhook-route.unit.spec.tsapps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.tsapps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.tsapps/medusa-be/src/api/hooks/payment/paykit_gopay/route.tsapps/medusa-be/medusa-config.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/utils/mappers.tsapps/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.tsapps/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 testquery.graph()pass-through calls in unit tests
Do not test logging calls; they are implementation details
Use factory functions likecreateMockEntity(overrides)for test data generation
Useit.each()to test multiple error cases and boundary conditions
Usevi.useFakeTimers()for deterministic time-based testing; usevi.setSystemTime()for absolute time
Clear mocks withmockFn.mockReset()instead ofvi.clearAllMocks()formockResolvedValueOncechains
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.tsapps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.tsapps/medusa-be/src/api/hooks/payment/paykit_gopay/route.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/utils/mappers.tsapps/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: Useconstand explicit typing withdbService.sqlRaw<Type>()for SQL query results
Resolve logger usingcontainer.resolve<Logger>(ContainerRegistrationKeys.LOGGER)
Resolve Query usingcontainer.resolve<Query>(ContainerRegistrationKeys.QUERY)
UseModules.LOCKING(notModules.LOCK) to resolve locking services
UseModules.CACHING(notModules.CACHE) to resolve caching services
ThrowMedusaErrorwith appropriate type and message for error responses
UseMedusaError.Types.INVALID_DATAfor 400 validation errors
UseMedusaError.Types.NOT_FOUNDfor 404 errors
UseMedusaError.Types.UNAUTHORIZEDfor 401 authentication errors
UseMedusaError.Types.NOT_ALLOWEDfor 400 permission errors
UseMedusaError.Types.DUPLICATE_ERRORfor 422 duplicate entry errors
UseMedusaError.Types.CONFLICTfor 409 conflict errors
Use caching module'scomputeKey()to generate stable cache keys from filters and pagination
Use caching module'sget()with type assertion for cache retrieval
Use caching module'sset()with TTL and tags for cache storage and bulk invalidation
Use caching module'sclear()with tags to bulk-invalidate related cache entries
Always use Redis for caching in multi-container deployments instead of local variables
Batch operations usingCHUNK_SIZEconstant instead of unbounded loops
Files:
apps/medusa-be/src/workflows/seed/steps/sync-existing-paykit-regions.tsapps/medusa-be/src/modules/payment-paykit/__tests__/gopay.unit.spec.tsapps/medusa-be/src/api/hooks/payment/paykit_gopay/route.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/utils/mappers.tsapps/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
UsecreateStep()to define workflow steps with input validation and response wrapping
UsecreateWorkflow()to define multi-step business logic with rollback support
Returnnew StepResponse()from workflow steps to pass data to next steps
Returnnew WorkflowResponse()from workflows to pass final result to caller
Usetransform()in workflows for data manipulation only; cannot contain side effects
Usewhen().then()for conditional logic in workflows instead of if statements
Do not reassign or iterate workflow variables; variable definitions are static at definition time
UseuseQueryGraphStep()for Query operations within workflows
UseacquireLockStep(),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.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/utils/mappers.tsapps/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: UsemoduleIntegrationTestRunner()for module tests with real DB instead of mocking MedusaService methods
Mock loaders in tests usingvi.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.tsapps/medusa-be/src/modules/payment-paykit/webhooks.tsapps/medusa-be/src/modules/payment-paykit/utils/mappers.tsapps/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: Usereq.scope.resolve()to access container in routes
Colocatevalidators.tsandmiddlewares.tswith each route file in the same directory
UsevalidateAndTransformBody(Schema)middleware for POST/PUT request validation
UsevalidateAndTransformQuery(Schema)middleware for GET request query parameter validation
Usereq.validatedBodyin 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.tsevaluated 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!
…ly, split delete/cancelPayment due to medusa rollback behaviour
…paykit <> medusa handling
… paykit <> medusa handling, stricter type definitions for paykit types
…dded Readme to document why we're not using paykit medusa adapter
… for medusa-config, added tests
4066c82 to
d10d15d
Compare
Summary
including provider config, runtime client loading, amount normalization,
provider metadata mapping, refund/capture/cancel handling, and webhook event
mapping.
Stripe/Comgate on Medusa’s generic payment webhook route.
PayKit SDK dependencies.
setup.
handling, webhook mapping, runtime loading, and GoPay hook behavior.
cart item id, manual capture, and cart metadata.
Summary by CodeRabbit
New Features
Bug Fixes
Chores