Skip to content
Akhil Pinnani
Back to selected work

Gauntlet AI, 2025

RapidPhotoUpload

A Spring Boot and React media platform for uploading large photo batches straight to object storage.

Sign-in required for the gallery.

The problem

Bulk upload of high-resolution photos: getting a large batch up quickly and surviving the failures that come with sending a thousand of anything over a network.

Overview

RapidPhotoUpload is a Spring Boot and React media platform: bulk photo upload straight to object storage, EXIF and thumbnail processing, a searchable gallery, and live progress over WebSocket. I built it against a PRD during the Gauntlet AI fellowship.

The repository is candid about performance. Uploading a large batch got faster because the backend left the data path for small files, client concurrency went up, and a self-imposed rate limit was lifted. Chunking buys recovery, not throughput. The method and numbers are in the repo's PERFORMANCE.md.

What I built

  • Direct-to-storage upload for files at or below 5 MiB: the browser PUTs to Cloudflare R2 with a presigned URL, so the bytes never cross the backend.
  • Chunked upload above 5 MiB, in 5 MiB pieces, ten in parallel per file. Sessions survive a reload: the client asks the server which chunks it holds and sends only the rest.
  • Validation that survives the bytes not crossing the server: the presigned URL is signed over content-length and content-type, and completion verifies the stored object's real size and sniffs its format.
  • A processing pipeline for EXIF extraction and three thumbnail sizes per photo, a gallery with search, filters, sorting and pagination, and JWT auth with per-user quotas and rate limiting.

Stack

  • Java 17 and Spring Boot 3 REST API with Spring Security and JWT, JPA/Hibernate, PostgreSQL and Flyway migrations.
  • A React and TypeScript web client and a React Native client sharing a typed API client.

A bug worth telling

  • A structural test failure kept 16 of 20 backend tests from running: Postgres-only jsonb columns broke H2 schema generation. I fixed it, documented the root cause, and grew the JUnit suite to 35 tests.

Stack

  • Java 17
  • Spring Boot
  • PostgreSQL
  • React
  • TypeScript
  • Cloudflare R2

Status

Deployed demo and public source.