- safeParsePhotos(): corrupted photo_urls JSON no longer crashes every request
that loads the dog
- DELETE /photos/:idx rejects NaN/out-of-range indexes with 400 (was silent no-op)
- PUT /:id returns 404 for missing dogs (was silent success)
- POST/PUT validate sire/dam exist, have the right sex, and aren't the dog itself
- Dog create (dog+parents), update (dog+parent swap), and cascade delete now run
in transactions — no more partial writes
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
All list endpoints now accept ?page and ?limit (default 50, max 200) and
return { data, total, page, limit } instead of a bare array, preventing
memory and performance failures at scale.
- GET /api/dogs: adds pagination, server-side search (?search) and sex
filter (?sex), and a stats aggregate (total/males/females) for the
Dashboard to avoid counting from the array
- GET /api/litters: adds pagination; also fixes N+1 query by fetching
all puppies for the current page in a single query instead of one per
litter
- DogList: moves search/sex filtering server-side with 300ms debounce;
adds Prev/Next pagination controls
- LitterList: uses paginated response; adds Prev/Next pagination controls
- Dashboard: reads counts from stats/total fields instead of array length
- LitterDetail, LitterForm: switch dogs fetch to /api/dogs/all (complete
list, no pagination, for sire/dam dropdowns)
- DogForm: updates litters fetch to use paginated response shape
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>