Fix/payment index validation tsconfig strictness - #276
Merged
martinzhames merged 4 commits intoSep 1, 2026
Merged
Conversation
Payment entity had no @Index decorators despite merchantId being the WHERE clause for findAll/findOne/getStats and the AML velocity-check join key, causing sequential scans as the payments table grows. Adds @Index() on merchantId plus composite indexes on (merchantId, status) and (merchantId, createdAt) to match the actual query patterns.
create-payment.dto.ts validated amountUsd with only @isnumber()/ @ispositive() (no ceiling) and metadata with only @isObject(), storing directly into a jsonb column with no size limit — a low-effort storage/DoS vector and a source of confusing downstream math at extreme values. Adds @max(1_000_000) to amountUsd on both CreatePaymentDto and BatchPaymentItemDto, and a new reusable @MaxJsonSize custom validator (src/common/decorators/max-json-size.decorator.ts) capping serialized metadata at 4KB on both DTOs.
CreatePaymentDto.expiryMinutes only had @isnumber(), unlike BatchPaymentItemDto.expiryMinutes which already required @ispositive(). PaymentsService.create() applied the value with no clamping, so a caller could pass 0/negative (payment expired at creation) or an arbitrarily large value (effectively never-expiring payment). Adds @ispositive() and @max(1440) (24h cap) to CreatePaymentDto.expiryMinutes, aligning single-payment creation with the batch DTO's validation, and applies the same 1440 cap to the batch DTO for consistency.
tsconfig.json disabled both flags, removing two of TypeScript's most important safety nets for a financial codebase full of nullable entity columns (Payment, Settlement, Merchant, Webhook) and optional DTO fields, letting null/undefined bugs and any-typed values pass compilation unchecked. Flips strictNullChecks and noImplicitAny to true. Full project-wide type-error cleanup surfaced by this flag flip is tracked as follow-up work rather than attempted in this change (see docs/fixes/payment-hardening.md). Also adds docs/fixes/payment-hardening.md summarizing all four fixes made on this branch: merchantId indexes, amountUsd/metadata payload caps, expiryMinutes bounds, and this tsconfig strictness change.
|
@Mac-5 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #145
Closes #146
Closes #147
Closes #148