Track
General Track
Inspiration
A volunteer handoff can leave the next shift with two spreadsheets, renamed columns and no clear explanation of what changed. A quick merge can look tidy while hiding repeated IDs, missing values and the comparison rules. ChangeReceipt is built around a smaller, useful outcome: a reviewable record of the differences, with the original evidence still attached.
What it does
ChangeReceipt compares two UTF-8 CSV snapshots entirely in the browser. You choose each file's identifier column, map the fields that matter, inspect added, removed, changed and unchanged records, then download a full JSON receipt or a convenient CSV change log.
Uncertainty is part of the result. Duplicate identifiers stay together as an unresolved group; empty identifiers are never matched. Leading zeros, letter case, whitespace, quoted line breaks and the distinction between missing and empty cells remain explicit. Unmapped columns stay in the receipt, outside the chosen comparison scope.
The demo follows synthetic community supplies through renamed headers, a count change, a location change, duplicate extension-reel IDs and missing identifiers. It ends with a downloaded receipt and a recoverable bad import.
How it was built
React and TypeScript provide a three-step source → mapping → review workflow. Papa Parse handles CSV records, with additional strict structure, UTF-8 and input-bound checks. The deterministic comparison core keeps source records separate from matching decisions. Web Crypto SHA-256 fingerprints identify imported bytes.
The JSON receipt includes original bytes, decoded source text, parsed records, mappings, rules, warnings and all results. An optional local Node.js verifier re-imports the saved evidence and recomputes the comparison using the same core. The compiled release runs through a dependency-free, loopback-only Node server; a source checkout uses npm and Vite to build.
AI tools assisted implementation, test development, review and presentation drafting. The application itself does not use AI inference or an external API. The video shows the actual compiled application with synthetic fixtures. Presentation captions are editorial annotations, not additional product features.
Challenges
The difficult part was refusing to manufacture certainty. Matching the first occurrence of a repeated identifier would create a plausible but unsupported result. Missing cells also cannot be silently treated as empty strings or zero. These cases drove the comparison model, warnings and receipt format.
Another important edge case was interrupted replacement: a malformed or canceled import must not erase the last good source or leave a stale result. The current build retains that evidence and requires a fresh mapping before comparing again.
Accomplishments
The full import → map → inspect → export loop works without an account, remote processing or a backend. Reviewed source has passed 187 unit/component cases, 44 verifier cases, two launcher test groups, and 20 Chromium browser scenarios in each of development and production-launcher modes. The demo capture separately verifies source-byte preservation and recomputes its downloaded receipt.
What was learned
A useful comparison needs to explain its scope and its unknowns, not just display a count. Making those boundaries visible improves both the interface and the evidence model.
What's next
Test the handoff workflow with volunteer coordinators, assess which explanations they actually use, and prioritize a saved-receipt inspector if that feedback supports it. Any future reconciliation suggestions should preserve the original evidence and require explicit human choices.
Limits
This is a local prototype, not a physical stocktake or fraud detector. A fingerprint identifies bytes; it does not authenticate a file's author. The receipt is editable, unsigned and not tamperproof. A verifier pass establishes internal consistency only. Sessions exist in memory and disappear on reset, reload or closing the tab; download a receipt to retain the result.
Judge quick start
Open the hosted synthetic demo in your browser; no account or local installation is needed. Click Load synthetic example, then Map columns. Choose Asset ID and Inventory ID, then map Count→Count, Notes→Notes, Item→Description and Location→Storage. Expected result: 2 changed, 1 added, 1 removed, 2 unchanged, 1 ambiguous identifier group and 2 missing-ID records. The comparison correctly remains incomplete. CSV contents are processed in your browser; the hosting provider receives ordinary page and asset request metadata. Hosted demo source.
For the no-install compiled prototype, download and extract v0.1.2, then run node server.mjs with Node.js 22.14+ (or use Start-ChangeReceipt.cmd on Windows). This local release serves only on your own computer; it remains available separately from the hosted demo.
Alternatively, use the source build: Clone the public repository, use Node.js 22.14 or newer, then run npm ci, npm run build, and npm start. Open http://127.0.0.1:4173/ and click Load synthetic example. Choose Asset ID and Inventory ID. Map Count→Count, Notes→Notes, Item→Description and Location→Storage. Expected result: 2 changed, 1 added, 1 removed, 2 unchanged, 1 ambiguous identifier group and 2 missing-ID records. The comparison correctly remains incomplete.
Log in or sign up for Devpost to join the conversation.