Inspiration
I kept coming back to one problem: businesses lose the ability to personally check every invoice the moment they grow past one location. A single shop owner would notice a wrong bill. A business running locations across different locations and beyond can't rely on that instinct anymore and that's exactly when duplicate or mismatched payments slip through. Most AP tools at this price point (like BILL) skip purchase order matching entirely, so I built the thing they don't.
What it does
blockstrip. checks every invoice against its purchase order before anyone pays it — vendor, amount (1% tolerance), and a duplicate check against recent submissions. Clean matches can auto-approve; anything uncertain routes to a manager to approve or reject, with a reason recorded either way. It handles bulk CSV/Excel uploads of up to 200+ invoices at once, and it's location-aware: clerks belong to one location, managers can oversee several.
Why Aurora DSQL runs the whole thing
This isn't a database that just stores rows — nearly every feature depends on something specific Aurora DSQL guarantees:
- PO matching relies on consistent reads: the purchase order lookup is never stale, so a match decision is always made against the real, current state.
- Bulk CSV/Excel import can write up to 200 invoices in rapid succession, some touching the same purchase order — this is where Aurora DSQL's optimistic concurrency control (OCC) actually gets exercised, not just included for show. Conflicts are caught, logged, and automatically retried with exponential backoff.
- The approval workflow updates an invoice's status and its matched PO's remaining balance in a single atomic transaction — ACID guarantees mean there's never a state where one updates without the other.
- Duplicate detection depends on strong consistency: two near-simultaneous submissions can never both miss seeing each other.
- Authentication runs entirely through Vercel's OIDC federation into an AWS IAM role — no access key, no secret, ever stored or transmitted.
- A live, on-demand concurrency demo in the app's Settings panel fires several simultaneous writes against the same purchase order and shows, in real time, whether Aurora DSQL detected and resolved a conflict — proof you can click yourself, not a claim in a README.
It currently runs single-region (us-east-1), which gives 99.99% availability with automatic AZ-level failure recovery — the right scale for where this is today. Because every write is already UUID-based and routed through the same OCC-protected retry path, moving to a multi-region Aurora DSQL cluster later is a configuration change, not a rewrite.
How I built it
Next.js, React, and TypeScript on Vercel, backed by Amazon Aurora DSQL — serverless, distributed, Postgres-compatible. Auth runs through Vercel's OIDC federation straight to an AWS IAM role, so there's no hardcoded credential anywhere. Every write is wrapped in retry logic that catches Aurora DSQL's OCC conflict codes and retries with backoff — which matters directly for bulk imports, where many rows can hit the same purchase order at once. Approving an invoice and updating its PO's remaining balance happen in one atomic transaction.
Challenges I ran into
Aurora DSQL doesn't support auto-incrementing IDs, which broke every insert I'd written — fixed by generating UUIDs in code, which fits a distributed database better anyway. I also hit a real bug where invoices matched incorrectly because location_id was silently null on purchase orders created before location-scoping was finished — a good lesson that schema completeness matters as much as logic. And since Vercel's OIDC auth only works inside Vercel's own runtime, local development needed its own clearly separate connection path.
Accomplishments that I'm proud of
Zero hardcoded credentials anywhere, end to end. A bulk import pipeline that runs every row through the exact same matching logic as a single submission — no duplicated code, no row ever blocking the rest of the batch. And a live, on-demand concurrency demo that fires simultaneous writes at the same purchase order and shows Aurora DSQL's OCC handling in real time — proof, not a claim.
What I learned
That Aurora DSQL's design — no auto-increment, IAM-only auth, OCC instead of locking — shapes real decisions throughout an app, not just the connection code. I also corrected a few early claims about multi-region capabilities I wasn't actually using; the project is stronger for being precise about what's real.
What's next for blockstrip.
3-way matching against delivery confirmation, not just the PO. OCR extraction from PDF/email invoices. And a multi-region Aurora DSQL cluster when traffic warrants it — the UUID-based, concurrency-safe design already fits that move without a rewrite.
Built With
- amazon-web-services
- auroradsql
- next.js
- v0

Log in or sign up for Devpost to join the conversation.