Back to all case studies

Case study

Aura Weather

Yes, it is a weather app — the most common portfolio project there is. It is also a study in defensive client-side data handling. The product answers "what is the day like?" at a glance; the engineering makes sure that when a provider returns partial, delayed, or missing data, the UI shows it as unavailable instead of coercing it into a confident, fake zero.

  • End-to-end nullish-rejection contracts
  • Independent multi-API fetch lifecycles
  • Unit, E2E, visual, and Lighthouse in CI
Project type
Weather dashboard and client-side data-trust project
Stack
React 19, Vite, plain CSS, Lucide icons, Open-Meteo + NOAA/NWS APIs (frontend-only, no UI framework)
Primary focus
Defensive data handling, resilient multi-API composition, and QA breadth that locks the trust contract
Last verified
— static, link, and route-readiness checks pass; deployed field profiling is still pending.
Aura Weather current conditions and environmental exposure interface
Captured from the public live demo on May 12, 2026.

Data trust lens

The core challenge was making weather data fast to scan without ever pretending missing data exists.

Aura answers the user's immediate question quickly while staying honest about provider limits. Three weather sources are composed with independent fetch lifecycles, every value is run through a nullish-rejection contract at the API boundary, and missing readings stay visible as unavailable rather than collapsing into misleading zeros.

Fast scanning

Current conditions, rain guidance, and hourly trends get visual priority.

Nullish-rejection contracts

Strict numeric handling at the boundary keeps null values null instead of fake zeros.

Independent fetch lifecycles

Separate requests stop one slow provider from blocking the whole experience.

Evidence Snapshot

What I built

  • Current conditions, hourly outlook, rain guidance, and risk signals
  • 7-day forecast with expandable day detail (UV, wind, sunrise/sunset)
  • Abortable, keyboard-friendly city search combobox
  • Saved + startup cities and historical archive comparison
  • NOAA/NWS severe-alert coverage

The engineering that matters

  • End-to-end nullish-rejection data contracts
  • Multi-API composition with independent fetch lifecycles
  • GPS resolved to a friendly place label, not a generic tag
  • Offline last-known restore without faking freshness
  • F/C toggle handled client-side without refetching
  • PWA shell installed after a first successful production visit

What was hard

  • Keeping weather information readable without hiding useful detail
  • Representing missing provider data honestly instead of as fake zeros
  • Making dense forecast content usable on small screens

QA breadth

  • Unit, integration, and E2E (Playwright + axe) coverage
  • Visual regression and Lighthouse budgets in CI
  • An internal audit caught a class of missing-data stability bugs
  • Each fix was locked with a regression test so the class can't return

What to verify in 90 seconds

  • Open the live demo and search a city by keyboard alone
  • Expand a forecast day for UV, wind, and sunrise/sunset
  • Find a value rendered as unavailable rather than a fake 0
  • Read an unsupported-region alert message
  • Resize to mobile and re-scan the hierarchy

Honest limits

  • This is a frontend sample, not a full production weather platform
  • Deployed Lighthouse field numbers are not captured yet
  • Reverse-geocoding edge cases for raw coordinates remain

Weather Data Trust Problem

Weather apps can become visually busy while still failing at the basic question: what does the user need to know right now? A second, deeper issue is data trust. When APIs return partial or missing values, the interface must not silently display fake readings that the user will act on.

Still to validate: real user behavior around saved cities, location permissions, and which weather panels people use most often.

Users

  • People who want a fast, readable weather snapshot before making daily decisions.
  • Mobile users scanning current conditions, hourly changes, rain guidance, and alerts.
  • Technical reviewers evaluating async data handling, API boundaries, and fallback states.

Fast-Scanning Goals

  • Make the current day understandable quickly without burying the answer in decoration.
  • Keep forecast, air quality, alerts, and climate context resilient when one source is slow or unavailable.
  • Represent missing data as missing, never as a confident zero.
  • Keep the responsive layout useful from desktop down to small mobile screens.

My Role

Sole frontend engineer. I built the dashboard layout, the keyboard combobox search, saved- and startup-location behavior, the weather API orchestration across three sources, the nullish-rejection data contracts, missing-data rendering, responsive CSS in plain stylesheets, the interface states, and the full QA suite that locks the trust contract.

Scannability Decisions

  • Start with a usable fallback forecast instead of blocking the first load on geolocation permission.
  • Prioritize the hero summary, rain guidance, and hourly trend for fast scanning.
  • Use labelled unsupported or unavailable states instead of vague failure copy.
  • Add touch-friendly mobile sample controls for dense timelines that would otherwise rely on hover.

Resilient Data Engineering

  • Independent fetch lifecycles. Forecast, supplemental data, and the climate archive are requested separately, so a secondary provider problem never blocks the core forecast.
  • Nullish-rejection at the boundary. Provider data is normalized with strict numeric handling so a missing value stays null end to end and is rendered as unavailable, never as 0.
  • Last-known recovery. Forecasts are cached with freshness limits so an offline start can restore the last-known view without presenting stale data as fresh.
  • Audit-and-lock. An internal audit surfaced a class of stability bugs in how partial provider responses flowed through the UI; each fix shipped with a regression test, so the same bug class cannot quietly return.
  • Co-located CSS. Styles live with their components in plain CSS so dashboard surfaces stay maintainable as they evolve — no UI framework required.

Missing-Data Tradeoffs

  • Constraint

    Weather data can be partial, delayed, or unavailable from individual provider endpoints.

  • Decision

    Normalize values at the API boundary with a nullish-rejection contract and render unavailable data explicitly instead of forcing fallback zeros.

  • Tradeoff

    The interface stays trustworthy, but the UI has to carry more clear empty and unsupported states — and the QA suite has to lock that contract so it can't regress.

Accessibility Considerations

  • Automated in CI: Playwright runs axe against the app's primary states as part of the end-to-end suite.
  • City search uses keyboard-friendly combobox and listbox behavior with an abortable request lifecycle.
  • Loading, refresh, error, and missing-data states use live status messaging where it helps.
  • Missing values include assistive text such as "no data available" instead of relying only on an em dash.
  • Preference-aware effects and mobile touch-target work are marked for continued interface QA.

Performance Considerations

  • Lighthouse budgets run in CI alongside the test suite, so regressions in the budgeted metrics are caught before merge.
  • Core forecast content loads before lower-priority supplemental panels; lazy panels and deferred mounting cut the work for the first useful screen.
  • Unit toggles are handled client-side, so changing F/C does not trigger unnecessary provider requests.
  • Service worker support is limited to the app shell; live weather data remains a network truth source.

QA Notes

  • The signature story: an internal audit caught a class of stability bugs around partial and missing provider data; each was fixed and then locked with a regression test, so the trust contract cannot silently regress.
  • Test pyramid: unit and integration tests, end-to-end coverage with Playwright + axe, visual regression, and Lighthouse budgets — the breadth is deliberate for a data-driven UI.
  • Evidence standard: missing-data behavior is described as a trust decision without inventing reliability metrics.
  • Still to validate: fresh production Lighthouse profiling, reverse-geocoding edge cases, and saved-city behavior with real users.

Current Status

Aura Weather is a working portfolio project with real multi-API integration, resilient loading/error behavior, defensive data contracts, and documented limitations. It should not be described as a full production weather platform.

What I Learned

Data products need honest absence states as much as polished success states. Keeping null, unavailable, and delayed provider responses visible makes the interface more trustworthy than a cleaner-looking screen with misleading fallback values — and a regression test is what keeps that honesty from eroding over time.

What I Would Improve Next

  • Capture deployed Lighthouse field numbers, then tune image and paint cost from real data.
  • Improve reverse-geocoding for raw device coordinates.
  • Revisit saved-city sync if the project needs account-level trust rather than lightweight optional sync.
  • Use product analytics or user testing to decide which panels deserve the most visual priority.