I Never Meant to Build Medical Software. Now I Sell It.
In April I ended a case study with a sentence I thought was a responsible place to stop: the clinical half of the system lives in a branch on my laptop, waiting. Five months later that branch is a company. ArturoMed is commercial medical software, with a published price, terms of service, a data processing agreement, and five clinics that signed up during a soft launch. We’re now in the distribution phase, which is a polite way of saying the product works and the hard part is getting it in front of doctors.
I didn’t plan any of this. I planned to help my sister stop drowning in WhatsApp threads. If you haven’t read that story, the original case study covers the build, the cryptominer that hit on launch night, and everything I rebuilt afterwards. This post is about what came next: the moment a favor becomes a product, and why that moment is much bigger than it looks from the outside.
The short version is this. Building software for someone you love is a project. Charging strangers for software that holds their patients’ health records is a different job entirely. Almost nothing I learned in the first phase prepared me for the second.
A preview of ArturoMed: a patient books from her phone and the appointment lands on the clinic’s calendar. This is the marketing animation from arturomed.com, a simplified take on the product with demo data.
1. Pulling a Product Out of a Favor
The system I built for Dra. Paola Ruiz was custom in the worst and best sense. It fit her practice perfectly because it was shaped around her practice. Her services, her schedule, her website, her way of confirming payments. When something needed fixing, I logged in as administrator and fixed it. When she wanted a new field, I added a new field. There was one clinic, one database, one set of expectations, and a support channel that was literally a family group chat.
That model does not scale past one clinic. It barely scales past one sibling.
So at some point I cloned the repository with a very specific intention written in my notes: sacarle el producto de adentro. Pull the product out from inside it. Paola’s system kept running untouched. The new repository became the place where her custom tool would be taken apart and rebuilt as something any clinic could subscribe to.
The commit history tells the story better than I can. The product repository had 40 commits in May, when it was still mostly an idea. It had 426 in July, 719 in August, and 869 in September. More than 2,400 commits in total, written by me and a rotating crew of AI agents. The acceleration isn’t a productivity flex. It’s what happens when you discover how many things a product needs that a favor never did.
What “multi-clinic” actually means
From the outside, turning one clinic into many sounds like adding a clinic_id column and a signup page. It is not that. Every assumption baked into the original system had to be found and challenged:
- Isolation. Clinic A must never, under any circumstance, see a single row from Clinic B. Not through a bug, not through a slow query, not through a misconfigured report.
- Roles. Paola’s system had “Paola” and “the assistant.” The product has six roles, and access is fail-closed: if the system can’t prove you’re allowed to see something, you don’t see it.
- Provisioning. A new clinic needs a database space, an owner account, default settings, a schedule, a booking link, and a welcome email. All of it created automatically, correctly, every time.
- Recovery. If one clinic deletes its March agenda by accident, you need to give it back without touching any other clinic’s data.
None of those problems existed when there was one clinic and I was its administrator. All of them are existential when there are five, and the architecture is designed so there can be thousands of clinics and, eventually, millions of patient records.

How ArturoMed is put together. The console creates clinics and does not open their records. Each clinic works in its own panel.

A clinic’s home screen in the product. Same idea as Paola’s system, rebuilt so any clinic can have its own. Demo data.
2. Once You Charge, There Is No Undo
This is the lesson I want every designer who’s flirting with building their own SaaS to hear. The moment money changes hands, your relationship with errors changes permanently.
When Paola’s system broke, it was a bad afternoon. She’d message me, I’d fix it, we’d laugh about it at dinner. When a paying clinic’s system breaks, a doctor can’t see her patients’ histories in the middle of a consultation. Appointments vanish. Someone who trusted you with their practice now has a reason not to. And you can’t fix it by quietly logging in as admin and editing rows, because you’re not supposed to be in there at all.
Deploys stop being casual
In the favor phase, a deploy was me pushing code and watching the site come back up. In the product phase, a deploy touches every clinic at once. A broken migration doesn’t break one practice; it breaks all of them. So the pipeline changed shape:
- Builds happen only on GitHub Actions runners, never on the server. (That rule came from the cryptominer. It survived the transition.)
- The main branch is treated as sacred. No agent pushes to it without my explicit consent. Not once, not “just this small fix.”
- Every change to the database schema has to be safe to run against every clinic that exists, including clinics with messy data I’ve never seen.
- Nightly encrypted backups, with a documented, tested procedure to restore one clinic from one night without touching the rest. For custom plans we’ve already planned to go much further: backups every 15 minutes or less, because in a large operation losing a night of data isn’t acceptable.
[!important] In a paid product, “we can fix it later” stops being a plan. Every system that holds customer data needs its failure path designed before its happy path ships: how you restore it, how you audit it, how you explain it.
The admin console is the real product
Here’s the shift I underestimated most. With Paola, the admin console was me, logged in with superuser powers. With a commercial product, that’s not acceptable: legally, ethically, or operationally. You need an operator console where every action you can take on a customer’s account is explicit, bounded, and logged.
The console is where you create clinics, see their plan, check their provisioning status, handle support, and do all of it without reading anyone’s medical records. It’s an entire second product that the customer never sees, and it has to be as well designed as the first, because you’re the one using it at 11pm when something is wrong.
I learned how much this matters the uncomfortable way. In September I asked a simple question: does creating a clinic from the console actually work end to end? The audit came back with a blunt answer. No. It breaks at step 2 of 8. The form asked for the owner’s name, email, title and ID number, displayed them on the confirmation screen, and then threw them away on submit. The endpoint only accepted the subdomain and the plan. Without the owner’s email there was no one to notify, so the provisioning job never entered the queue. The clinic sat in the catalog as “incomplete signup” and nobody would ever look at it again.
The worst part: our own agent instructions claimed the console “already provisions end to end.” It didn’t. The public signup path, the one triggered by an actual payment, did work: 267 tests passing, queue, executor, clinic creation, owner account, welcome email. But the path I’d use to onboard a clinic by hand was a beautiful form attached to nothing.
Nobody got hurt, because we found it before it mattered. But it’s the clearest example I have of the gap between “the screen works” and “the system works.” As a designer, I’m trained to trust the screen. A product owner can’t.

How a clinic is born in ArturoMed. Every step is a screen, a state or an email someone has to design, and every one of them can fail.
3. Health Data Changes the Design
Scheduling was the safe half. Appointment times and contact details are sensitive, but they’re not clinical. The moment ArturoMed started holding triage notes, consultations, prescriptions, lab and imaging orders, and diagnoses coded in ICD-10, it crossed into the category of data where mistakes have consequences for people who never agreed to be part of my learning curve.
In Ecuador that means the Personal Data Protection Law, the LOPDP. Reading it as a designer was a strange experience, because most of its requirements are design requirements in disguise.
Who owns the data
The first question is who is responsible for what, and the answer shaped the entire product. The data belongs to the patient. They own their own information. The clinic controls it: it decides what gets recorded and why. ArturoMed processes it: I operate the system that stores it, on the clinic’s instructions, under a written data processing agreement.
That single sentence rules out a lot of things I used to do casually. I don’t browse clinic data to debug. I don’t use records to “improve the product.” Every access I have is justified by a contract clause, and if it isn’t, I don’t have it.
Legal compliance that became features
The legal documents aren’t paperwork that sits next to the product. They’re a spec. And what follows aren’t promises we chose to make: it’s legal compliance, what the law requires. Here’s what each one forced us to build:
- Breach notification within 48 hours. That means we need to know within 48 hours, which means monitoring, audit trails, and a written procedure for who does what.
- Clinics must keep records for 15 years after the last visit. So deleting a clinic can’t mean dropping its tables. Export, retention, and deletion all needed real design.
- Patients have rights over their data. Access, correction, and the rest. We audited every path patient data travels through the system and every right a patient can exercise, and built the screens to honor them.
- Health data stays confidential indefinitely. Not for the contract term. Forever.
One piece doesn’t come from the law but from security: an audit log nobody can edit. Every sensitive action is recorded, and the table is protected at the database level by a trigger, so not even the application can quietly rewrite history. No article of the law asked for it. I built it because if something goes wrong, I want to be able to prove exactly what happened.
[!warning] If you’re building anything that touches health data, don’t treat compliance as a phase at the end. Read the law first. Half of its clauses will turn into database constraints, and it’s much cheaper to design them in than to retrofit them.
This is also where the thesis of this whole post comes from. I used to think of compliance as a tax on building. Now I think of it as the most honest user research I’ve ever done. The law is a document written by people who’ve seen what happens when patient data goes wrong. Every clause is a failure mode someone already lived through.
4. The Doctor and the Paper Records
Every new product has a first real customer outside the family, and ours taught me more in a few weeks than the previous months combined.
She’s a psychiatrist with a practice in Manta. She wanted ArturoMed, and she wanted her history in it. Years of patient records, living in paper, loose files, and spreadsheets. Psychiatric notes, medication histories, diagnoses. About the most sensitive category of health data that exists.
Here’s where the favor mindset would have failed completely. With Paola, I’d have said “send me the files, I’ll load them tonight.” With a paying doctor, that sentence is a legal problem. Migrating her records means someone at ArturoMed actually sees and handles copies of her patients’ histories, and AI systems read those materials to classify them and put each piece in the right field. None of that is covered by the normal operation of the platform. It needs its own permission.
So we wrote one. A separate, scoped authorization just for the migration:
- It lists exactly which categories of data can be migrated, and only what she explicitly hands over. No “just send me the whole drive.”
- It names who can access the working copies and for what, and what AI systems can do with them. Classify and place, nothing else. No training models on her patients’ records, ours or anyone else’s, and no use for any other clinic.
- It sets a time limit and requires the working copies to be deleted when the migration closes.
- It’s reviewed by an Ecuadorian lawyer before it’s final.
And the rule that matters most: until she signs, not a single record gets copied or loaded. It doesn’t matter that she’s eager. It doesn’t matter that it would take one evening. The friction is the point.
That’s slower than anyone wants, including me and including her. But it’s the difference between a doctor trusting you with her practice and a doctor trusting you with her patients. The second one is a much bigger ask, and it deserves a much more careful answer.

The migration flow. Until she signs, nothing is copied.
5. Product Design at Real Scale
When I was building for Paola, UX meant making her screens clear. Now UX means everything a customer touches, and a lot of things they don’t. The job expanded in every direction at once.
Onboarding and knowing your client
You can’t hand medical software to an anonymous signup. Knowing who your client is (their legal name, tax ID, professional title, the person responsible for the data) isn’t bureaucracy; the processing agreement is signed with a real person or entity, and the welcome email goes to the owner of the account. Onboarding became a designed flow: pay, get provisioned, receive your owner account, configure your schedule and services, share your booking link. Each step has to work without me in the loop, because at a thousand clinics I can’t be in the loop.
Pricing is a design problem
I rewrote the billing model three times in four days. That wasn’t indecision; each version exposed a question the previous one had dodged. Who counts as a seat? Is an assistant the same as a doctor? What about a supervisor? Where we landed:
- Solo: USD 30 a month, or USD 300 a year (you pay for ten months). Up to two seats: one doctor, one assistant. Ecuadorian VAT on top.
- Equipo (Team): priced per role, up to ten seats. The first assistant is included; supervisors are charged from the first one.
- A medida (Custom): agreed in writing, no seat cap.
The refund guarantee went from 30 days to 10, and there’s no free trial. Both decisions came from the same place: a clinic that tries ArturoMed puts real patient data in it. A casual trial with medical records isn’t a trial. It’s a data processing relationship with no commitment behind it.
Metrics without looking at patients
You can’t improve what you can’t see, and you can’t look at patient data. So product analytics had to be designed around events, not records: a clinic was created, an appointment was booked, a consultation was closed. Events are tracked in Amplitude under the terms clients accept, the public site only measures with cookie consent, and nothing clinical goes into an event. I can see that consultations are being completed; I can’t see what’s in them. That’s exactly how it should be.

Three billing models in four days to get here. Every pricing question is really a question about roles and access.
Running a product with AI agents
I still build ArturoMed with AI agents, but the way we work looks nothing like the vibe coding of April. A few rules that exist because something went wrong without them:
- Linear is the only source of truth. No task files in the repo. Every change starts as a ticket, and tickets and commits are written in Spanish, because that’s how I review work without reading every line of code.
- Every agent works in its own git worktree.
git stashis banned, because one agent’s stash can swallow another agent’s work. - A test you never saw fail doesn’t count. Agents have to break the behavior on purpose and watch the test go red before it’s trusted. And they have to name which of our fourteen test suites they actually ran.
- Instructions drift, so they get audited. Our agent instruction files had quietly diverged to twice the length of each other before we unified them. The console audit found that those instructions contained at least five claims that turned out to be false.
That last one is the lesson I’d underline for any designer managing agents. The agents are fast and capable, and they will confidently tell you things are done. Your job is to ask the question that reveals whether the system actually does what the screen says.
What It Takes, Honestly
Five clinics. A soft launch. A product that’s live with scheduling, a full electronic health record, roles, an audit trail, and published prices. By the standards of the SaaS dream I used to scroll past, that’s tiny. By the standards of the guy who deployed a scheduling app for his sister in April and got a cryptominer for his trouble, it’s the hardest thing I’ve ever built.
If you’re a designer thinking about building your own product with AI, here’s what I’d tell you. The tools really do let you build it. The code is no longer the barrier. The barrier is everything that surrounds the code once someone pays you: the console you need so you never have to go inside their data, the restore procedure you hope you never run, the law that turns out to be a spec, the onboarding flow that has to work at 3am without you, and the discipline to say “not until you sign” to a doctor who’s ready right now.
None of that shows up in a demo. All of it is product design. And it’s exactly the kind of design work our profession is well placed to do, if we’re willing to go below the interface and own what happens there.
ArturoMed is live at arturomed.com. If you run a practice in Ecuador, the plans are at arturomed.com/planes. If you’re a designer standing at the edge of your own “favor that could be a product,” I hope this saves you a few of the surprises. You’ll still get the rest.
