src/teams/team-split.util.ts's validateSplitPercentages() and src/escrow/escrow.service.ts's private assertValidSplits() both exist to answer the same question — "does this list of recipient percentages sum to 100, with no non-positive entries" — for the two places this codebase collects percentage-based splits (CreateTeamDto.members and SplitReleaseDto.recipients). They're implemented completely independently rather than sharing one utility:
- Both reject an empty list.
- Both sum percentages and reject if
Math.abs(total - 100) > 0.01.
- Both reject non-positive individual percentages.
validateSplitPercentages additionally rejects percentage > 100 per-entry; assertValidSplits doesn't bother, because SplitRecipientDto.percentage already has @Max(100) — but TeamMemberSplitDto.percentage doesn't have an equivalent @Max() (already tracked separately), so the one place this duplication isn't purely cosmetic is exactly the one place the two implementations diverge in strictness.
Consolidating into one shared validator (in src/common/, alongside money.validator.ts/stellar-address.validator.ts) would remove the duplication and make the two DTOs' validation strictness consistent by construction rather than by two authors remembering to keep them in sync.
src/teams/team-split.util.ts'svalidateSplitPercentages()andsrc/escrow/escrow.service.ts's privateassertValidSplits()both exist to answer the same question — "does this list of recipient percentages sum to 100, with no non-positive entries" — for the two places this codebase collects percentage-based splits (CreateTeamDto.membersandSplitReleaseDto.recipients). They're implemented completely independently rather than sharing one utility:Math.abs(total - 100) > 0.01.validateSplitPercentagesadditionally rejectspercentage > 100per-entry;assertValidSplitsdoesn't bother, becauseSplitRecipientDto.percentagealready has@Max(100)— butTeamMemberSplitDto.percentagedoesn't have an equivalent@Max()(already tracked separately), so the one place this duplication isn't purely cosmetic is exactly the one place the two implementations diverge in strictness.Consolidating into one shared validator (in
src/common/, alongsidemoney.validator.ts/stellar-address.validator.ts) would remove the duplication and make the two DTOs' validation strictness consistent by construction rather than by two authors remembering to keep them in sync.