AI Morning Dashboard
Serverless daily briefing that aggregates seven personal data feeds — including Google Calendar — passes them all to Claude simultaneously, and surfaces what's actually relevant — with a Blazor WASM frontend built entirely in .NET.
The Idea
Every morning I was opening seven tabs: Hacker News, Dev.to, GitHub, Steam, weather, Google Calendar, and a to-do list. The data was all there — what was missing was anything that connected the dots. A trending article about .NET performance is more interesting when you pushed a performance-sensitive commit yesterday. A reminder to prep for a presentation is more urgent when the forecast shows a bad commute.
I wanted a single dashboard that aggregated all of it and used AI to reason across sources — not just summarize each one in isolation. That's the job Claude is actually good at: correlating things a simple aggregator can't.
Proof of Concept: AI as a Cross-Source Reasoning Layer
The data sources here are deliberately personal — GitHub commits, Steam games, weather. Some of them are a little silly. That's intentional. The real question this project is answering isn't "what's my weather today?" — it's: what happens when you give an AI model access to multiple heterogeneous data sets simultaneously and ask it to reason across all of them at once?
Replace the personal feeds with enterprise data — inventory levels, support ticket volume, sales pipeline, deployment frequency, on-call incidents — and the same architecture surfaces insights that no individual dashboard can: an unusual spike in tickets correlated with a recent deploy, a sales slowdown in a region that also has an active logistics incident, a pattern across datasets that's invisible when you look at them one at a time. The Google Calendar integration is a good example of this in practice — Claude can now see your actual schedule alongside everything else, so it can flag that a trending architecture article is worth reading before an 11am review meeting, or that two overdue reminders need to move given a packed afternoon.
The personal context makes it easy to validate whether the AI is actually reasoning or just summarizing. When Claude notes that a trending Dev.to article on async performance is relevant because you pushed async-heavy code yesterday, you can verify that's a real insight, not hallucination. That kind of ground truth is harder to establish with enterprise data. The personal proof of concept lets you build confidence in the pattern before applying it at scale.
What It Does
Every morning, an EventBridge-scheduled pipeline runs. DataFetcher Lambda pulls from seven sources in parallel and writes raw JSON to S3. Summarizer Lambda reads that data and passes everything to Claude Haiku 4.5 via AWS Bedrock in a single invocation — generating three AI outputs at once. The result is stored in DynamoDB. The Blazor frontend reads it on demand through a cached API Gateway endpoint.
- Google CalendarToday's events via OAuth
- Hacker NewsHN Algolia API
- Dev.toTrending articles
- GitHubYesterday's commits
- SteamRecently played
- WeatherOpenWeather current + 3-day
- Task QueueDynamoDB reminders
- Daily Briefing Flags relevant articles, connects cross-source insights, ranks today's priority actions
- Daily Dev Challenge Randomized interview-style question across C#, Blazor, AWS, and SQL
- Cult Vault: B-Horror Pick TMDB real low-popularity films → Claude curates one. No hallucinated titles.
Fetches all seven sources in parallel. Each call wrapped in SafeFetch — a single source failing (rate limit, outage) returns null instead of crashing the pipeline. Writes raw JSON snapshot to S3 with 7-day retention.
Reads raw data from S3. Passes all seven feeds to Claude simultaneously in a single invocation — daily briefing, dev challenge, and B-horror pick generated in one call. Writes result to DynamoDB with 48h TTL.
Reads the latest summary from DynamoDB on demand. Reserved concurrency capped at 5. Result passed through API Gateway's 1-hour cache — Lambda only invokes on cache miss.
Engineering Decisions
Three Lambdas instead of one. Each step has a different timeout profile and failure mode. DataFetcher wraps every external call in SafeFetch — if HN rate-limits or Steam goes down, the rest of the pipeline continues with nulls instead of crashing. Separating the functions makes failures debuggable and retries cheap without re-running the expensive Bedrock invocation.
Blazor WASM over React or plain JS. The entire backend is .NET. Blazor lets the frontend reference Dashboard.Shared directly — the same DashboardRecord, Reminder, and SteamGame types the Lambdas use. No duplicated type definitions, no JSON property name guessing, compile-time null safety across the full stack.
TMDB + Claude instead of pure prompting. Claude hallucinates film titles when asked to recommend obscure movies from memory. TMDB's discover API with sort_by=popularity.asc and vote_count.gte=50 surfaces real low-popularity films. Claude picks from that verified list — real data for existence, AI for curation.
API Gateway 1-hour cache. The pipeline runs once daily. There's no value in hitting DynamoDB on every browser refresh. Caching at the gateway layer means the Lambda only invokes when the cache is cold.
Scale and Cost
| Data sources integrated | 7 (Google Calendar, HN, Dev.to, GitHub, Steam, OpenWeather, TMDB) |
| AI invocations per day | 1 — pipeline runs once, result cached 48h |
| Lambda functions | 3 with reserved concurrency caps |
| Estimated monthly cost | $0–$2 (Bedrock ~$0.30, rest free tier) |
| Secrets in code | Zero — all in SSM Parameter Store as SecureString |
My Role
Personal project, built end to end.
- Designed the 3-Lambda Step Functions pipeline with EventBridge scheduling
- Implemented all three Lambda functions in .NET 8 / C# with
SafeFetchresilience pattern - Integrated AWS Bedrock with cross-region inference for Claude Haiku 4.5
- Built full infrastructure in AWS CDK (C#) — EventBridge, Step Functions, Lambdas, DynamoDB, S3, API Gateway, SSM, SNS, CloudWatch
- Built the Blazor WASM frontend with a dedicated component per widget and shared type library
- Integrated Google Calendar via OAuth refresh token — built a small CLI tool to handle the OAuth flow and store the refresh token in SSM
- Implemented
?mockmode for demo deployments using a static JSON fixture - Designed the TMDB + Claude hybrid approach to eliminate hallucinated film recommendations