Joe Barbere’s Blog

Claude "hello world"

It started, as these things do, with a "hello world." Three weeks later I had a weather-themed monorepo with micro-frontends, an event-streaming pipeline, a full observability stack, a data science platform, single sign-on across five services, and — for reasons that made sense at the time — a suite of exploits I wrote to attack my own creation.

This is the story of my first big project built entirely through conversation with Claude Code. Not a toy. Not a tutorial I followed. Just me and an AI pair programmer, a blank repo, and the words "let's build something." The repo is public: joebarbere/claude-hello-world.

By the project's own count: 260+ commits, 53,500+ lines of code, and 188 documented build steps, produced in about three weeks in March 2026. Every app, every container image, every Kubernetes manifest, every Grafana dashboard, every test — all written in natural language, back and forth.

Scope creep, as a feature

The honest premise was to learn Claude Code by pushing it. So instead of stopping at a working weather table, every time something worked I asked: what would a "real" system bolt on next? The answer kept being yes, and the thing kept growing. What follows are the highlights of what actually got built.

The frontend: micro-frontends, because of course

The foundation is an Nx monorepo driving several Angular apps wired together with Module Federation — a shell host that loads independently-deployable remotes at runtime:

They all share a design system — a @org/ui library built on PrimeNG with a dark-mode-first theme, so the whole thing looks like one product instead of five stitched-together apps.

The backend: a .NET weather brain

Behind the tables sits a .NET 9 / ASP.NET Core Weather API with Entity Framework Core talking to PostgreSQL 17. A neat touch Claude and I worked out: the API has swappable repository modes — random data (no database), in-memory CRUD, or full PostgreSQL persistence — flip one config value and the whole backend changes behavior. OpenAPI docs come free via Scalar.

Identity, and the saga that nearly broke me

Then I decided everything needed real authentication. Enter Ory Kratos — self-hosted identity, registration, sessions, and role-based access — with single sign-on wired across five separate services through Traefik's forwardAuth and a little custom auth-proxy I had Claude write to bridge Kratos sessions into Grafana, Airflow, Jupyter, and MinIO.

I'll be honest: this was the hardest part of the whole project, and the commit history shows it. There's a stretch of the log that is nothing but Kratos: switching the datastore from in-memory to PostgreSQL and back, an init-container that deadlocked on startup until we moved it to a sidecar, health-check timeouts in CI, and — my favorite — a cipher secret that had to be trimmed to exactly 32 characters. Working through that with Claude, one failed CI run at a time, taught me more about debugging distributed startup ordering than any tutorial ever has.

Event streaming and a desktop app

With data flowing, the obvious next move was to stream every change. Apache Kafka (in single-node KRaft mode, no Zookeeper) paired with Debezium for Change Data Capture: every row-level write to PostgreSQL is captured off the write-ahead log, Avro-encoded through a Schema Registry, and published to Kafka topics. No polling — the database mutations push themselves downstream.

To consume them I built Lightning App, an Electron desktop application that connects to Kafka natively and pipes live weather events into an Angular renderer over IPC. A custom slot-guard service watches the replication slots and drops stale ones before they can fill the disk — a safety net Claude suggested after we hit exactly that problem.

Watching it all: observability

You can't run this many moving parts blind. So: Prometheus scraping eleven targets, Grafana with three hand-built dashboards (Weather API, System Health, Kafka & CDC), and Loki + Promtail aggregating logs from every pod, container, and access log. A small zoo of exporters (Postgres, nginx, blackbox, Podman) feeds the metrics. Watching a request flow from the browser, through Traefik, into the API, out to Postgres, off to Kafka, and light up a Grafana panel in real time never got old.

A data science stack, for good measure

Because why not: Apache Airflow for DAG-based pipelines, Jupyter Lab loaded with DuckDB, pandas, and pyarrow, and MinIO as S3-compatible object storage — all behind the same Kratos SSO as everything else.

Holding it together: Podman, Kubernetes, Traefik

None of this runs on my machine as loose processes. Everything is containerized with Podman (rootless, daemonless) and orchestrated with standard Kubernetes manifests via podman play kube, split into separate pods you can bring up independently. Traefik sits in front doing SSL termination and path-based routing, redirecting HTTP to HTTPS and gluing every service under one hostname.

Testing and CI/CD

It's a learning project, but it's not untested. Playwright drives three end-to-end suites against the running pods, Vitest and xUnit cover units, and GitHub Actions runs lint, builds, E2E smoke and full suites, plus a Claude Code review on PRs. CodeQL, OWASP Dependency-Check, and Dependabot round out the security scanning.

The twist: attacking my own project

Here's where it got genuinely educational. This system is insecure by design — hardcoded secrets, an unauthenticated admin API, a committed TLS key, no Kubernetes Secrets. Rather than pretend otherwise, I had Claude run a full security audit on it.

The result: 63 vulnerabilities across 45 files — 42 confirmed exploitable, 9 partial, and, importantly, 7 flagged findings that turned out to be false positives once we checked them against the actual code. Then we went further and wrote 14 working exploit proof-of-concepts: session forgery from the committed HMAC secret, an admin-API identity takeover, Jupyter RCE, a Podman socket container escape, CDC data exfiltration, and more. Watching an AI find a vulnerability and then verify whether it was actually reachable — throwing out the ones that weren't — was maybe the most valuable part of the entire three weeks.

(To be very clear: this whole thing is a learning sandbox. It is not meant to run anywhere near the public internet, and the repo says so loudly.)

What I actually learned

The tech stack is a mile long, but that's not the point. The point is what it felt like to build at this pace. A few things stuck:

What started as "hello world" turned into the most complete full-stack system I've ever assembled, and I built it by talking. If you're curious what that looks like end to end, the whole journey — every one of those 188 steps — is documented in the repo.


AI icon by Flaticon.

#ai #claude #fullstack #nx #weather