Skip to content

Projects

Split into two. What I build at work, and what I build on my own.

Professional Work

Production systems I built at work. Described without internal names or proprietary detail.

production system
Data Platform EngineeringProfessionallive

Metadata Reconciliation System

I noticed this problem months before I solved it properly. Schema deployments were silently stripping the descriptions, tags, and contacts attached to Snowflake objects, because recreating an object discards everything attached to it. My first fix captured that metadata before each deployment and reapplied it afterward, covering every level metadata can attach to and ten or more object types, and I wired it into the deployment pipeline across all five environments. It worked, but it was fragile and it lived inside every deployment. In mid April the data governance team reported losing three to four hours of metadata work they would have to redo by hand, so I replaced that approach with declarative reconciliation. Governance metadata is now declared once in version control and restored automatically whenever a deployment removes it. I designed and built it between mid April and the end of August 2026, from the first conversation to production.

  • ›Recovery went from three to four hours of manual rework to seconds, and 20+ schema deployments since go-live have been restored without anyone stepping in
  • ›Manages thousands of metadata rows across Snowflake object types and both standard and custom metadata
  • ›Multi-tenant from the start, so each team onboards itself and manages its own metadata without engineering work
  • ›The governance team works from the Excel spreadsheets they already use, without writing YAML or waiting on an engineer
  • ›Safe to re-run. A failure leaves data as it was instead of corrupting it, so recovery is a replay
  • ›Runs unattended every day and costs very little on days with no work to do
production system
Platform EngineeringProfessionallive

Streamlit Dashboard Platform

Two dashboards other teams rely on came to me after the original developers left, with no handover. I read through both codebases, took ownership, and rebuilt the observability dashboard from a flat structure into a feature based architecture with a shared core. Then I turned that architecture into a template repository other tenant teams can start from, on top of shared Python packages for authentication, cloud access, Snowflake access, and a common Streamlit layer. A team that wants a dashboard writes the dashboard itself, and the cloud infrastructure and deployment pipeline are already set up.

  • ›Inherited two dashboard repositories with no knowledge transfer, read through 300+ files across both, and became the owner and point of contact for the teams that use them
  • ›Rebuilt the observability dashboard from a flat layout into a feature based architecture with a shared core, retired the legacy codebase, and wrote the developer standards and documentation so others on the team can contribute
  • ›Turned that architecture into a template repository for tenant teams. A new dashboard starts with SSO, cloud access, Snowflake access, and the shared UI layer already wired in, with empty feature folders so it stays small
  • ›Built the shared Python packages underneath it, writing the PKCE single sign on package and the Streamlit utilities package and adding cloud and Snowflake connectivity to two existing shared packages. An improvement to any of them reaches the dashboards through a version bump
  • ›Automated the provisioning, so repository setup, per environment secrets and variables, CI/CD, and the GCP infrastructure and deployment target are handled for each tenant team
  • ›Serves 100+ daily users across the platform's data domains, with Streamlit caching across sessions so repeat views do not re-query Snowflake

// also shipped on the job

Product Engineering

Governed Exception Workflows

live

The data governance team's quality scores were full of noise. Rules they already knew were not meaningful, test rules, rules that always warn or always fail. I built the workflow that lets them retire that noise deliberately, as governed records carrying a validity window and a stated reason, so suppressing a rule is an auditable decision rather than a silent deletion.

  • ›Built a governed exception workflow for data quality rules, then reused the same pattern for a second domain
  • ›Every exception is a governed record with a validity window, a stated reason, and full audit fields. Scores recalculate to exclude suppressed rules, and a toggle shows the unfiltered scores
  • ›In use. Users have retired a double digit number of rules that were not actionable, and a partner team bulk loaded tens of thousands of known exceptions at launch
PythonStreamlitSnowflakeSQL

Data Engineering

Data Pipeline Engineering

live

Pipeline and query work across the platform's warehouse layer, from the validation framework underneath a custom pipeline builder to the queries behind the dashboards and the alerting that tells teams when their data is late or wrong.

  • ›Introduced Pydantic into a custom pipeline builder library, took it through design review with my tech lead, and replaced hundreds of lines of hand written validation with models that reject bad configuration before a pipeline runs
  • ›Found that pipeline failure notifications had been silently missing every data source onboarded after a legacy lookup table went stale, so teams might not know their data was broken. Rebuilt the notification queries and checked that the fix added the missing sources without dropping any
  • ›Rewrote 33 queries and 6 dependent views to cover every data domain on the platform, and built three reusable query templates, so onboarding a new domain means filling in a template instead of days of development
  • ›Roughly halved execution time on the busiest queries, cut data scanned from about 50MB to 28MB, and removed disk spill
PythonSnowflakeSQLAirflowPydantic

Personal Work

KriegerDataForge, my personal platform, and the apps I am building on it.

featured payload
Personal Platform EcosystemPersonalin development

KriegerDataForge

A personal platform I build and use for my own apps, across 18 repositories. Building apps is a passion of mine, and I wanted to stop starting each one from scratch. At its center is an OAuth 2.0 and OIDC identity provider that gives the apps single sign on and single logout. Code the apps have in common lives in shared Python and npm packages, Terraform declares the dev and production environments, and a shared CI/CD library builds and deploys every repository the same way. Two apps are being built on it, a nutrition tracker that is deployed and in use and a boutique storefront for my sister that has not launched yet.

  • ›One identity provider and one shared user table give every app single sign on and single logout
  • ›Two separate environments, dev and production, that share no databases, signing keys, or service keys
  • ›Deploys are started by hand and checked against a list of who may deploy, and production also needs a passing run of the full test suite
  • ›The app backends do not implement sign in themselves. They check the identity provider's tokens through the shared SDK

Frontend

Next.jsReactTypeScriptTailwindCSS

Backend

FastAPIPythonSQLModelPostgreSQL

Platform

TerraformGitHub ActionsDockerVercel

// more from this ecosystem

Auth Service

KriegerDataForge

KDF Identity Provider

live · in development

The identity service every app on the platform delegates sign in to, plus the hosted login and consent UI in front of it, so they all share one account. It gives the apps single sign on (SSO) and single logout. Signing in to one app starts a session at the login page, and while that session lasts the other apps sign me in without asking for my password again. Signing out of any app signs me out of every app. Each app still gets its own token, and the other apps refuse it. It implements the authorization code flow with PKCE, rotating refresh tokens, argon2id password hashing, account lockout, signing key rotation, and a login audit log. The UI is a backend for frontend that keeps the service key on the server, so browsers talk to the UI rather than to the identity service directly.

  • ›Single sign on and single logout across the apps, and each app gets its own token that the others refuse
  • ›Authorization code flow with PKCE, rotating refresh tokens, argon2id password hashing, and account lockout
  • ›Apps check tokens locally against its published signing keys, with no call to the identity provider on each request
FastAPIPythonOAuth 2.0 / OIDCJWTargon2idPostgreSQLNext.jsTypeScript

Storefront

KriegerDataForge

Tiffany's Space

pre-launch

A boutique storefront I am building for my sister, where she will sell curated clothing, books, handmade crafts, art, and accessories. Customers will be able to browse and search the catalog, keep a cart saved to their account, and see their past orders. Checkout takes two steps, first reserving the items and then paying. An admin dashboard will let her manage products, variants, images, and orders. The server works out every price, total, and stock count itself rather than trusting the browser. The reservation runs in one database transaction that locks the items it holds, and a repeated request returns the original order instead of creating a second one. Payments will go through Stripe, which is set up on the server and switched off until the shop opens.

  • ›The server works out every price, total, and stock count itself rather than trusting the browser
  • ›Checkout reserves the items in one database transaction that locks them, then takes payment, and a repeated request returns the original order
  • ›An admin dashboard for products, variants, images, and orders
Next.jsReactTypeScriptTailwindCSSFastAPIPostgreSQLSQLModelStripeZod

Nutrition App

KriegerDataForge

Calorie Tracker

live · in development

A simple food and nutrition tracker for casual users and beginners. It covers logging meals, setting daily calorie and macro goals, and looking back at daily calorie totals for the past week or month. Its food database includes about a thousand foods from USDA data, and each food can hold up to 43 nutrition fields. New foods and meals are added through step by step forms. The daily log saves in the background, and the server recomputes daily totals from what was logged, ignoring any totals the browser sends. It was the first app built on the platform, and it is deployed and in use while I keep building it.

  • ›A food database with about a thousand foods from USDA data, plus custom foods and meals added through step by step forms
  • ›Daily totals are recomputed on the server, so totals sent by the browser are ignored
  • ›Next on the roadmap are recipes, a nutrition label scanner, and progress charts
Next.jsReactTypeScriptFastAPIPythonPostgreSQLSQLModel

Python Platform Library

KriegerDataForge

kdf-sdk

in development

The shared Python library every app backend installs, so the code they have in common is written once instead of in each app. At its core it checks the identity provider's tokens against the provider's published signing keys, with no database lookup. It also includes a FastAPI application factory, auth dependencies, ownership checks, pagination, rate limiting, request ids and health checks, SQLModel database setup, blob storage, email, and log injection sanitization. Each backend pins a tagged release, so a new version reaches them one at a time rather than all at once.

  • ›Checks tokens against the identity provider's published signing keys, with no database lookup per request
  • ›A FastAPI foundation with auth, pagination, rate limiting, database setup, storage, and email, so each backend does not write its own
PythonFastAPISQLModelJWTpytestRuffmypy

Python Formatter & Linter

KriegerDataForge

kdf-fmt

in development

A Python formatter and linter built only on the standard library, mainly its ast and tokenize modules, with no runtime dependencies. It formats and checks the platform's Python code to one house style, including sectioned module preambles, aligned assignment runs, Google style docstrings, and wrapping at 120 columns. Each rule either fixes the code, reports an error, or reports a warning, and a project can turn a rule off or change its tier in TOML. It is the style check in CI for the platform's Python repositories, where existing findings are kept in a baseline and only new ones fail the check.

  • ›Stdlib only at runtime, no third party dependencies to audit or pin
  • ›A written spec defines the style, and golden test fixtures pin the output
Pythonasttokenizepytest

Web Application

KriegerDataForge

Video Game Database

planned

A searchable game catalog planned as a future app on the platform, for browsing and filtering titles by genre, platform, and rating. Like the other apps, it will sign in through the identity provider and run its own backend on the shared SDK.

Next.jsReactFastAPIPostgreSQL