Inspiration Every scholarship and college application asks the same question: prove it. But proof of volunteer work, club leadership, and part-time jobs lives nowhere - a certificate photo buried in Camera Roll, a forwarded confirmation email, a screenshot of a text from a coordinator. By application season half of it is missing or misremembered, and there's no way for anyone reading the application to actually trust the numbers. We wanted evidence to become a record automatically, as it happens, with a trail that shows it's real.
What it does Impact Receipts turns scattered evidence into a verified, exportable record. Drop in a photo of a certificate, a sign-in sheet, or a pasted email, and Claude extracts a structured record: organization, activity, dates, hours, skills, and the literal excerpt that backs the claim. A deterministic engine then groups evidence about the same commitment and assigns a verification tier - Corroborated when two or more sources agree on hours, Self-reported when there's only one, and Needs review when sources disagree, with a simple UI to resolve the conflict by hand. Totals are always computed in plain code from the verified records, never guessed by the model. The finished record exports as a print-ready one-pager or shares as a read-only link, no login required.
How we built it Next.js 15 App Router with TypeScript and Tailwind, deployed on Vercel. Claude does the extraction work through the Anthropic SDK's tool-use, forced into schema-valid JSON with a Zod-validated retry loop so a malformed response never reaches the database. Everything after extraction is deliberately kept out of the LLM's hands: a pure, unit-testable dedup engine normalizes and compares evidence with Jaccard and Levenshtein similarity, then unions matching records with a union-find structure so grouping doesn't depend on upload order. Neon Postgres and Drizzle handle persistence, and Vercel Blob stores the evidence images. There's no auth - a workspace is a long unguessable id in the URL, with a separate share id for the public one-pager.
Challenges we ran into The hardest problem wasn't extraction, it was keeping dedup honest as evidence keeps arriving. Every new upload has to re-run grouping across the whole workspace, but a student may have already resolved a conflict or overridden an hours total by hand - naive re-grouping would silently throw that work away. We ended up matching evidence sets across re-groupings so manual resolutions carry forward instead of resetting. Org name matching was its own fight: a formal certificate says "Riverside Community Food Bank" and a text from the coordinator says "the food bank," and those need to land in the same bucket without over-merging unrelated orgs that happen to share a word.
Accomplishments that we're proud of The verification model actually works end to end - we fed it a certificate and a sign-in sheet for the same volunteer stint with different hour counts, and it correctly flagged them as Needs review instead of averaging or picking one, then let the resolution carry through cleanly to the exported one-pager. Keeping the LLM strictly in the extraction step, with every downstream number computed by plain deterministic code, means the totals a scholarship reader sees are never a hallucination - they're auditable back to a literal excerpt from real evidence.
What we learned Where you draw the line between "the model decides" and "code decides" matters more than how good the model is. Extraction is exactly the kind of fuzzy, unstructured task Claude is good at; verification, deduplication, and arithmetic are exactly the kind of task you want out of its hands entirely. Building the dedup engine as pure functions with zero DB or LLM imports made it trivial to unit test in isolation and to reason about correctness independent of anything the model produced.
What's next for Impact Receipts PDF parsing, so a scanned certificate or a downloaded confirmation letter doesn't need to be screenshotted first. Direct verification with issuing organizations for a stronger trust tier above Corroborated. Team accounts so a club advisor or coach can co-sign entries instead of a student self-reporting everything. And richer one-pager templates suited to different application formats (Common App activities list, scholarship-specific rubrics).
Built With
- claude
- drizzle
- neonpostgress
- next.js
- tailwindcss
- typescript
- vercel
Log in or sign up for Devpost to join the conversation.