PeakSeek answers a simple traveler question: where is actually good right now? Traditional travel sites sell destinations. PeakSeek sells timing: it ranks 117 public hubs by outdoor conditions first — surf, powder, wind, climbing, scuba — then overlays flight pricing, on the premise that for adventure travel the conditions matter more than the date.
Cache-First, Then Render
Most platforms hit weather APIs on every page load. PeakSeek inverts this with a waterfall pattern: scheduled jobs fetch and evaluate weather data, write results to Upstash Redis, and fall back to a checked-in durable snapshot when live cache data is unavailable. If Tomorrow.io or OpenWeather is slow, rate-limited, or down during refresh, the public site keeps serving the last verified evaluation — user-facing latency is decoupled from API reliability.
The page architecture matches this model. Discovery and destination pages use unstable_cache with 1-hour revalidation, rendering as ISR: most users hit the CDN, revalidation happens on schedule, no live API call in the request path. An in-memory LRU fallback handles Redis unavailability. The critical property is that an external API failure degrades gracefully to stale data rather than a broken page.
A Shared Sport Evaluation Layer
The public destination model spans surf, wind, powder, climbing, scuba, whitewater, and more across 117 hubs. Each sport has different acceptance criteria — powder requires temperature, snowfall depth, and recent accumulation; surf requires swell height, period, and offshore wind direction. Instead of N sport-specific scoring functions, the evaluation layer is a shared policy engine that each sport parameterizes. Adding a sport means defining its acceptance criteria, not writing new infrastructure.
All 117 public hubs run through the same code path on each refresh cycle. Scoring is consistent, ranking is reproducible, and there’s one place to tune or debug evaluation logic.
Auth and Edge Security
Supabase handles auth with row-level security policies enforcing data ownership at the database layer — users can only read and write their own saved hubs and trip data, regardless of what the client sends. Session tokens live in HttpOnly cookies, not localStorage, making them inaccessible to JavaScript in the page.
Static security headers live in the app configuration, while proxy middleware focuses on rate limiting and route-specific CORS. Auth logic has one home rather than being reproduced across API routes. Flight deal data follows the same cache pattern as weather: refreshed off the render path, Redis-backed, and never fetched on request.

