At First Mate, I built StampMate — a QR-based loyalty app for small businesses — in two focused working days.
The speed did not come from asking an AI to "build the whole app." It came from reducing ambiguity before writing code, giving agents specific roles, and working in milestones small enough for a human to test. It is the same playbook we used to ship a production app in days with AI coding agents.
Start with the complete user flow
Before choosing the stack, I defined what success looked like:
- An owner registers and creates a loyalty program.
- The business displays a join QR code.
- A customer scans it and receives a digital stamp card — no account required.
- Staff scan the customer's personal QR and add stamps.
- Staff redeem the reward when the card is complete.
- A new card cycle starts automatically.
This became StampMate's core MVP rule. Anything that did not support this flow — payments, POS integrations, digital wallets, SMS verification, advanced analytics, subscriptions — moved to the backlog.
That is the first founder lesson: AI makes it cheap to generate more software, so strict scope becomes even more important.
Create the agent team around project risks
Next, I created six project-specific agents in the repository's ai-agents directory:
- Product Planner: turns requirements into small tickets and acceptance criteria.
- Database Architect: owns models, constraints, indexes, and migrations.
- Auth & Security: checks authorization, data exposure, and business isolation.
- Backend Feature: implements validation, business rules, and server actions.
- Frontend UI: builds simple, mobile-first owner, customer, and staff flows.
- QA / Test: checks the happy path, edge cases, security, and mobile usability.
These were not generic personas. Each Markdown file contained the agent's responsibility, project rules, technical constraints, output format, and definition of done.
The goal was not to have more agents. It was to give each decision the smallest amount of relevant, high-quality context.
Break the project into small milestones
The Product Planner divided the MVP into four phases:
| Phase | Milestones |
|---|---|
| Foundation | Setup, authentication, loyalty program |
| Customer Card | Join QR, digital stamp card |
| Staff Operations | Scanner, add stamp, redeem reward |
| Launch Readiness | Dashboard, security, polish, deployment |
The developer agent never received the task "build StampMate." It only received the next small milestone.
Every milestone followed the same development loop:
Plan → Design Data → Define Checklist → Build Backend → Build Frontend → Test → Review Security and Scope → Clean Up → Commit
This kept changes small, bugs easier to isolate, and human testing practical. It also meant I never went too long without understanding what had changed under the hood.
DORA identifies small-batch development as an important safety mechanism for AI-assisted software delivery: faster code generation only creates value when teams can still review and validate the output.
This was a structured workflow, not an uncontrolled swarm of agents editing the same codebase. Anthropic makes a similar distinction in Building effective agents: predictable workflows are often the better choice when a task already has a clear path.
What shipped: a full-stack Next.js MVP
StampMate became a full-stack Next.js and TypeScript application with:
- Better Auth for owners and staff;
- Postgres, Prisma, and Supabase;
- public customer joining without passwords;
- secure, random card tokens and QR codes;
- in-browser QR scanning;
- protected stamp and redemption actions;
- automatic loyalty-card cycles after redemption;
- owner statistics and customer activity; and
- mobile-first customer and staff screens.
The meaningful checkpoint was the complete business flow: an owner could create a program, a customer could join by QR, staff could scan and add stamps, and a completed reward could be redeemed into a fresh card cycle.
One technical example: stopping a redemption race condition
The redeemReward action shows why the specialist contexts mattered.
A simple implementation would disable the Redeem button after a tap and assume the job was done. But the browser can send two requests before the page updates. The same thing can happen through a slow connection, a retry, or two open tabs.
Both requests might read the card while its status is still COMPLETED. Without a server-side defense, both could record a redemption and create two new active cards.
StampMate handles the case in layers:
- The server validates the card token and derives the business from the card instead of trusting a client-provided business ID.
- It verifies that the current user belongs to that business.
- Inside a database transaction, it reads the current card status again.
- It marks the old card REDEEMED, writes an audit record with the staff user, and creates the next card cycle with a new random token.
- The database allows only one redemption record for the old card. If a second request races past the status check, that unique constraint rejects it.
Because everything is in one transaction, the losing request rolls back instead of leaving half-finished data. The app turns the database error into "This card has already been redeemed."
That is more than generated UI. It is product, database, backend, and security context working together.
What went wrong: a QR scanner camera-lifecycle bug in React
Not every agent output was correct on the first pass.
The first QR scanner implementation assumed that normal component cleanup would always stop the camera. That failed during a timing edge case: if a user navigated away while the asynchronous scanner startup was still pending, cleanup ran before the scanner entered its SCANNING state and skipped the stop call. Startup then completed after the page had unmounted, leaving the camera stream active.
I had to revisit the implementation and change the lifecycle logic. The scanner now checks whether the component was cancelled after startup resolves; if so, it immediately stops and clears the scanner.
That camera lifecycle bug took longer than the visible scanner UI. It was also a useful loss: it showed that specialized agents and small milestones reduce risk, but they do not remove the need for human testing and review.
The First Mate takeaway: a repeatable AI-agent workflow
"Built in two days" does not mean the software will never need maintenance, production monitoring, or user feedback. It means a carefully scoped MVP moved from requirements to a working implementation in two focused days.
AI did not remove engineering judgment. It allowed one person to apply that judgment across more work while keeping every step small enough to understand and verify.
That is how First Mate handles AI-assisted development:
- Define the user outcome.
- Remove nonessential scope.
- Create specialists around the real risks.
- Work on small, testable milestones.
- Keep the human responsible for every checkpoint.
The best result was not only that StampMate shipped quickly. It was that I could still explain how it worked when it was finished.
Try StampMate — or hire the AI engineers who work this way and start a two-week trial.


