Patrik Warranty Form
Production warranty registration portal for Patrik windsurfing products — multi-step form, direct-to-S3 photo uploads, dual persistence to MongoDB and Google Sheets, transactional email, and IP rate limiting.
The shape of the problem
Patrik International needed a way for customers to submit warranty claims — with proof photos — and for staff to receive structured notifications without manually chasing attachments. File bytes going through a Next.js server would be slow and expensive; a plain form with email attachments wouldn't scale.
What I built
A Next.js App Router portal where each claim flows through a multi-step form: customer details, product info, address autocomplete via Mapbox, and four photo slots (invoice, serial number, full product, close-up).
Photos upload directly to Hetzner S3 via presigned PUT URLs — the server never touches the file bytes. On submit, the server writes to MongoDB and appends a row to a Google Sheet simultaneously, then fires a customer confirmation email and a staff notification in parallel. A MongoDB-backed sliding-window rate limiter blocks abuse per endpoint and surfaces a live countdown in the UI on 429.
The health endpoint (GET /api/health) pings MongoDB, verifies SMTP, and asserts Sheets config — returns 200 or 503 so the load balancer knows what's actually alive.
Lessons
- Presigned S3 uploads cut server memory and latency to near zero for file-heavy forms.
- Dual persistence (MongoDB + Sheets) sounds redundant until the operations team opens Sheets and never asks for a dashboard.
- Boot-time env validation that crashes the server early beats silent runtime failures by a wide margin.