Pro eMarketing LLC
Case study — Live — vaultxl.com

VaultXL

Estate transition and value-recovery marketplace: photograph an estate, and software identifies, prices, lists, and sells it across three marketplaces.

Role
Pro eMarketing — design, build, ops
Timeline
2026 · ongoing — {{TODO: confirm build start month}}
Stack
Next.js 16React 19TypeScriptSupabaseNextAuth 5Stripe + ConnectClaude APIGoogle VisionUpstash RedisResend
01Problem

When a family downsizes a parent's home or settles an estate, they inherit a house full of objects and no good options. Estate-sale companies take heavy commissions and dump what doesn't move in a weekend. Junk haulers destroy value indiscriminately. Selling item-by-item yourself means months of research, photography, and marketplace admin most families can't take on while grieving.

VaultXL is a premium estate-transition service for the Carolinas with a software thesis: if identifying, valuing, listing, and selling an item can be compressed from hours of manual work to minutes of review, one operator can recover value at a scale that used to take a crew — and the same software becomes a product other liquidators subscribe to.

02What it does

The core of VaultXL is an item pipeline: an estate goes in one end as photographs and comes out the other as settled, itemized proceeds. Every stage below is shipped code.

  1. Intake & booking

    Public booking, assessment, and instant-offer flows feed the pipeline. Checkout runs through Stripe with every price re-resolved server-side against a catalog — a client-tampered price is rejected, not trusted. Recurring storage tiers run as Stripe subscriptions.

    Stripe Checkout · server-side price catalog · one-time + subscription modes

  2. Photo capture

    Operators and clients upload item photos from a phone. Files are validated by magic bytes (not the claimed content type), size-capped, renamed to UUIDs, and stored in Supabase Storage. HEIC from iPhones converts client-side before upload.

    magic-byte validation · UUID filenames · HEIC→JPEG conversion

  3. AI photo identification

    The most mature piece of the product. Google Vision runs reverse-image web detection across every photo of an item; the merged evidence is handed to Claude, which returns the item name, brand, exact model or style code, colorway, release year, condition, materials, and per-marketplace category mappings. Low-confidence results escalate up a ladder: a deeper model retry, then a Google Lens reverse-image pass, and if it's still unsure it asks the operator for a close-up rather than guessing.

    Google Vision web detection → Claude structured extraction → confidence-escalation ladder (deep model → Google Lens → needs_closeup)

  4. Research & valuation

    A dedicated research flow prices items against reality, not vibes: eBay sold-comps retrieval, market-valuation reconciliation, and a structured market analysis per item — suggested price, demand level, sell-through estimate, competition, and target buyer.

    eBay sold comps · valuation reconciliation · per-item market analysis

  5. Listing generation

    Claude writes the SEO listing title and structured description in the same pass that identifies the item. Before anything publishes, per-channel readiness (missing required fields) and eligibility (prohibited-item rules) are recomputed server-side and fail closed — a listing that isn't ready for a channel can't be pushed to it.

    80-char SEO title formula · server-side readiness + eligibility gates

  6. Multi-channel publishing

    One item, one click, three marketplaces: eBay via the Sell Inventory API with auto-provisioned business policies, Shopify via OAuth with HMAC-verified webhooks, and Etsy via OAuth with PKCE. Marketplace tokens are AES-256-GCM encrypted at rest and never touch a URL.

    eBay + Shopify + Etsy OAuth · encrypted token vault · per-channel category mapping

  7. Sales sync & auto-delist

    When an item sells on any channel, the sync engine marks it sold and delists it everywhere else — the classic multi-channel nightmare (selling the same lamp twice) is handled by orchestration, not operator memory.

    cross-channel sale events · automatic delisting · orders hub

  8. Settlements, payouts & tax docs

    Consignors get itemized settlement statements from a single money-math source of truth; the same numbers drive the client portal's financials, the operator's accounting view, and the PDFs. Eleven generated document types cover consignment agreements through donation receipts, with W-9 collection and 1099 prep built in. Stripe Connect handles marketplace payouts.

    single settlement-math module · 11 PDF document types · Stripe Connect Express

Asset pending

{{TODO: Operator dashboard command-center screenshot (money/pipeline/activity zones)}}

Asset pending

{{TODO: AI analyze flow: item photos → identification result with confidence + market analysis}}

Asset pending

{{TODO: Listings screen showing per-channel readiness/eligibility for one item}}

Asset pending

{{TODO: Sample settlement statement PDF (redacted)}}

03Technical decisions

Object-level authorization is a hard gate, not a convention

Every server component and API route goes through one data-access layer that enforces who can touch which org's rows. The Next.js middleware is explicitly documented as an optimistic cookie check only — the real security boundary lives in the DAL, which fails closed if the org claim is missing. Three surfaces (public site, client portal, operator dashboard) share one auth spine.

Tenant isolation by construction

The app talks to Postgres through a wrapper that automatically scopes every read to the caller's org and stamps every write with it — a client-supplied org ID can never win. The fully-generic typed version of this wrapper blew past an 8GB TypeScript heap compiling deep conditional types, so the types were deliberately loosened: a real production constraint shaping architecture, documented in the code.

Untrusted webhooks are triggers, not truth

eBay has no Stripe-grade webhook signature scheme, so inbound eBay webhooks are treated as untrusted pings: the handler re-fetches real order data over an authenticated API call instead of trusting the payload, and a shared-secret header stops unauthenticated poll triggering. Shopify webhooks get full HMAC verification against the raw body with timing-safe comparison.

Money math has exactly one home

Gross, commission, and net are computed in a single settlement-math module that the orders hub, the sync cache, and the settlement PDFs all call — none of them can drift. The file is marked money-gated in source: it doesn't change without an independent review pass. That rule exists because of the bugs below.

04What verification caught

VaultXL is where the verification discipline documented on the How I Build page earned its keep. Phase-gated audits against the real codebase — recorded in a dated audits/ directory in the repo — caught bugs a green build and a 200 response would have shipped:

  • Caught:A 100× fee double-conversion: the project form pre-multiplied dollars to cents, the API multiplied again — a $1,000 fee stored as $100,000
  • Caught:Broken inventory editing: value updates skipped the cents conversion on PATCH that POST applied, silently corrupting item values on every edit
  • Caught:Unauthenticated webhook triggers: eBay's ping endpoint accepted any POST until a shared-secret header closed it
  • Caught:Client-side price tampering on checkout: booking prices are now re-resolved against a server-side catalog, tampered payloads rejected
  • Caught:Predictable initial passwords from Math.random(), replaced with crypto.randomBytes
05Traction
83
API routes in production
69
pages across three surfaces
3
marketplace integrations (eBay, Shopify, Etsy)
11
generated PDF document types
~66K
lines of TypeScript, solo-written
{{TODO: items processed to date}}
items through the pipeline
{{TODO: GMV / value recovered}}
value recovered for families
{{TODO: avg minutes per item listed}}
operator time per item
06Status & next
  • Multi-tenant SaaS layer: org-scoped billing, plans, and AI usage caps are built; packaging the operator toolkit for other estate liquidators is the next revenue line
  • Additional channels beyond eBay/Shopify/Etsy as sales data justifies them
  • {{TODO: confirm current operational focus — first paid estates, Mercury account, sales-tax cycle}}