All workCase study12 min read

Fyxes: on-demand home cleaning

A two-sided marketplace for on-demand home cleaning in Melbourne. Built from scratch on my own time and money, launched for real, and shut down when the data said no. This is the whole story, numbers included.

Role
Founder & Product Designer
Company
Fyxes
Year
2026
Project
Two-sided marketplace, ground-up
Outcome
Launched, measured, shut down
Flight crew
Solo, directing an AI crew: Kai on engineering, Mochi on QA, Knope on PM, Amy on finance. Built in Claude Code on React Native, Expo, Supabase and Stripe Connect, every change PR-reviewed before release. Plus two agents of my own build, Opi and Codsworth, running ops in production.

Booking a cleaner shouldn't mean a group chat, three reschedules, and hoping the person who shows up is who you agreed to. Fyxes was my attempt to fix that for Melbourne: a proper two-sided marketplace where customers booked a clean in a few taps and cleaners ran their whole workload from the same system.

It was also the first product I built entirely on my own terms. I was the founder, the designer and the product owner, working alongside an AI-augmented team standing in for the engineering, finance and QA roles I couldn't hire for: Kai on engineering, Amy on finance, Knope on project management, Mochi on QA. Every call on scope, and especially on money and auth, got made the way I'd want a senior engineering team to make it.

React Native + Expomobile app
Supabase + Stripe Connectauth, data & payouts
Solo + AI teamfounder-led, AI-augmented

Two sides, one marketplace

The customer side starts with a home screen built around one job: get a clean booked fast. From there, a room-by-room builder (bedrooms, bathrooms, kitchen, living areas) prices the job as you go, so there's never a surprise total at checkout.

The Fyxes customer home screen: a 'get your house cleaned' booking prompt, referral offer, and nearby cleaners.
The customer home screen: booking is the first and only thing on offer.
The room-by-room booking builder, with per-room counters and a running subtotal.
Room-by-room pricing: the total updates live as you build the job.

Confirmation closes the loop immediately: cleaner assigned, time and address locked in, room list itemised. No back-and-forth, no waiting to hear back.

Booking confirmed screen, showing the assigned cleaner, date, address and itemised room list.
Booking confirmed: cleaner, time and address locked in on the spot.

...and the other side of the marketplace

None of that works without the other half: cleaners need their own tool to manage jobs, availability and service areas, or the whole thing turns into me manually matching bookings by hand. The cleaner app runs on the same booking data (upcoming jobs, ratings, availability), so both sides of the marketplace are looking at the same source of truth.

The cleaner-side home screen: upcoming and completed job counts, rating, next job details, and availability/service area management.
The cleaner side of the same marketplace: jobs, ratings and availability in one place.

One brand, four surfaces

The apps were only half the operation. Around them I built a marketing website to do the SEO legwork, an ops dashboard to run the business from, and a pair of AI agents doing the work a support team would. Every surface designed, built and shipped solo, all of it in production.

4surfaces: customer app, cleaner app, website, ops dashboard
~100Supabase edge functions behind them
2AI agents on staff: Opi and Codsworth

The front door: fyxes.com.au

The website's job was to be found, and then to convert. Sixteen suburb pages across Melbourne's inner north, each one hand-written rather than templated, structured data down to a per-suburb service schema, and an llms.txt so even AI assistants could quote the pricing correctly.

Pricing lives as code in a single shared schedule: one source of truth feeding the app, the website's earnings calculator for cleaner recruitment, and the structured data, so the numbers could never drift apart. And the cookie banner has a real reject: saying no genuinely tears the trackers down. A small thing, but it's the kind of honest UX I want my name on.

The fyxes.com.au landing page: the headline 'If you can order a ride, you can book a clean', app store badges, and a clay character holding a phone showing the Fyxes app.
fyxes.com.au: if you can order a ride, you can book a clean.

Mission control: the ops dashboard

Behind the marketplace sat the dashboard I ran the company from: cleaner applications, document verification, disputes and call-outs as work queues, with live booking insights on a map. It started as a launch-week monitoring tool and hardened into a proper admin product, with multi-factor login and every state-changing action written to an audit log.

Its most important design rule: money never moves casually. Some surfaces hand the action to Codsworth in Slack to draft and approve; the ones that act directly state their money outcome in plain language before the button will work, and write to the audit log after. The post-payout dispute form is my favourite example: it tells you exactly what submit will do, the Stripe reversal, the fallback if the payout already cleared, who gets paged, before it lets you do it.

The Fyxes dashboard overview: needs-attention counters for new applications, document verifications and disputes, alongside all-time booking counts and system health checks for Supabase and Stripe.
Mission control: the queues that need attention up top, the health of everything underneath.
The post-payout dispute form: booking ID and reason fields, a source dropdown, and a yellow 'Money outcome on submit' panel spelling out the Stripe reversal before the Flag dispute button activates.
The post-payout dispute form: the money outcome spelled out, in yellow, before the button works.

AI where it earned its keep

Fyxes used AI where it removed real toil, never as garnish. Cleaner onboarding is the clearest example: Claude reads each police check and insurance document in two passes, a quality gate that tells the cleaner instantly when an upload is unreadable, then extraction of names, expiry dates and coverage. The AI pre-screens; I made every final call. One detail I'm fond of: if the model abstains on an identity document for safety reasons, the document routes to human review instead of auto-reject. An AI declining to answer should never cost someone a job application.

  1. Cleaner uploads a document

    A police check or an insurance document.

  2. Pass one · quality gate

    Unreadable uploads bounce instantly, so the cleaner knows right away.

  3. Pass two · extraction

    Names, expiry dates and coverage pulled out, ready for review.

  4. Final call · human

    I approve every application. If the model abstains, the document routes to me, never to auto-reject.

The document pipeline: AI pre-screens, a human decides, and an abstaining model never costs anyone a job application.

Booking photos got the same treatment. Customers photograph their kitchen and bathrooms, and a vision model answers exactly one question: is this a regular clean or a deep clean? It shows its reasoning, it only speaks up when it's confident, and the customer always confirms. The rule we locked early: on a pricing path, no suggestion beats a wrong suggestion. If the AI fails, the booking flow never blocks.

Opi and Codsworth: the staff I didn't hire

Opi is the first responder. It watches live bookings for the moments that go sideways, a customer not home, a cleaner running late, a dispute, and works the problem over SMS with both sides while reporting to me in Slack. It runs on tiered autonomy: almost everything is drafted for my approval first, and its one self-serve money action is the $60 call-out fee, charged only after a timed three-message escalation goes unanswered.

Opi · SMS · live booking
OpiHi Priya, Maria has arrived at your place but can't reach you at the door. Are you home? – Fyxes
Priya · customeromg sorry, stuck in traffic, 5 min away!!
OpiNo stress, I've let Maria know you're close. She'll wait at the door. – Fyxes
Recreated from Opi's 'customer not home' playbook: replies classified and relayed to the cleaner at the door. If nobody answers within 15 minutes, the call-out fee is the one charge Opi can make on its own.

Codsworth is the operations lead: a courteous AI butler who lives in my Slack DMs. Fifteen tools, from booking and customer lookups to long-term memory, and the two that matter, cancel and refund. Anything destructive posts a draft with an Approve button; nothing sends and no dollar moves until I tap it. Both agents run on a metered monthly budget with a hard pause, because an AI ops team should have a payroll cap too. And yes, he's named after the Fallout butler.

Codsworth · Slack DM
Michelle@codsworth what's the story with this morning's Thornbury booking?
CodsworthConfirmed for 10am, madam: 3 rooms, $185, Maria assigned and en route. The customer has one prior cancellation on file.
Michelleshe just emailed to cancel. draft it
CodsworthVery good. Cancellation drafted: $60 late fee, split 80/20 to Maria. Customer SMS prepared for your review. Nothing sends until you approve.
Recreated from Codsworth's real tools and guardrails: instant answers from read-only lookups, and an Approve gate on everything that moves money.

None of this ran unwatched. The whole platform reported into a single #fyxes-alert channel in Slack: severity-throttled pages when something broke, and a cron watchdog that checked all 38 scheduled jobs and posted a heartbeat on every tick. My favourite line in the whole system lives inside that heartbeat: if the message stops arriving, the watchdog itself is down. Even the thing that watches the things gets watched.

The #fyxes-alert Slack channel: the Fyxes Ops bot posting FYX445_HEARTBEAT_OK cron watchdog ticks, 38 crons checked, zero stale, with a note that a missing heartbeat means the watchdog itself is down.
The real #fyxes-alert channel: the cron watchdog posting its heartbeat, 38 jobs checked, zero stale. No news is bad news, by design.

The cargo manifest

Running a marketplace solo is mostly a supply-chain problem: pick boring, reliable services and make them talk to each other. This is what was in the hold.

Cargo manifest
  • SupabasePostgres, auth, storage, realtime, ~100 edge functions
  • Stripe Connectpayments, cleaner payouts, refunds
  • Anthropic APIOpi, Codsworth, and vision for documents and photos
  • Twilioevery SMS, in and out
  • Slackthe ops console and every Approve button
  • Expo + EASReact Native builds and over-the-air updates
  • Sentrycrash and error monitoring
  • PostHogproduct analytics
  • Resendtransactional email
  • Google Mapsaddress entry and the bookings map
  • Vercelwebsite and dashboard hosting
  • PDFShiftreceipts and invoices
  • ATO ABN Lookupcleaner ABN verification
  • Notiondocument review queue and product board

Where it landed

Fyxes launched in June 2026. I ran Meta ads, dropped flyers across nearby suburbs, offered 15% off a first clean, and recruited the supply side one conversation at a time. The top of the funnel did its job: 21 customers signed up, 19 cleaners registered, and five made it through document verification.

Then the number that mattered: zero. Not one of those 21 signups became a booking. Every booking in the production database was me, testing. The marketplace I had spent months hardening never processed a single real transaction.

The launch funnel, in full. Both sides of the marketplace showed up; the transaction never did.

When weeks of live marketing refused to move that number, I made the call to shut it down. Not because I stopped believing in the problem, but because the data had answered the question the company existed to ask, and the answer was no. Killing it quickly was the last product decision Fyxes needed from me. I think it was the best one I made.

What I learned

I sequenced it backwards. I built a production system I'm still proud of: fraud signal logging, payout reconciliation, rate limiting, dispute flows. All of it defends against risks that require customers to exist. The only question that actually mattered, will a stranger pay for this, could have been answered in a fortnight with a landing page and a weekend of matching bookings by hand. I answered it last, after months of engineering. Next time: validate demand with the cheapest artifact that can produce a yes, and spend real engineering only after real money moves.

A two-sided marketplace is two cold-start problems at once, and a solo founder with a day job gets to solve one at best. Supply was winnable; cleaners answered flyers and finished verification. Demand needed a budget or a distribution edge I didn't have. I'd build a marketplace again one day, but not alone, and not as a 5-to-9.

What survived the shutdown: the AI-augmented team practice, the stack, the defensive instincts on money and auth, and a tested playbook for shipping production software solo. All of it went straight into Simply Kind, which went from first sketch to the App Store in a fraction of the time. Fyxes never returned the investment in bookings. It returned it in capability.