Back to portfolio
ProjectLive

Hearth

The user manual your house never came with. Hearth turns photos, documents, and public records into the maintenance plan, inventory record, and historical archive your home has never had.

ToddTech LLC · System architecture
Hearth
The user manual your house never came with. A phone photo becomes a record, public data becomes a finding, and both become a maintenance plan.
01Smart Uploader — the paper trail, inTap + Add, point the phone at a nameplate or a receipt. Every action is RLS-scoped, and nothing in the request path bypasses the owner check.
Capture
Hash, downscale, dedupe
SHA-256 before upload, so a byte-identical re-shoot never makes a row. Receipts up to 5 pages.
↓
Classify + extract
Vision model, swappable
Nameplate, equipment photo, or not useful. The model is an env var. The output has to validate against a Zod schema or it is rejected.
↓
Match
Already have one?
Alias matcher (fridge → refrigerator, never washer → dishwasher). Receipts match by serial to the item they service.
↓
Decode, in parallel
Reasoning model, serials only
Fast models invented a date rule per call. The decoder cites the rule, applies it, and persists only at high confidence.
↓
Record
Inventory + document
User confirms, row lands. A registration card with an expiry seeds a renewal task on the spot, with no model involved.
02Habitat modules — what the owner didn't know to askPluggable: one contract, one orchestrator. Each check narrates its own activity log in plain English, and the methodology is public at /how-it-works.
EPA Superfund proximityEnvirofacts SEMS
Every NPL site in the state, haversine distance to each, three rings (½ / 2 / 5 mi) crossed with NPL status. A canonical contaminants table adds exposure pathways. A solvent two miles out escalates for a house on a well, and vapor intrusion needs a basement inside the half-mile.
One model call writes a four-sentence portfolio summary. Hard rule in the prompt: never assert the property is or isn't contaminated. If the call fails, the finding ships without it.
State cache · 7 d30 s → 8 s warmCIC contact scraped
Water quality awarenessSDWIS · CCR
Address → utility polygon → PWSID, with a 500 m fallback for EPA's map gaps and the owner's own answer as the primary signal. After that, violations and lead/copper samples. Any detected lead is caution, because the action level is a regulatory line, not a health one.
Upload the utility's annual report and a vision model extracts exactly five sections. The schema has no field for the marketing. One extraction serves every household on that system, and years become trend lines.
Per-utility cacheFilter matrixPublic SEO pages
FEMA flood zonesNFHL
Zone + subtype at the point. Retries, a 180-day cache, then stale-but-labeled data before it ever says failed. No coverage reads neutral, never all-clear.
EPA radon zoneCounty map
County-level predicted radon, compiled from EPA's dataset at build time. The template for how cheap a new module should be.
The model never gets the last word.
Every AI output is bound to a Zod schema or discarded. Reasoning models only where determinism pays for itself. Regeneration is lazy: on click or a key-field edit, never on every write. Every call soft-fails, so the record ships even when the paragraph does not.
03 Maintenance synthesis, durable workflow
Findings become a plan
In: the item's researched manual, the house's habitat findings, its receipts, its install date. Out: 4 to 8 recurring tasks, each with frozen reasoning (source, cadence basis, anchor, modifiers). A durable workflow runs the 50-second reasoning call, so the user can close the tab.
Habitat modulates cadence: hard water with iron shortens the anode-rod interval, and the task says why, citing the finding. Renewals bypass the model: an expiry date writes the task directly, and a rebuild supersedes only synthesized rows, so it survives.
04 Data layer
One schema, RLS everywhere
Supabase, a dedicated hearth schema, every table scoped to its owner. The RLS-bypassing service role is confined to background jobs. Shared caches mean the second neighbor on a water system never re-fetches EPA. Realtime dashboard with a polling fallback.
05 What it actually found
The manual the house never had
A dryer vent nobody had cleaned in 40 years, nearly closed. Washer and garbage-disposal upkeep no one had ever mentioned. And the question it asks first: where are your water and gas shutoffs? Answered once, as a phone video, filed where anyone in an emergency could find it.
Stack: TypeScript · Next.js App Router · Supabase (Postgres, RLS, Storage, Realtime) · Vercel AI SDK + Gateway (Anthropic, OpenAI, xAI) · Vercel Workflow · Mapbox · EPA + FEMA data · ~320 issues merged since May 2026, solo
toddtech.llc/portfolio/hearth · Kalamazoo, MI
Live and open to the public

Public water quality findings

Hearth publishes a water quality profile for each city it serves, and these two are open to anyone, no account needed. Every number on them comes from EPA's Safe Drinking Water records and the utility's own published annual water quality report. Hearth reads those records the same way it does for the households it watches over, and shows its work. The tone is awareness, not alarm: it is the same report the utility already mails out, made easier to understand.

Sources on every page: EPA's Safe Drinking Water Information System for violations and lead and copper sampling, and each utility's published annual water quality report, the Consumer Confidence Report it sends to customers, for everything detected in the supply. Hearth adds the plain-English reading and nothing else.

Tech Stack

Next.js 15+React 19TypeScriptTurbopackSupabasePostgreSQLVercel Workflow SDKVercel AI SDKVercel AI GatewayxAI / Grok 4.2Anthropic / Claude HaikuPerplexity / SonarMapboxArcGIS RESTTailwind CSS
Inside the app

Screenshot gallery

Dashboard

The home view: an AI-generated architectural sketch of the property, the facts pulled from public records, an emergency video reference panel, and a live preview of the habitat findings. Every tile is real data, updating as background workflows finish.

Onboarding discovery

The first run narrates its own work as it happens: public records first, then radon, Superfund proximity, flood zones, and water quality. Showing the work builds more trust than a spinner ever could.

Smart Uploader

A photo of an appliance nameplate becomes a structured inventory record, with a review step between the extraction and the save. The same uploader takes multi-page service receipts.

Inventory detail

Each appliance gets its own page: the extracted facts, an on-demand “Research this model” panel that streams a grounded summary of service life and maintenance, and a manufactured-date tile decoded from the serial number.

Habitat: Superfund proximity

The finding for a nearby Superfund site: distance tier, NPL status, and EPA's Community Involvement Coordinator for the site. Every contaminant listed carries a plain-language description of what it actually is.

Habitat: Water quality awareness

The compliance picture for the home's own water system: violation history, the contaminants detected against their federal action levels, and the actions Hearth recommends for this specific source.

Habitat: Remediation matrix

The water module's real output, built from the home's own 2024 Consumer Confidence Report: every contaminant actually detected in the supply, mapped against six filter technologies, detected rows highlighted. Hearth reads that grid into one specific recommendation, with certifications named and install and annual costs attached, so it points at a product the homeowner can buy rather than a generic “consider a filter.”

Maintenance panel

A real maintenance plan for one appliance, tiered by urgency and scheduled by cadence: interval, seasonal, one-time, per-use. Every task carries its own reasoning.

Task detail with cross-module reasoning

Every task is one tap from a “why this task” card. Here a dishwasher-cleaning cadence tightened from the usual one to two months down to monthly, because the water-quality module found hard water in the county, and the card says exactly that.

How it was built

Selected Design Decisions

JSONB columns earn promotion to real columns only when a query pattern demands it. The inventory and document tables both carry a `metadata` JSONB column for subtype-specific fields that don't need cross-row queries yet, things like vehicle VINs and plate states, pet microchip numbers, or a receipt's vendor and line items. When a query pattern finally needs one of those fields as a real column, say, aggregating values for an insurance valuation, that shape migrates out of JSONB into a column of its own. Until then, JSONB keeps the schema small and the path to a new feature short.

Workflow errors are sorted into terminal vs. retryable. Hearth's durable jobs run on Vercel Workflows, where a naive policy retries every failure as if it were transient. Hearth instead marks its orchestrator-internal errors as non-retryable: constraint violations, missing entities, a failed write. Those surface a deterministic bug in about two seconds rather than grinding through roughly thirty seconds of pointless retries, while genuinely transient errors like a flaky EPA call or a gateway hiccup still retry. That one distinction turns the workflow layer into a fast feedback loop during development instead of a latency tax.

Under the Hood

AI Integrations

Vision extraction pipeline

Anthropic / Claude Haiku

Reads appliance nameplates, multi-page service receipts, and identifying documents. Haiku for fast, cheap structured extraction; every output is bound by a Zod schema, with unit tests pinning the no-prompt-leak contract.

Research this model

Perplexity / Sonar

A web-grounded summary of an appliance's service life, maintenance needs, and known issues, routed through the Vercel AI Gateway. It streams section by section, so there is real content on screen within seconds.

Serial-number decode

Reasoning model (env-driven)

Decodes a manufacture date from the serial number when no install date is on file. The model has to name its rule, apply it, and return null rather than guess; only high-confidence decodes persist.

Maintenance synthesis workflow

Vercel Workflow SDK

A durable background job turns the appliance's research summary, the home's habitat findings, and its receipts into a scheduled plan. Each task is stored with its own cadence, anchor, modifiers, and reasoning.

Habitat data integration

Mapbox + EPA + FEMA

Mapbox address autofill feeds coordinates into EPA Envirofacts, FEMA NFHL, EPA's water-utility layer, and SDWIS. Shared per-state caches spread the cost of slow federal APIs across everyone in the same area.

Activity logs and methodology transparency

In-house

Every habitat finding emits a step-by-step log of what was queried, what came back, and how severity was decided. The classification rules themselves are published on an in-app methodology page.

Want to talk about this work?

I'm available for contract and full-time roles, and happy to walk through any of these systems in detail.

Get in touch