biehl.io
All case studies

Sonora Fly Co. / reporst.sonoraflyco.com

Building a Live Fly-Fishing Intelligence Platform for Sonora Fly Co.

I designed and built Sonora Fly Co.’s live fishing-report platform, combining interactive maps, local editorial guidance, river and weather data, access points, scheduled ingestion, and context-aware ecommerce.

Who
Sonora Fly Co. / reporst.sonoraflyco.com
What
Design and build a live fly-fishing intelligence platform across reports, environmental data, mapping, editorial content, and commerce
Result
A decision-ready fishing platform connecting local expertise, live river conditions, access, weather, and relevant products
Sonora Fly Co. live fishing intelligence platform case study cover

Project snapshot

Client / context: Sonora Fly Co., a fly-fishing outfitter serving Yosemite, Sonora Pass, and the Sierra Nevada

Role: Full-stack design engineer

Focus: Fishing-report UX, live environmental data, interactive mapping, editorial tooling, ecommerce integration, responsive design, and performance

Stack: Next.js 14, React, TypeScript, Tailwind CSS, Radix UI, Leaflet, Recharts, Notion API, MongoDB, Mongoose, Inngest, OpenWeather, USGS, California Data Exchange Center, Dreamflows, Square Catalog API, GoDaddy blog feeds, Vercel Speed Insights

Live site: reports.sonoraflyco.com

One-line version

I designed and built a live fly-fishing intelligence platform that combines local reports, river conditions, weather, access maps, tactics, guides, fly selections, and shoppable gear in one responsive experience for Sonora Fly Co. customers.

The challenge

A useful fishing report is more than an article.

Anglers planning a day in the Sierra need to understand where conditions are promising, how water is moving, whether temperatures are safe, what the weather is doing, where they can access the river, and which flies or gear make sense. That information lives across systems with very different shapes and update cycles:

  • editorial reports written by local experts
  • river-flow readings from USGS and California state sources
  • Dreamflows data that required scheduled collection
  • current conditions and forecasts from OpenWeather
  • access-point coordinates and descriptions
  • shop products managed in Square
  • tactics, guide profiles, and adventure stories from an existing blog
  • location relationships and ratings maintained by the Sonora Fly Co. team

The product challenge was to turn those sources into one experience without making the customer understand the underlying integrations.

The operational challenge was equally important. Shop staff needed to update reports and relationships without editing application code, while time-sensitive environmental data needed to refresh automatically. The site also had to stay useful on a phone, where many anglers would check conditions or navigate to an access point.

My role

I designed and built the product across experience, interface, application architecture, data integration, and operations.

My work included:

  • defining the information architecture for the reports index and individual river pages
  • designing responsive map, card, accordion, tab, chart, forecast, and product patterns
  • building the application in Next.js, React, TypeScript, and Tailwind CSS
  • using Notion as a structured publishing and relationship layer
  • connecting USGS, CDEC, Dreamflows, OpenWeather, Square, and blog-feed data
  • building scheduled Dreamflows ingestion and rolling data retention with Inngest and MongoDB
  • translating raw flow, release, water-temperature, weather, and moon data into readable UI
  • connecting fishing reports to access points, flow gauges, tactics, guides, flies, and gear
  • implementing caching, server rendering, lazy loading, Suspense boundaries, responsive images, and performance instrumentation
  • handling partial data and third-party failures so one missing source did not erase the rest of the report

Selected work

1. A map-first reports experience

The home page begins with an interactive map because fishing decisions are inherently geographic.

I built a Leaflet and OpenStreetMap experience that plots every published report, centers itself around the active set of locations, and gives each marker a visible fishing rating. The hottest location receives an additional alert treatment, while marker popovers connect directly to the full report.

Below the map, a hot-spots grid and complete accordion list give customers alternate ways to browse. The list combines the latest editorial context with current conditions, so users can compare locations without opening every page.

The map also becomes a different tool inside a report. Instead of showing report locations, it displays related access points. Selecting an access point moves the map, reveals its description, and provides a direct handoff to Google Maps navigation.

This was one component serving two distinct jobs: regional discovery on the home page and practical river access on the detail page.

2. A report page organized around decisions

I designed each river page as a decision-support surface rather than a long article.

The page brings together:

  • a clear river or destination title
  • a visual fishing rating
  • the latest local report
  • tactics for the specific water
  • relevant guides and adventures
  • recommended flies and gear
  • current flow and water temperature
  • historical flow charts
  • dam-release schedules when available
  • current weather, wind, pressure, forecast, and moon phase
  • mapped access points with navigation

Tabs keep the editorial and product layers easy to scan. Larger environmental sections receive their own visual rhythm, while expandable charts and forecasts preserve detail without overwhelming the first view.

The result gives an angler a fast answer to “should I go?” and enough depth to plan how.

3. Notion as a relational field-report CMS

The team needed an approachable way to manage content, ratings, and location relationships.

I used Notion as more than a rich-text CMS. Structured databases model:

  • published fishing destinations
  • overall ratings
  • coordinates and slugs
  • GoDaddy blog categories
  • access points
  • river-flow measurement points
  • CDEC, USGS, and Dreamflows identifiers
  • release stations
  • fly and gear SKU relationships

The application queries published reports, sorts them by rating, resolves related access and flow records, and converts report-page blocks into Markdown for the site.

That architecture lets the team change a rating, connect an access point, associate a gauge, or update report copy in a familiar editorial tool. The public product receives structured data without requiring a custom admin panel.

4. One environmental model across multiple sources

No single provider covered every river and data type the product needed.

I built a source-selection and fallback model across USGS, the California Data Exchange Center, and Dreamflows. For each flow point, the system can retrieve:

  • current flow
  • historical flow
  • water temperature
  • reservoir outflow when direct river flow is unavailable
  • dam-release schedules when applicable

The interface does not expose the complexity of those provider boundaries. It shows a consistent current reading and chart model regardless of the source behind it.

I also filtered invalid sentinel values, normalized dates and units, and used California time when building state-data request windows. Those details are easy to miss in a visual design, but they determine whether the experience is trustworthy.

5. Scheduled Dreamflows ingestion and rolling storage

Dreamflows required a different integration strategy from the JSON APIs.

I built an Inngest workflow that:

  • runs on a schedule
  • reads the active Dreamflows station IDs from Notion
  • downloads and parses the current CSV feed
  • filters the feed to the locations used by the product
  • upserts river identity records in MongoDB
  • saves time-series flow and water-temperature readings without duplicating the same timestamp

A second scheduled function removes readings older than one week.

This created a small data pipeline inside the application: editorial configuration in Notion controls which stations matter, Inngest coordinates collection, MongoDB preserves the rolling history, and the report UI reads a stable model instead of scraping the source during every page request.

6. Weather designed for anglers

A generic weather widget would not answer the questions this audience cares about.

I translated OpenWeather data into a river-specific conditions module with:

  • current temperature and “feels like” context
  • condition illustrations and weather icons
  • wind speed and compass direction
  • atmospheric pressure
  • moon phase
  • an expandable forecast

The component sits alongside river data instead of apart from it. Weather, flow, temperature, and release information become one planning context.

The interface also uses compact tooltips and responsive layouts so dense environmental information remains readable without becoming a dashboard full of unexplained numbers.

7. Editorial content connected to commerce

The reports experience supports the retail business without turning every section into an advertisement.

I connected existing Sonora Fly Co. blog feeds to report-specific categories for:

  • current fishing reports
  • tips and tactics
  • local guides
  • 32 Hour Adventure stories

I also connected report relationships in Notion to the Square catalog. Fly and gear SKUs resolve to current product names, images, prices, and ecommerce URLs, then appear in responsive carousels that link to the shop.

This keeps recommendations contextual. Products appear because they are associated with a specific destination or report, not because the page has a generic merchandising slot.

8. Responsive interaction for field use

The product needed to work at a desk, in the shop, and beside the river.

I designed separate responsive behavior where the content demanded it:

  • maps and access-point details shift from side-by-side to stacked layouts
  • report lists use accordions on constrained screens
  • tactics and guide content moves from grids to compact expandable items
  • carousels expose touch-friendly product browsing
  • long report content uses a mobile read-more treatment
  • tabs keep report categories reachable without a long page of competing sections
  • images use optimized Next.js rendering and placeholders

The goal was not only to make the desktop layout shrink. It was to preserve the decisions a customer needs to make when screen space and attention are limited.

9. Performance across many remote dependencies

A report page can call multiple remote services, databases, and content sources. That made performance an architectural concern.

I used:

  • Next.js server components for data-heavy sections
  • cache revalidation appropriate to each source
  • lazy-loaded report modules
  • localized Suspense boundaries
  • responsive and optimized images
  • component-level loading states
  • Vercel Speed Insights
  • a MongoDB-backed cache path for collected Dreamflows data

Breaking the page into independent server-rendered sections meant slower integrations did not have to define the structure of the whole experience. It also made the system easier to reason about: each module owns its data and its user-facing fallback.

Design engineering approach

Design from the trip-planning decision backward

I began with the questions an angler asks: Where should I go? What are the conditions? How do I get there? What should I use? The page structure follows that mental model instead of mirroring the source systems.

Keep editorial control close to local expertise

The shop team owns the judgment in the product: ratings, reports, access descriptions, tactics, and recommendations. Notion gives that expertise a structured publishing path without requiring developer intervention.

Normalize integrations at the product boundary

USGS, CDEC, Dreamflows, Square, OpenWeather, and the blog feed all speak different languages. I converted them into stable application concepts—report, flow point, condition, access point, article, and product—before presenting them in the interface.

Treat failure as a design state

Environmental sources can be delayed, incomplete, or unavailable. The product uses fallbacks, conditional sections, null-safe rendering, and independent loading boundaries so a missing reading does not make the whole destination disappear.

Connect content and commerce through relevance

The retail layer works because it follows the report context. A fly or product recommendation is useful when it is tied to current water and local guidance, not simply inserted into a page.

Impact

The project gave Sonora Fly Co. a dedicated digital product for turning local expertise and live conditions into customer action.

It delivered:

  • a map-first regional view of published fishing reports and current hot spots
  • destination pages that combine editorial guidance with live planning data
  • consistent flow and water-temperature experiences across USGS, CDEC, and Dreamflows
  • historical charts and release-schedule context
  • scheduled Dreamflows collection with rolling MongoDB storage
  • current weather, wind, pressure, forecast, and moon information
  • mapped access points with direct navigation
  • destination-specific reports, tactics, guides, flies, and gear
  • live Square product data connected to report recommendations
  • a Notion-based operating model for reports and relationships
  • responsive behavior for mobile field use
  • cache, loading, image, and rendering strategies for a multi-source application

The most important result is that the product turns fragmented information into one coherent local guide. It helps customers move from browsing to making a decision, preparing for the trip, finding access, and purchasing the right equipment.

What made this hard

The complexity was distributed across the whole system.

The project had to reconcile:

  • editorial judgment with rapidly changing sensor data
  • several river-data providers with different identifiers and response formats
  • JSON APIs, CSV scraping, relational Notion records, and MongoDB time series
  • live weather and forecast data
  • ecommerce catalog data that can change independently
  • blog categories that had to align with report locations
  • server-rendered sections and a client-rendered interactive map
  • dense information on small screens
  • partial failures in external services
  • caching intervals appropriate to information with different freshness requirements

The design problem was deciding what belonged together for the customer, even when it came from completely separate systems behind the interface.

What I learned

A vertical product becomes more useful when it respects both expert judgment and machine data.

The fishing rating and field report capture local experience. Flow, temperature, forecast, and release data provide measurable context. Neither is sufficient alone. The product is strongest when those layers explain each other.

I also learned that a lightweight operational tool can be the right backend for a specialized team. Notion provided a flexible relational publishing layer, while the application handled the data collection, normalization, caching, and presentation that did not belong in the editor.

Why it matters

This project demonstrates the full-stack design engineering work I enjoy most: taking a real-world decision with many hidden dependencies and making it feel straightforward.

I did not only design a fishing-report page or connect a few APIs. I built the content model, map interaction, environmental data layer, scheduled ingestion workflow, ecommerce handoff, responsive UI, caching strategy, and operational publishing path as one product system.

The result is a practical bridge between Sonora Fly Co.’s local knowledge and the live conditions customers need to act on it.