Skip to content

feat: standardize payment kit configuration and workflows#22

Open
Zaiidmo wants to merge 7 commits intomasterfrom
develop
Open

feat: standardize payment kit configuration and workflows#22
Zaiidmo wants to merge 7 commits intomasterfrom
develop

Conversation

@Zaiidmo
Copy link
Collaborator

@Zaiidmo Zaiidmo commented Mar 1, 2026

Standardization Pull Request

Changes

  • ✅ Updated ESLint configuration for v9 compatibility
  • ✅ Fixed 51 lint + TypeScript errors
  • ✅ Changed tsconfig module resolution from "nodenext" to "commonjs"
  • ✅ Updated build script to use tsc + tsc-alias
  • ✅ Fixed redundant type modifiers in imports
  • ✅ Added standardized GitHub workflows (pr-validation, release-check, publish)
  • ✅ Updated SONAR_PROJECT_KEY to CISCODE-MA_PaymentKit
  • ✅ All validation checks passing: format, lint, typecheck, build

Status

  • ✅ All checks passing locally

@Zaiidmo Zaiidmo requested review from a team and Copilot March 1, 2026 23:43
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR standardizes the repo’s TypeScript/Jest/ESLint configuration and CI workflows to align build + validation behavior across local development and GitHub Actions, alongside broad import hygiene changes (type-only imports / ordering) across src and tests.

Changes:

  • Updates TS build/typecheck configuration (module + moduleResolution, build script changes) and adds dedicated ESLint tsconfig.
  • Introduces Jest and ESLint flat-config files and adjusts numerous imports across tests/src to satisfy lint/type rules.
  • Adds/updates GitHub Actions workflows for release checks and publishing, plus contributor guidance and an .env.example.

Reviewed changes

Copilot reviewed 67 out of 69 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tsconfig.json Switches TS module settings and narrows compilation include set to src/**.
tsconfig.eslint.json Adds an ESLint-specific TS project for type-aware linting.
package.json Updates build/typecheck scripts, sets package type, and adjusts dependency versions.
jest.config.ts Adds standalone Jest configuration (migrated from package.json).
eslint.config.js Adds ESLint v9 flat config with TS + import ordering rules.
.github/workflows/release-check.yml Adds PR-time “release checks” CI workflow (format/lint/typecheck/test/build + optional Sonar).
.github/workflows/publish.yml Refines npm publish workflow steps and node version.
.github/copilot-instructions.md Adds a project-specific contributor/developer guide.
.env.example Adds example environment variable template for local/dev setups.
src/paymentKit.module.ts Reorders imports / consolidates stack wiring imports.
src/nest/controllers/internal-webhook.controller.ts Converts some imports to type-only and reorders.
src/main.ts Minor formatting/import spacing changes.
src/core/services/webhook-mode.service.ts Converts imports to type-only and reorders.
src/core/services/webhook-event-dispatcher.service.ts Converts webhook type imports to type-only.
src/core/services/payment-engine.service.ts Reorders imports and converts some to type-only.
src/core/services/gateway-registry.service.ts Converts imports to type-only and adds spacing.
src/core/services/error-normalizer.service.ts Splits type/value imports and reorders.
src/core/ports/payment-gateway.port.ts Converts multiple imports to type-only.
src/core/ports/payment-engine.port.ts Converts import to type-only.
src/core/gateways/stripe/stripe.gateway.ts Reorders imports; normalizes type/value import usage.
src/core/gateways/stripe/stripe.client.ts Converts config import to type-only.
src/core/gateways/stripe/stripe-webhook.handler.ts Converts imports to type-only and reorders.
src/core/gateways/stripe/stripe-webhook-normalizer.ts Converts imports to type-only.
src/core/gateways/stripe/stripe-payments.client.ts Reorders imports; converts some to type-only.
src/core/gateways/stripe/stripe-error.mapper.ts Splits type/value imports; converts GatewayKey to type-only.
src/core/gateways/paypal/paypal.gateway.ts Reorders imports; normalizes type/value import usage.
src/core/gateways/paypal/paypal.client.ts Reorders type-only imports.
src/core/gateways/paypal/paypal-webhook.handler.ts Reorders imports; converts to type-only.
src/core/gateways/paypal/paypal-webhook-normalizer.ts Converts webhook imports to type-only.
src/core/gateways/paypal/paypal-payments.client.ts Reorders imports; converts PaypalClient to type-only.
src/core/gateways/paypal/paypal-error.mapper.ts Splits type/value imports.
src/core/entities/payment.entity.ts Converts entity imports to type-only and reorders.
src/core/entities/refund.entity.ts Converts imports to type-only and reorders.
src/config/paymentKit.config.ts Converts WebhookMode import to type-only.
src/config/paymentKit.config-loader.ts Reorders imports between common/config and gateway-specific configs.
src/common/types/webhook.types.ts Converts GatewayKey import to type-only.
src/common/errors/normalized-error.model.ts Converts GatewayKey import to type-only.
test/unit/paymentKit.module.spec.ts Reorders imports and uses type-only import.
test/unit/core/services/webhook/webhook-mode.service.spec.ts Reorders imports and uses type-only import.
test/unit/core/services/webhook/webhook-gateway-router.service.spec.ts Reorders imports; uses type-only imports consistently.
test/unit/core/services/webhook/webhook-gateway-router.normalization.spec.ts Reorders imports; uses type-only imports consistently.
test/unit/core/services/webhook/webhook-event-dispatcher.service.spec.ts Reorders type-only import.
test/unit/core/services/payment-engine.service.spec.ts Reorders imports; normalizes type-only imports.
test/unit/core/services/gateway-registry.service.spec.ts Reorders imports; normalizes type-only imports.
test/unit/core/services/error-mappers/stripe-error-mapper.spec.ts Reorders imports; normalizes type-only imports.
test/unit/core/services/error-mappers/paypal-error-mapper.spec.ts Reorders imports; normalizes type-only imports.
test/unit/core/services/error-mappers/error-normalizer.service.spec.ts Reorders imports; normalizes type-only imports.
test/unit/core/gateways/stripe/stripe.gateway.spec.ts Reorders imports; normalizes type-only imports.
test/unit/core/gateways/stripe/stripe.client.spec.ts Reorders imports; normalizes type-only imports.
test/unit/core/gateways/stripe/stripe-webhook.handler.spec.ts Reorders imports; normalizes type-only imports.
test/unit/core/gateways/stripe/stripe-webhook-verifier.spec.ts Reorders imports and adds spacing.
test/unit/core/gateways/stripe/stripe-payments.client.spec.ts Reorders imports and adjusts type-only groupings.
test/unit/core/gateways/stripe/stripe-error.mapper.spec.ts Reorders imports; normalizes type-only imports.
test/unit/core/gateways/paypal/paypal.gateway.spec.ts Reorders imports; normalizes type-only imports.
test/unit/core/gateways/paypal/paypal.client.spec.ts Reorders imports; normalizes type-only imports.
test/unit/core/gateways/paypal/paypal-webhook.handler.spec.ts Reorders type-only imports.
test/unit/core/gateways/paypal/paypal-webhook-verifier.spec.ts Reorders imports; normalizes type-only imports.
test/unit/core/gateways/paypal/paypal-payments.client.spec.ts Reorders imports; normalizes type-only imports.
test/unit/core/gateways/paypal/paypal-error.mapper.spec.ts Reorders imports; normalizes type-only imports.
test/unit/core/entities/payment-and-refund.entity.spec.ts Reorders imports; normalizes type-only imports.
test/unit/controllers/internal-webhook.controller.spec.ts Reorders imports; normalizes type-only imports.
test/unit/config/paymentKit.config.spec.ts Reorders imports; normalizes type-only imports.
test/unit/config/paymentKit.config-loader.spec.ts Reorders imports; normalizes type-only imports.
test/unit/common/errors/normalized-error.model.spec.ts Reorders imports; normalizes type-only imports.
test/integration/stripe/stripe-payments.integration.spec.ts Converts imports to type-only where appropriate and reorders.
test/integration/setup.ts Splits type/value imports and reorders.
test/app.e2e-spec.ts Converts imports to type-only and reorders.
Comments suppressed due to low confidence (7)

.github/workflows/release-check.yml:52

  • This workflow runs npm run format, which modifies files rather than validating formatting. In CI, that can let unformatted code pass (and can create a dirty working tree). Use npm run format:check (or an equivalent check-only command) for PR validation.
      - name: Format
        run: npm run format

      - name: Typecheck
        run: npm run typecheck

tsconfig.eslint.json:8

  • tsconfig.eslint.json includes *.js but it extends tsconfig.json which does not enable allowJs. With parserOptions.project, that can cause TypeScript program/diagnostic issues during linting. Either remove *.js from the include list, or set compilerOptions.allowJs (and optionally checkJs) in the ESLint tsconfig if you intend to type-check JS files.
    src/core/services/webhook-mode.service.ts:6
  • Spelling typo in the doc comment (aruond). Rename to around for readability in generated docs/IDE hints.
    src/core/services/error-normalizer.service.ts:10
  • The ErrorNormalizer interface parameter name has a typo (contexxt). While parameter names don't affect TypeScript assignability, this reduces readability and can propagate into generated docs/IDE hints. Rename it to context.
export interface ErrorNormalizer {
  normalize(error: unknown, contexxt: { gateway: GatewayKey }): NormalizedError;
}

src/common/types/webhook.types.ts:6

  • Spelling in the WebhookMode doc comment has typos (hendling, PaymekntKit). Please correct these to keep public types/docs polished.
/**
 * Webhook hendling mode for PaymekntKit.
 *
 * - "internal": Webhooks are handled internally by PaymentKit.

.github/copilot-instructions.md:74

  • This contributor guide describes a project structure and path aliases (src/adapters, src/controllers, @adapters/*, @controllers/*) that don't exist in the current repo (the code uses src/core/gateways and src/nest/controllers, and tsconfig.json defines different aliases like @src/* and @nest/*). Please update the guide to match the actual structure/aliases (or update the codebase to match the documented structure) to avoid misleading contributors.
## 🏗️ PaymentKit Project Structure

PaymentKit uses a Hexagonal Architecture (Ports & Adapters) for gateway abstraction.

src/
index.ts # PUBLIC API exports
paymentKit.module.ts # Main NestJS module
common/
constants.ts # DI tokens, magic strings
errors/ # Error models
types/ # Shared type definitions
utils/ # Helper functions
config/
paymentKit.config.ts # Public config interface
paymentKit.config-loader.ts # Env-based config builder
gateways/ # Gateway-specific configs
stripe.config.ts
paypal.config.ts
core/
entities/ # Domain entities
payment.entity.ts
refund.entity.ts
payment-status.enum.ts
value-objects/
money.value-object.ts
ports/ # Interface contracts (Hexagonal)
payment-gateway.port.ts
payment-engine.port.ts
services/
payment-engine.service.ts # Main orchestrator
gateway-registry.service.ts
error-normalizer.service.ts
adapters/ # Gateway implementations
stripe/
stripe.gateway.ts
stripe-webhook.handler.ts
stripe-payments.client.ts
paypal/
paypal.gateway.ts
paypal-webhook.handler.ts
paypal-payments.client.ts
controllers/
payments.controller.ts # Main API endpoints
webhooks.controller.ts # Internal webhook controller

package.json:19

  • package.json is now marked as ESM ("type": "module"), but tsconfig.json compiles to CommonJS ("module": "commonjs") and main/exports point to dist/*.js. That combination will cause Node to treat the emitted CommonJS files as ESM at runtime (e.g., node dist/main / consumers importing dist/index.js), which typically fails. Align the package type and TS output (either remove type: module, or switch TS output to ESM and update exports/file extensions/entrypoints accordingly).
  "type": "module",
  "description": "Unified payments package for NestJS (Stripe, PayPal).",
  "author": "Zaiid Moumni",
  "private": false,
  "license": "MIT",
  "repository": {
    "type": "git",
    "url": "https://github.com/CISCODE-MA/PaymentKit"
  },
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "default": "./dist/index.js"
    }

jest.config.ts Outdated
'^@config/(.*)$': '<rootDir>/src/config/$1',
'^@core/(.*)$': '<rootDir>/src/core/$1',
'^@adapters/(.*)$': '<rootDir>/src/adapters/$1',
'^@controllers/(.*)$': '<rootDir>/src/controllers/$1',
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

jest.config.ts is missing path alias mappings that are used throughout the tests (e.g. @src/*, @nest/*, and @gateways/* are in tsconfig.json and referenced in test/**). Without these, Jest will fail module resolution. Add the missing moduleNameMapper entries (or generate them from tsconfig.json paths) so Jest matches the TS compiler resolution.

Suggested change
'^@controllers/(.*)$': '<rootDir>/src/controllers/$1',
'^@controllers/(.*)$': '<rootDir>/src/controllers/$1',
'^@src/(.*)$': '<rootDir>/src/$1',
'^@nest/(.*)$': '<rootDir>/src/nest/$1',
'^@gateways/(.*)$': '<rootDir>/src/gateways/$1',

Copilot uses AI. Check for mistakes.
"@nestjs/cli": "^11.0.0",
"@nestjs/schematics": "^11.0.0",
"@nestjs/testing": "^11.0.1",
"@nestjs/cli": "^7.6.0",
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

@nestjs/cli is pinned to ^7.6.0 while the project depends on Nest v11 (@nestjs/common/core/testing are 11.x). This major-version mismatch can break nest start and other CLI-driven tasks. Update @nestjs/cli to a compatible v11 version (or adjust the Nest dependency versions to match the CLI major).

Suggested change
"@nestjs/cli": "^7.6.0",
"@nestjs/cli": "^11.0.0",

Copilot uses AI. Check for mistakes.
Zaiidmo added 5 commits March 4, 2026 00:56
- Add changeset config and release note
- Move copilot instructions to .github/instructions
- Add sonarqube MCP instructions
- Update publish workflow
- Add Jest path aliases and skip integration tests without env vars
- Prefix unused parameters with underscore (_) to comply with ESLint rules
- Update examples for ecommerce checkout, webhook handling, and refund operations
- All examples now pass linting checks
- Applied prettier formatting to examples
- Fixed ESLint configuration to include examples folder
- All code passes linting and formatting standards
Copilot AI review requested due to automatic review settings March 12, 2026 10:21
@sonarqubecloud
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
2 Security Hotspots

See analysis details on SonarQube Cloud

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 78 out of 81 changed files in this pull request and generated 11 comments.

Comment on lines +11 to +12
STRIPE_SECRET_KEY=sk_test_your-secret-key
STRIPE_WEBHOOK_SECRET=whsec_your-webhook-secret
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

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

The env var names in this example don’t match what the Stripe config builder reads (PAYMENTKIT_STRIPE_API_KEY / PAYMENTKIT_STRIPE_WEBHOOK_SECRET). As written, users copying this file won’t be able to bootstrap PaymentKit from env.

Suggested change
STRIPE_SECRET_KEY=sk_test_your-secret-key
STRIPE_WEBHOOK_SECRET=whsec_your-webhook-secret
PAYMENTKIT_STRIPE_API_KEY=sk_test_your-secret-key
PAYMENTKIT_STRIPE_WEBHOOK_SECRET=whsec_your-webhook-secret

Copilot uses AI. Check for mistakes.
Comment on lines +15 to +18
PAYPAL_CLIENT_ID=your-client-id
PAYPAL_CLIENT_SECRET=your-client-secret
PAYPAL_MODE=sandbox
PAYPAL_WEBHOOK_ID=your-webhook-id
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

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

The env var names in this example don’t match what the PayPal config builder reads (PAYMENTKIT_PAYPAL_CLIENT_ID / PAYMENTKIT_PAYPAL_CLIENT_SECRET / optional PAYMENTKIT_PAYPAL_WEBHOOK_ID). Update these names so the example is usable.

Suggested change
PAYPAL_CLIENT_ID=your-client-id
PAYPAL_CLIENT_SECRET=your-client-secret
PAYPAL_MODE=sandbox
PAYPAL_WEBHOOK_ID=your-webhook-id
PAYMENTKIT_PAYPAL_CLIENT_ID=your-client-id
PAYMENTKIT_PAYPAL_CLIENT_SECRET=your-client-secret
PAYPAL_MODE=sandbox
PAYMENTKIT_PAYPAL_WEBHOOK_ID=your-webhook-id

Copilot uses AI. Check for mistakes.
{
"name": "@ciscode/paymentkit",
"version": "1.2.0",
"type": "module",
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

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

"type": "module" makes Node treat emitted dist/*.js as ESM, but tsconfig.json emits CommonJS ("module": "commonjs") and main/exports point at dist/index.js. This will break node dist/main and consumers importing dist/index.js. Align the package/module format by either removing/setting type to commonjs, or switching TS emit + exports to proper ESM (or dual CJS/ESM conditional exports).

Suggested change
"type": "module",
"type": "commonjs",

Copilot uses AI. Check for mistakes.
Comment on lines +18 to +22
parserOptions: {
project: './tsconfig.eslint.json',
tsconfigRootDir: import.meta.dirname,
ecmaVersion: 'latest',
sourceType: 'module',
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

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

import.meta.dirname is not part of the standard import.meta API and is undefined in many Node environments. ESLint will fail to resolve tsconfigRootDir if this is undefined. Use a fileURLToPath(import.meta.url) + path.dirname(...) pattern (or keep this config as .mjs and use __dirname via createRequire/URL conversion) to compute the directory reliably.

Copilot uses AI. Check for mistakes.
Comment on lines +18 to +22
const REQUIRED_ENV = [
'PAYMENTKIT_ENVIRONMENT',
'PAYMENTKIT_STRIPE_SECRET_KEY',
'PAYMENTKIT_PAYPAL_CLIENT_ID',
'PAYMENTKIT_PAYPAL_SECRET',
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

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

REQUIRED_ENV is checking for PAYMENTKIT_STRIPE_SECRET_KEY / PAYMENTKIT_PAYPAL_SECRET, but the actual config expects PAYMENTKIT_STRIPE_API_KEY and PAYMENTKIT_PAYPAL_CLIENT_SECRET. Update this list so integration tests are gated on the correct variables.

Copilot uses AI. Check for mistakes.
Comment on lines +62 to +70
adapters/ # Gateway implementations
stripe/
stripe.gateway.ts
stripe-webhook.handler.ts
stripe-payments.client.ts
paypal/
paypal.gateway.ts
paypal-webhook.handler.ts
paypal-payments.client.ts
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

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

This doc’s project structure lists gateway implementations under src/adapters/..., but the actual codebase has them under src/core/gateways/.... Updating the diagram/paths will prevent contributors from creating files in the wrong place.

Suggested change
adapters/ # Gateway implementations
stripe/
stripe.gateway.ts
stripe-webhook.handler.ts
stripe-payments.client.ts
paypal/
paypal.gateway.ts
paypal-webhook.handler.ts
paypal-payments.client.ts
gateways/ # Gateway implementations
stripe/
stripe.gateway.ts
stripe-webhook.handler.ts
stripe-payments.client.ts
paypal/
paypal.gateway.ts
paypal-webhook.handler.ts
paypal-payments.client.ts

Copilot uses AI. Check for mistakes.
Comment on lines +71 to +73
controllers/
payments.controller.ts # Main API endpoints
webhooks.controller.ts # Internal webhook controller
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

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

This doc references src/controllers/..., but this repository’s Nest layer lives under src/nest/controllers/... (and there is no src/controllers folder). Adjust the structure + examples to match the real layout to avoid incorrect imports.

Suggested change
controllers/
payments.controller.ts # Main API endpoints
webhooks.controller.ts # Internal webhook controller
nest/
controllers/
payments.controller.ts # Main API endpoints
webhooks.controller.ts # Internal webhook controller

Copilot uses AI. Check for mistakes.
Comment on lines +19 to +22
'^@gateways/(.*)$': '<rootDir>/src/gateways/$1',
'^@nest/(.*)$': '<rootDir>/src/nest/$1',
'^@adapters/(.*)$': '<rootDir>/src/adapters/$1',
'^@controllers/(.*)$': '<rootDir>/src/controllers/$1',
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

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

This Jest config maps @gateways/*, @adapters/*, and @controllers/* to directories that don't exist in this repo (src/gateways, src/adapters, src/controllers). If these aliases are legacy, removing them reduces confusion; if they are intended, update them to actual directories (e.g., src/core/gateways, src/nest/controllers).

Suggested change
'^@gateways/(.*)$': '<rootDir>/src/gateways/$1',
'^@nest/(.*)$': '<rootDir>/src/nest/$1',
'^@adapters/(.*)$': '<rootDir>/src/adapters/$1',
'^@controllers/(.*)$': '<rootDir>/src/controllers/$1',
'^@nest/(.*)$': '<rootDir>/src/nest/$1',

Copilot uses AI. Check for mistakes.
Comment on lines +5 to +6
branches:
- master
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

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

This workflow publishes on every push to master. Because it only checks that some v*.*.* tag exists in the repo (not that a new tag was pushed), most pushes to master will attempt to republish the same version and fail (npm ERR! You cannot publish over the previously published versions). Prefer triggering on tag pushes (on.push.tags: ['v*.*.*']) or use semantic-release/changesets to create a new version/tag before publishing.

Suggested change
branches:
- master
tags:
- 'v*.*.*'

Copilot uses AI. Check for mistakes.

echo "✅ Valid tag found: $TAG"
echo "✅ Version matches package.json: $PKG_VERSION"
echo "TAG_VERSION=$TAG" >> $GITHUB_ENV
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

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

The workflow exports TAG_VERSION=$TAG, but TAG_VERSION was computed earlier without the v prefix (TAG_VERSION="${TAG#v}"). If this env var is used later, it will be incorrect; export the computed value (or rename the env var to avoid confusion).

Suggested change
echo "TAG_VERSION=$TAG" >> $GITHUB_ENV
echo "TAG_VERSION=$TAG_VERSION" >> $GITHUB_ENV

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants