Skip to content

Repository files navigation

Weather Intelligence Dashboard

Weather data is free. Weather decisions are not.

This isn't a temperature display - it's a small explainable decision engine that turns raw weather and air quality data into specific, reasoned answers: should you carry an umbrella, is today good for a run, is the air safe to breathe, is travel likely to be disrupted.

Every recommendation comes with a plain-English reasoning trace citing the exact factor(s) behind it, instead of a black-box yes/no.

Live demo: add your deployed URL here after deploying

Add a screenshot or GIF of the dashboard here once deployed - the recommendation cards with visible reasoning are the most important thing for a visitor to see in the first few seconds.

Why this isn't a basic weather app

A typical weather app's job ends at displaying data. This project's actual subject is the recommendation engine sitting on top of that data: five independent, unit-tested rules, each with its own configurable thresholds and its own human-readable explanation, orchestrated by a small engine that knows nothing about the rules themselves. Adding a new recommendation type means writing one new class - no existing code changes. See docs/architecture.md for the full design and docs/decision-log.md for the reasoning behind every major architectural choice (why no provider averaging, why no Redis/auth/DB in v1, why thresholds live in configuration instead of code).

What it answers

  • Should I carry an umbrella today?
  • Is today good for running?
  • Is today good for outdoor activities?
  • Is today good for travelling?
  • Is the air quality safe?

v2: search, forecast, and dark mode

The original MVP answered "what should I do today, for one location." This maintenance pass extends that without changing what the project fundamentally is - still Spring Boot + Thymeleaf, still server-rendered, still zero database, still one Docker image:

  • Location search now supports disambiguation: if a search term matches more than one place, a picker is shown instead of silently guessing (e.g. searching a common city name).
  • Browser geolocation ("use my location") and hourly + 5-day forecast (Open-Meteo only, matching the project's existing no-cross-provider-fallback policy for anything beyond current conditions).
  • Pressure, visibility, sunrise/sunset, local time, and coordinates added to the conditions display.
  • Dark mode, with no flash-of-incorrect-theme, prefers-color-scheme respected on first visit, and the choice persisted in localStorage.
  • Recent searches and a retry action on the error state.
  • One new file, static/js/dashboard.js - the project's first and only client-side script, intentionally small, vanilla, and framework-free. Everything else stays server-rendered.

See the changelog at the bottom of this README for the complete list of changes made in this pass, including the Spring Boot 3.3.4 → 3.5.16 version bump (the 3.3.x line reached end-of-life).

Tech stack

  • Java 17 + Spring Boot 3.5 + Maven
  • Thymeleaf for server-rendered views
  • Vanilla JavaScript (static/js/dashboard.js) for dark mode, geolocation, and recent searches - no framework, no bundler, no build step
  • Open-Meteo (primary weather/air-quality/forecast/geocoding provider - no API key required)
  • OpenWeatherMap (documented fallback provider for current conditions only, used if Open-Meteo is unavailable; forecast has no fallback, see docs/decision-log.md)
  • Caffeine for in-memory caching with per-data-type TTLs
  • Docker + GitHub Actions CI

Running it locally

No API key is required to run this project - Open-Meteo, the primary provider, is keyless.

Prerequisites

  • Java 17+
  • (No local Maven install required - the Maven Wrapper is included)

Run

git clone https://github.com/your-username/weather-intelligence-dashboard.git
cd weather-intelligence-dashboard
./mvnw spring-boot:run

Then open http://localhost:8080.

Note: browser geolocation ("use my location") only works over localhost or HTTPS - this is a browser security restriction, not an application bug. It works fine locally and on any HTTPS deployment.

Run the tests

./mvnw clean verify

Optional: enable the OpenWeatherMap fallback

The application runs completely without this, since it only engages if Open-Meteo fails. To exercise it deliberately:

cp .env.example .env
# edit .env and set OPENWEATHERMAP_API_KEY (free key at https://openweathermap.org/api)
export $(cat .env | xargs)
./mvnw spring-boot:run

Running with Docker

docker build -t weather-intelligence-dashboard .
docker run -p 8080:8080 weather-intelligence-dashboard

or with Compose:

docker compose up --build

Project structure

src/main/java/com/portfolio/weatherintel/
├── config/        # Typed configuration properties, RestClient + cache beans
├── controller/     # Thymeleaf-facing controllers and view models
├── domain/         # Normalized domain model (WeatherSnapshot, ForecastSnapshot,
│                   #   HourlyForecastPoint, DailyForecastPoint, Location, enums)
├── provider/       # WeatherProvider interface + Open-Meteo/OpenWeatherMap implementations
├── aggregation/    # Primary/fallback orchestration with caching
├── engine/         # Rule interface, RecommendationEngine, and the five rules
├── service/        # GeocodingService
└── exception/      # Domain exceptions and the global exception handler

src/main/resources/
├── templates/      # Thymeleaf views (dashboard.html, error.html, fragments/)
└── static/
    ├── css/dashboard.css   # All styling, including the dark theme variable set
    └── js/dashboard.js     # The project's only client-side script (theme, geolocation,
                             #   recent searches) - vanilla, no build step

See docs/architecture.md for the full data flow diagram.

Recommendation engine at a glance

Rule Answers Key factors
UmbrellaRule Should I carry an umbrella? Precipitation probability, precipitation amount
RunningSuitabilityRule Is today good for running? Feels-like temperature, wind speed, AQI
OutdoorActivityRule Is today good for outdoor activities? Feels-like temperature, precipitation probability, AQI
TravelSuitabilityRule Is today good for travelling? Wind speed, precipitation probability/amount
AirQualityRule Is the air quality safe? US EPA AQI banding

All thresholds are configurable in application.yml under weather.rules.* - tuning the engine's behavior does not require a code change.

Future work (deliberately out of scope for this MVP)

  • "What to wear" recommendation (layered clothing logic)
  • User profiles / personalized sensitivity thresholds
  • Redis-backed caching for multi-instance deployment
  • User accounts and authentication
  • Historical trend visualization

Each of these is a deliberate scope decision, documented in docs/decision-log.md, not an oversight.

Deployment

See Deployment instructions below, or jump straight to docs/architecture.md for the resilience and caching design that makes this deployable as a single, stateless instance. For an evaluation of hosting options and a deployment checklist, see docs/deployment-review.md.

Changelog

See CHANGELOG.md for a complete list of changes made in each maintenance pass.

License

MIT

About

An explainable weather intelligence dashboard built with Spring Boot, Thymeleaf, and a rules-based recommendation engine.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages