← All work

Case study

ClaimHawk

AI-powered class-action claim filing — Chrome extension + heterogeneous scraper + Stripe billing, end-to-end. Shipped solo in roughly six months.

claimhawk.ai →·Live · Stripe live mode · Chrome Web Store review

The problem

Tens of billions of dollars in class-action settlement funds go unclaimed every year. The filing process is opaque and fragmented: every settlement has its own admin portal, its own quirky form, its own deadline. Consumers eligible across a dozen settlements can't keep up, and the law firms running the settlements have no incentive to make filing easier.

What I built

  • Scraper — Python + httpx, five adapters monitoring FTC refunds, CFPB enforcement, ClassActionRebates, OpenClassActions, and ClassAction.org. Admin-site enrichment, LLM-driven field extraction with gpt-4o-mini, daily schedule on Fly.io with an auto-stop machine.
  • API — Hono on Fly.io. AES-256-GCM PII encryption at rest with push-button key rotation via admin endpoint. Stripe live-mode billing with tiered plans, referral tracking, and webhook handling.
  • Web app — Next.js 14, Supabase Auth (magic link + Google OAuth), Tailwind, Sentry, PostHog, Crisp live chat. Eligibility quiz, semantic-ranked settlement matching, four-step claim wizard, ID + receipt scanning via Google Document AI, payout tracker.
  • Chrome extension — MV3, plain JS, no build step. Autofills class-action claim forms directly on settlement-administrator sites. Handles MUI, Angular, ngx-mask, cross-origin iframe widgets. Per-field undo. Submit-event detection for confirmation capture.
  • Proof-of-Purchase Locker — Google Document AI for receipt parsing. Retroactive matching: when a new settlement scrape hits, users get notified if prior receipts match.

Hard problems I solved

Cross-origin iframe injection for payment widgets

Many class-action admins embed cross-origin payment-choice widgets (e.g. Digital Disbursements) inside their claim forms. Chrome's same-origin policy blocks the content script from injecting into those frames. I built a server-curated widget_hosts registry plus extension telemetry on encountered iframes, then issued matching content scripts via chrome.scripting.registerContentScripts dynamically. Same-origin iframes pierce automatically via all_frames.

Form classifier across modern JS frameworks

Angular admin sites frequently have no id or name on inputs — only formcontrolname and ng-reflect-name. MUI sites hide labels inside ancestor FormControl nodes, not sibling <label> elements. The classifier reads data-test, data-testid, walks ancestors for MUI labels, and falls back to Angular binding attributes. ngx-mask support required switching from a React setter pattern to execCommand('insertText') to trigger the directive's input handlers.

Heterogeneous settlement scraping with LLM extraction

Five sources, each with its own page structure — some PDFs, some listing cards that link out to admin sites. The scraper pulls candidate URLs per-adapter, then fans out to admin-site enrichment via a generic extractor that uses the LLM to pull structured fields (deadline, payout, filing URL, mailing address, proof requirements) from raw HTML. Card-deterministic values win over LLM values wherever both are present. Prompt explicitly forbids PDFs in the filing URL field — a trap that kept breaking the Launch-claim CTA until regression tests caught it.

PII encryption key rotation as a single admin endpoint

Every PII column is encrypted at rest with AES-256-GCM using a derived key. Rotation used to be a two-hour ad-hoc job; the new POST /api/admin/pii-rotate endpoint does dual-key decryption, re-encryption, verification, and cleanup push-button in about ten minutes.

What a consulting engagement looks like

If you're building a compliance-heavy AI consumer product, or a Chrome extension that automates form-filling for a regulated workflow, ClaimHawk is the closest prior art. Most of the hard parts — cross-origin extension plumbing, PII encryption with rotation, LLM-driven extraction at acceptable cost, Stripe live with per-tier gates, Supabase RLS done right — are patterns I'll reuse or simplify for your build.

Start with a discovery sprint →