Pet photo upload: staff and customer portal #93
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Staff and customers should be able to upload, view, and manage photos of pets. Mobile-first UX is required.
Parent: GRO-112
Technical Plan
Storage
Use S3-compatible object storage via Rook-Ceph RGW (per cluster policy). Photos stored in a dedicated bucket
groombook-pet-photoswith key patternpets/{petId}/{timestamp}.{ext}.Presigned URL flow — binary data never touches the API server:
Database Changes
Add columns to
petstable:photoKey TEXT— S3 object key (nullable)photoUploadedAt TIMESTAMP— when the photo was last updated (nullable)No separate photos table — one photo per pet for MVP. Can extend to gallery later if needed.
API Endpoints
POST/api/pets/:petId/photo/upload-urlPOST/api/pets/:petId/photo/confirmDELETE/api/pets/:petId/photoGET/api/pets/:petId/photoPublic booking portal: Read-only photo display (no upload from booking flow).
Customer portal (impersonation): Customers can upload photos for their own pets only.
Frontend Components
PetPhotoUpload— Drag-and-drop or tap-to-select image input. Shows preview. Client-side resize to max 1200px before upload to reduce bandwidth on mobile.PetPhotoDisplay— Responsive image display with loading skeleton. Used on pet profile cards and detail pages.PetPhotoCrop— Optional crop/adjust before upload using a lightweight library (e.g.,react-image-croporreact-easy-crop).Mobile-first: touch-friendly upload area, responsive image sizing, lazy loading.
S3 Client
Add
@aws-sdk/client-s3and@aws-sdk/s3-request-presignertoapps/api/. Configure via env vars:S3_ENDPOINT— Rook-Ceph RGW endpointS3_BUCKET— bucket nameS3_ACCESS_KEY_ID/S3_SECRET_ACCESS_KEY— credentialsS3_REGION— defaults tous-east-1(Ceph convention)RBAC
Photo upload/delete follows existing RBAC:
Implementation Order
photoKey,photoUploadedAtto pets)apps/api/src/lib/s3.tsPetPhotoDisplaycomponentPetPhotoUploadwith resize and optional cropcc @cpfarhood
Product Prioritization Flag
Pet photos are listed as P3 (Someday/maybe) in the product backlog (#84) and explicitly in the Gray Area of the product scope: "evaluate when core is stable."
Core is not yet stable for this purpose:
We have three P1 features in the approved build order that directly serve the primary persona and address security gaps. Pet photos are a nice-to-have that introduces real complexity (S3-compatible object storage, presigned URLs, client-side resize, RBAC for customer uploads).
Recommendation: Defer this until the three P1 features ship. The technical plan here is solid — it can be picked up as-is once the core feature gaps are closed. I don't want Scrubs splitting attention between security-critical RBAC work and a P3 feature.
If there's a compelling reason to reprioritize (user demand signal, adoption blocker), I'm open to hearing it. But absent that, this should wait.