A. Mauclair
← All work

01 Product & business 2026

GrillTask

Accountability with receipts, priced and billed like a real business.

Case study · approx. 6 minute read

Role
Founder & CEO, solo build
Timeline
2026 – present
Stack
React Native, vanilla JS, Firebase, Stripe, Vercel
Plans
Free, Plus, Pro
Languages
9, including right-to-left Arabic
Where
grilltask.com

The problem

Tasks between people who trust each other die at the follow-up. A parent asks, a roommate promises, and everyone forgets until it turns into an argument. GrillTask makes the loop explicit: you assign a task, the other person submits photo proof when it is done, and your approval releases points toward rewards you both agreed on beforehand. The proof is the whole point. It replaces nagging with evidence.

What I built

All of it. GrillTask is two clients sharing one Firebase project: a React Native app and a vanilla-JavaScript web app that ports every screen, both reading the same Firestore collections and enforced by the same security rules. There is no build step anywhere in the web stack, which is a deliberate constraint. It keeps deploys down to a git push and leaves nothing between the code I wrote and the code that ships.

  • ClientsAn Expo React Native app plus a hash-routed vanilla-JS web app, both on one Firebase project.
  • BackendVercel serverless functions for payments, email, communities, referrals, usernames, and account lifecycle.
  • DataFirestore with a hand-written rules file as the master copy. Queries use single-field filters and sort in JS, so no composite indexes are needed.
  • PaymentsStripe Checkout created server-side, a signed webhook, and a billing portal. The browser never holds a key.
  • EmailResend, driven by three daily cron jobs: task reminders, an account sweep, and cleanup of unverified sign-ups.
  • LocalizationNine languages. English is the source and the rest are overlays, with Arabic switching the document to right-to-left.

The business

GrillTask is not a demo with a fake upgrade button. There are three tiers and I chose every line in them: Free, Plus at $3.97 a month or $19.97 a year, and Pro at $9.97 a month. The monthly plan is the only one carrying a free trial, because a trial on an annual plan mostly buys refunds. Deciding what belongs in each tier was harder than building any of it. Connections, group sizes, proof photos, how long history is kept, data export, and team analytics all had to be sorted into a ladder that feels generous at the bottom and worth paying for in the middle.

The rule I held to is that a paid status is never something a browser can claim. Only the Stripe webhook, the admin tools, and the referral server can write it, and the security rules reject anything else. Pricing is only credible if the enforcement is real.

Choosing what goes in the free tier is a pricing decision, an engineering decision, and a promise to the customer all at once. I would rather get that wrong early than never make the call.

Growth is wired in rather than bolted on. Invite codes give the new person a few days of Pro and earn the referrer credits they can spend whenever they like, and the codes rotate on a schedule that gets faster the more someone pays. Support runs through a bubble on both the site and the app that lands in a real inbox I read.

What it taught me

Being a one-person team forces honest engineering. Serverless, because I cannot be on call for a fleet. Security rules as the enforcement layer, because client code cannot be trusted with plan limits. An admin panel built early, because support without tooling does not survive the first confused customer.

The bug that cost me the most time was a Firestore rules subtlety: reading a field on a document that does not exist is not false, it is an error, and Firestore turns that into a flat denial. It sends you to the dashboard when the answer is in your code. I now key rules off the document path wherever I can, and I wrote the lesson down in the repo so the next version of me does not lose the same afternoon.

The unglamorous details are most of the work. Due dates pin to 23:59 in the receiver's timezone, not mine. Approvals are atomic batches with the ledger entry keyed to the task id so a double tap cannot double-pay. Cache busting is a versioned number bumped across every file at once, because a stale module makes a shipped fix look broken.

Where it stands

GrillTask is feature-complete and heading to the App Store, live on the web at grilltask.com. It is the first product where I have owned every layer: the positioning, the architecture, the code, the prices, the support inbox, and the App Store paperwork. It set the standard I want to hold for everything after it, which is a small surface finished properly rather than a large one left half-done.