Skip to content

Comments

feat: add pet photo upload and management#120

Merged
llinsss merged 7 commits intoDogStark:mainfrom
dmystical-coder:feat/pet-photo-management
Feb 22, 2026
Merged

feat: add pet photo upload and management#120
llinsss merged 7 commits intoDogStark:mainfrom
dmystical-coder:feat/pet-photo-management

Conversation

@dmystical-coder
Copy link
Contributor

@dmystical-coder dmystical-coder commented Feb 21, 2026

Closes #64


Description

  • Add multi-photo upload, gallery management, and S3 storage integration for pet profiles
  • Implement drag-to-reorder, set-primary, and delete functionality with both client-side and server-side image processing
  • Create pet detail page (/pets/[id]) with the photo manager embedded in context

Related Issues

Closes issue #64

Changes Made

Criteria Implementation
Multiple photo upload Drag-and-drop + file picker supporting up to 10 files at once; enforces 10-photo-per-pet limit server-side
Set primary photo PATCH /pets/:id/photos/:photoId/primary — clears previous primary, sets new one; auto-promotes next photo when primary is deleted
Photo ordering PUT /pets/:id/photos/reorder — persists displayOrder column; frontend uses @dnd-kit/sortable for drag-to-reorder with optimistic updates
Image compression Client-side: browser-image-compression (max 2MB, 1920px) before upload. Server-side: sharp via ImageProcessingService for further compression + EXIF metadata stripping
Thumbnail generation Server-side 150x150 attention-cropped JPEG thumbnails via sharp; stored as separate S3 objects with dedicated thumbnailUrl and thumbnailStorageKey
S3 storage integration Uses existing StorageServiceS3StorageProvider; keys structured as uploads/pets/{petId}/photos/ and uploads/pets/{petId}/thumbnails/
Delete photos DELETE /pets/:id/photos/:photoId — removes both original and thumbnail from S3, deletes DB record, re-indexes display order

API Endpoints

  • GET /pets/:petId/photos — List photos (ordered by displayOrder)
  • POST /pets/:petId/photos — Upload multiple photos (multipart/form-data)
  • PATCH /pets/:petId/photos/:photoId/primary — Set as primary photo
  • PUT /pets/:petId/photos/reorder — Reorder photos
  • DELETE /pets/:petId/photos/:photoId — Delete photo

New Dependencies (frontend)

  • @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities — drag-to-reorder gallery
  • browser-image-compression — client-side image optimization

How to Test

  • Upload single and multiple photos (JPEG, PNG, WebP) and verify they appear in the gallery
  • Verify photos exceeding the 10-photo limit are rejected with a clear error message
  • Drag a photo to reorder and confirm the new order persists after page reload
  • Click "Primary" on a non-primary photo and verify the badge moves
  • Delete the primary photo and confirm the next photo auto-promotes
  • Delete a non-primary photo and verify gallery re-indexes correctly
  • Upload a large image (>2MB) and confirm client-side compression reduces size before upload
  • Verify thumbnails are generated and displayed in the gallery grid
  • Confirm S3 objects (original + thumbnail) are created on upload and removed on delete
  • Test drag-and-drop file upload into the dropzone
  • Verify responsive layout on mobile viewports

Screenshots (if applicable)

Checklist

  • My code follows the project's coding style.
  • I have tested these changes locally.
  • Documentation has been updated where necessary.

dmystical-coder and others added 7 commits February 21, 2026 11:38
Add @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities for
drag-to-reorder photo gallery, and browser-image-compression for
client-side image optimization before upload.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add thumbnailUrl, storageKey, thumbnailStorageKey, displayOrder,
mimeType, fileSize, width, height, and originalFilename columns
to support photo ordering, thumbnail references, and S3 storage
key tracking.

Co-authored-by: Cursor <cursoragent@cursor.com>
Implement PetPhotosService and PetPhotosController with endpoints for:
- POST /pets/:id/photos (multi-file upload with S3 storage)
- GET /pets/:id/photos (list ordered photos)
- PATCH /pets/:id/photos/:photoId/primary (set primary photo)
- PUT /pets/:id/photos/reorder (drag-to-reorder support)
- DELETE /pets/:id/photos/:photoId (S3 cleanup + auto-promote primary)

Integrates with existing StorageService for S3 uploads and
ImageProcessingService for server-side compression and thumbnail
generation. Enforces a 10-photo-per-pet limit.

Co-authored-by: Cursor <cursoragent@cursor.com>
Create PetPhotos component suite:
- PhotoUploader: drag-and-drop multi-file upload with client-side
  compression via browser-image-compression and staged file previews
- PhotoGallery: sortable grid using @dnd-kit for drag-to-reorder
- PhotoCard: individual photo card with set-primary and delete actions
- PetPhotosManager: orchestrator handling state, API calls, optimistic
  updates, error handling, and upload progress tracking

Add petPhotosAPI client with upload progress callback support.

Co-authored-by: Cursor <cursoragent@cursor.com>
Create /pets/[id] dynamic page that displays pet information and
embeds the PetPhotosManager component directly in context. Includes
pet header with primary photo avatar, details grid, responsive layout,
and back navigation.

Co-authored-by: Cursor <cursoragent@cursor.com>
@llinsss llinsss merged commit 4791a38 into DogStark:main Feb 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Pet Photo Management

2 participants