PATCH /api/snowball/order silently swallows invalid rows #52

Closed
opened 2026-05-16 21:43:12 -05:00 by null · 1 comment
Owner

Severity: MED 🟡

Affected Files

  • routes/snowball.js — ~line 220

Problem

PATCH /api/snowball/order accepts an array of {id, snowball_order} pairs and updates each one. Invalid or non-integer snowball_order values are quietly skipped:

for (const item of items) {
  if (!Number.isInteger(item.snowball_order)) continue; // silently skipped
  // ... update ...
}

The client receives a 200 with no indication that some rows failed to reorder. There's no count of skipped rows, no validation error, no partial success indicator.

Impact

  • Frontend can't tell the user that some bills weren't reordered
  • Debugging reordering failures requires server-side logs
  • Inconsistent with how other endpoints return validation errors

Fix

Return a summary in the response:

{
  "updated": 5,
  "skipped": 2,
  "skipped_ids": [12, 34]
}

Or reject the entire request if any items are invalid (preferred — keeps client and server in sync).

Acceptance Criteria

  • Invalid snowball_order values are reported to the client
  • Response includes count of updated vs skipped rows
  • Or: entire request is rejected if any item is invalid (preferred)
## Severity: MED 🟡 ## Affected Files - `routes/snowball.js` — ~line 220 ## Problem `PATCH /api/snowball/order` accepts an array of `{id, snowball_order}` pairs and updates each one. Invalid or non-integer `snowball_order` values are quietly skipped: ```javascript for (const item of items) { if (!Number.isInteger(item.snowball_order)) continue; // silently skipped // ... update ... } ``` The client receives a 200 with no indication that some rows failed to reorder. There's no count of skipped rows, no validation error, no partial success indicator. ## Impact - Frontend can't tell the user that some bills weren't reordered - Debugging reordering failures requires server-side logs - Inconsistent with how other endpoints return validation errors ## Fix Return a summary in the response: ```json { "updated": 5, "skipped": 2, "skipped_ids": [12, 34] } ``` Or reject the entire request if any items are invalid (preferred — keeps client and server in sync). ## Acceptance Criteria - [ ] Invalid `snowball_order` values are reported to the client - [ ] Response includes count of updated vs skipped rows - [ ] Or: entire request is rejected if any item is invalid (preferred)
null added the
priority:medium
backend
labels 2026-05-16 21:43:12 -05:00
Author
Owner

Fixed in 44320a7. Pre-validates all rows before touching the DB, rejects bad entries with a 400, adds deleted_at IS NULL filter, returns updated count.

Fixed in `44320a7`. Pre-validates all rows before touching the DB, rejects bad entries with a 400, adds `deleted_at IS NULL` filter, returns updated count.
null closed this issue 2026-06-03 20:48:31 -05:00
Sign in to join this conversation.
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: null/BillTracker#52
No description provided.