
TariffsGPT helps importers understand duties, rulings, and refunds — and it's the most production-hardened product in the family. Three parts are worth studying: the command palette (the search experience), the Stripe upgrade (real commerce, done carefully), and the 7501 reader (a PDF that turns into money owed).
A command palette that always has an answer
The palette is the primary way to move through the app. Short queries show navigation and actions, filtered as you type; static matches render instantly while data results stream in underneath; and at the foot there's always an escape hatch — "Ask the assistant: <query>" — so the search never dead-ends:
// src/components/CommandPalette.tsx
// • empty / short query → NAVIGATE (routes) + ACTIONS, filtered as you type
// • always, at the foot → "Ask the assistant: <query>" → /chat?q=<query>
// static matches render instantly; data results stream in underneath.
type Result =
| { id: string; type: "nav"; label: string; href: string }
| { id: string; type: "action"; label: string; run: () => void }
| { id: string; type: "ask"; query: string };Actions live right next to navigation — "Check refund eligibility," "Toggle light / dark mode," "New chat" — so the palette is a command surface, not just a jump list. The instant-static / streaming-data split is what makes it feel fast even when the data isn't back yet.
Stripe that fails closed
TariffsGPT has a real Pro upgrade. The elegant part is that the same endpoint runs live or mock depending on whether a Stripe key is present — so the entire gated experience is testable locally with zero config — but the mock path refuses to run in production, so a missing key is a locked door, not a free-Pro button:
// src/app/api/stripe/checkout/route.ts
const stripe = getStripe();
if (!stripe) {
// Mock is a DEV convenience. It must NEVER run in production — there, a
// missing key is a misconfiguration, not a free-Pro button. Fail closed.
if (process.env.NODE_ENV === "production") {
return Response.json(
{ error: "Upgrades are temporarily unavailable." },
{ status: 503 }
);
}
await setPlan(user.id, "paid");
return Response.json({ upgraded: true, mock: true });
}
// LIVE: create a Checkout Session, reuse the saved customer, return { url }."Swapping in the real key needs no code change" is the design goal, and the
NODE_ENV guard is the discipline that makes shipping it safe.
A PDF that computes your refund
The standout document feature: upload a CBP 7501 entry summary and get money back. The route extracts the PDF's AcroForm fields, normalizes the entry, resolves each Chapter-99 overlay code against a tariff table, and computes the recoverable IEEPA pool from the entered value × each refundable line's rate:
// src/app/api/parse-7501/route.ts
import { PDFDocument, PDFTextField } from "pdf-lib";
import { parse7501Fields, type ParsedLine } from "@/lib/parse-7501";
/**
* POST /api/parse-7501 (multipart, field "file": a CBP 7501 PDF)
* Extracts AcroForm fields, resolves each Chapter-99 overlay against
* tariff_codes (refundable? + rate), and computes the recoverable IEEPA pool.
* Only fillable AcroForm 7501s are supported — scanned/flattened PDFs are
* rejected with a clear message (no OCR yet).
*/Reading the fillable-only limitation and stating it plainly to the user is the mark of a shipped feature — it knows exactly what it can and can't do, and says so instead of failing mysteriously on a scanned form.
Why it matters
TariffsGPT is what the family's patterns look like once they're hardened for production: search that always resolves, commerce that fails closed, and a document pipeline honest about its limits. It's the same DNA as the other projects — modes, panels, PDFs — carried the last mile to "money changes hands."
Brendan Stanton
Founder, NYSgpt
Read more

PolicyGPT — reading legislation like a first-class document
The NYSgpt flagship pairs a resilient, resizable PDF reader for live bill text with recharts sparklines and a chat that knows the document — a template for putting a real PDF and a GPT in the same view.

InsuranceGPT — commerce inside the conversation
The family's only buy-in-chat experience: quote results render as ranked cards in the message stream, and a checkout drawer takes you from answer to purchase without leaving the thread.
ScienceGPT — a domain-agnostic search engine wearing a physics costume
Built over the Nuclear Science References database, ScienceGPT's real contribution is a reusable search stack: multiple query modes, a typed combobox bound to a distinct-values table, and record cards that could front any structured corpus.