Portfolio/Private
Private project logo

Weather InTouch

A full-stack, multi-channel weather forecast platform built around proactive alerts and automation rather than passive data display. Weather InTouch pairs a free open-data backbone with a cost-controlled caching layer that deduplicates paid weather-API calls across all users. It runs in production as a B2C web app — live weather cards, official alerts from seven national sources, watchdog automations, an AI weather assistant and Stripe billing — backed by a multilingual marketing site and blog spanning 20 languages. An embeddable white-label widget is built and rolling out, with the native iOS/Android shell (Capacitor) pending store release.

My Role & Activities

  • Product architecture and monorepo design
  • Full-stack development (Angular 22 + NestJS 11)
  • Cost-control caching engine (two-layer single-flight + Redis)
  • Shared DTO package as single source of truth
  • Auth (Apple Sign-in + Google OAuth, token-on-backend)
  • Stripe billing (Free / Plus / Pro tiers)
  • Official weather alerts from seven national sources (NWS, ČHMÚ, DWD, MET Norway, MSC, IMD, Ireland)
  • Watchdog rules with multi-channel delivery (email, Telegram, webhook, push)
  • AI assistant, trip planner and NL-to-rule compiler (Google Gemini)
  • Loxone smart-home integration with per-client API keys
  • Embeddable white-label widget (Angular Elements web component + iframe)
  • Capacitor iOS/Android shell (geolocation, push, social login)
  • Multilingual SSG marketing site and blog (20 languages)
  • CI/CD pipelines (GitHub Actions)
Period: 2026 – Present
Role: Founder, product architect, full-stack developer
Visit site

Technologies

Architecture and delivery context

Problem

Most weather products stop at showing pretty icons. People don't pay to look at the weather — they pay to be warned in time or to have something acted on for them. At the same time, paid weather APIs are billed per call, so any service that scales to many users and locations risks runaway costs unless requests are aggressively deduplicated.

Approach

Weather InTouch is a TypeScript monorepo built around two ideas: proactive value (official alerts, watchdog rules, automations and webhooks) and disciplined cost control. A free Open-Meteo data backbone covers the bulk of the forecast, with an optional paid OpenWeather overlay for premium current-conditions — enabled by the presence of the paid API key and fetched best-effort, so the product degrades gracefully to the free backbone if the paid source is unavailable.

Product Architecture

The product spans three applications inside a single npm-workspaces monorepo, all sharing one source of truth for data shapes:

1. Web app (app.weatherintouch.com)

Angular 22 SPA with zoneless, OnPush, standalone components. Stateless weather cards (current conditions, multi-day forecast, hourly multi-variable chart, meteorological radar) receive data as inputs; a single API service proxies to the backend. Air-quality and pollen data, official alerts, and saved favourite locations round out the experience.

2. Backend API (api.weatherintouch.com)

NestJS 11 + Mongoose service that owns all paid-API access, auth, and billing. Apple Sign-in and Google OAuth use a token-on-backend pattern; JWT access and refresh tokens are issued server-side. Stripe powers the Free / Plus / Pro tiers.

3. Marketing site and blog (weatherintouch.com)

Custom TypeScript static-site generator turning Markdown + frontmatter into HTML, translated into 20 languages via a Google Gemini pipeline.

Cost-Control Engine

The core innovation is a two-layer single-flight cache. Requests are keyed by coordinates rounded to four decimals (~11 m grid) so nearby users share one cache entry. An in-process promise map collapses concurrent requests inside a single Node process, and a Redis SET NX lock (with a Lua check-and-delete) coordinates across replicas. The lock loser polls the freshly cached result instead of calling the paid API. Combined with stale-while-revalidate, the design calls the paid weather API roughly once per location per TTL (default 30 minutes) no matter how many users share that location — the property the tenant-agnostic widget depends on as it rolls out.

Business Model

  • B2C subscriptions (Free / Plus / Pro) via Stripe
  • B2B white-label widget licensing — an embeddable, stateless current-weather card for third-party sites, served from the same shared cache
  • Automation and webhooks API (developer tier) — fire a webhook when weather matches a rule, for IoT and Home Assistant integrations

Status

Live in production. The web app, backend API and multilingual marketing site are deployed (app / api / weatherintouch.com). Shipping today: auth (Apple/Google) with server-side JWT rotation, Stripe Free/Plus/Pro billing, the two-layer cost-control cache, the full weather-card suite (current conditions, six-day and 168-hour forecast, hourly multi-variable chart, meteorological radar, POI map, air quality and pollen), official alerts from seven national sources (NWS, ČHMÚ, DWD, MET Norway, MSC Canada, IMD India, Ireland), watchdog rules with multi-channel delivery (email, Telegram, webhook, push), an AI assistant, trip planner and natural-language rule compiler (Gemini), a Loxone smart-home integration with per-client API keys, and saved favourite locations. The embeddable white-label web component (Angular Elements + iframe, per-tenant keyed) is built and pending CDN rollout; the Capacitor iOS/Android shell (geolocation, push, social login) is scaffolded and pending store publishing. Still on the roadmap: per-tenant widget quotas, further smart-home targets (Home Assistant, KNX) and an admin integrations-health console.

Contact Info

Feel free to reach out for project inquiries, consulting, or longer-term collaboration. I'm open to discussing practical product work and frontend engineering opportunities.

Get in Touch

© 2026 Martin Hubalek. All rights reserved.

Martin Hubálek Business ID (IČO): 08827303 Registered office: Dolní Štěpanice 29, 514 01 Benecko, Czech Republic Registered in the Czech Trade Licensing Register Not registered for VAT