Severity: Medium
Type: Bug
Scope: Campaigns
Labels: bug, good first issue
Description
CampaignsService.createCampaign (src/campaigns/campaigns.service.ts, line ~37) maps incoming milestone DTOs as targetAmount: (m.targetAmount ?? 0) as any. A missing or zero-valued targetAmount therefore becomes 0 (often a Prisma.Decimal) instead of triggering validation. Because milestones are tracked as MilestoneStatus, a milestone with a 0 target can be created and immediately be considered "satisfied" once any donation arrives, unlocking funds prematurely.
A class-validator decorator such as @IsNumber / @Min(0.0000001) is also absent from the inferred DTO shape (the field is typed via (m.targetAmount ?? 0) as any rather than properly declared).
Recommendation
- Define a typed
CreateMilestoneDto class with @IsNumber and @Min(0.0000001), and validate it via class-validator at the controller boundary.
- Remove the
as any cast; let Prisma receive a properly typed Decimal.
- Add unit tests asserting that zero / negative / non-numeric milestone targets are rejected with
400 Bad Request.
Severity: Medium
Type: Bug
Scope: Campaigns
Labels:
bug,good first issueDescription
CampaignsService.createCampaign(src/campaigns/campaigns.service.ts, line ~37) maps incoming milestone DTOs astargetAmount: (m.targetAmount ?? 0) as any. A missing or zero-valuedtargetAmounttherefore becomes0(often aPrisma.Decimal) instead of triggering validation. Because milestones are tracked asMilestoneStatus, a milestone with a0target can be created and immediately be considered "satisfied" once any donation arrives, unlocking funds prematurely.A
class-validatordecorator such as@IsNumber/@Min(0.0000001)is also absent from the inferred DTO shape (the field is typed via(m.targetAmount ?? 0) as anyrather than properly declared).Recommendation
CreateMilestoneDtoclass with@IsNumberand@Min(0.0000001), and validate it viaclass-validatorat the controller boundary.as anycast; let Prisma receive a properly typedDecimal.400 Bad Request.