Skip Supabase: How Claude Built a Role-Secured CRM — Database, API, Email, and Frontend — in One Conversation

Skip Supabase: How Claude Built a Role-Secured CRM — Database, API, Email, and Frontend — in One Conversation

Think about what it takes to ship a small CRM on a traditional stack today.

You create a Supabase project for the database and auth. You write row-level security policies for every table. You write an edge function for anything the auto-generated API can't do. You sign up for Resend or SendGrid to send email. You deploy the frontend to Vercel or Netlify. Then you wire all of it together and pray the CORS gods are merciful.

That's four services, a handful of dashboards, and a security model you have to implement correctly yourself.

We did the whole thing in one conversation instead.

Claude - connected to AINIRO's Magic Cloud over MCP - was given a single prompt, and built a complete, role-secured CRM. Database, API, email, and frontend. This article walks through it step by step, and you can watch the entire build in the video below.

The prompt

The prompt was, in spirit, the following.

Create a new app named "crm6". I need a database with 3 tables, a CRUD web API, the ability to send emails to contacts, and a modern designed frontend at "/crm6". Only allow users belonging to the role "guest" to invoke the API.

Notice what's missing. No schema. No endpoint list. No framework choice. No security implementation details. We described the outcome, and let the machine figure out the wiring.

Step 1: The database

Claude started by creating a SQLite database called crm6, with three tables.

  1. contacts - name, email, phone, company, and status
  2. deals - title, amount, stage, and a foreign key to contacts
  3. activities - type, notes, due date, done flag, and a foreign key to contacts

Foreign keys, sensible defaults, and seed data included, so the app had something to show from the first render.

On Supabase this part is honestly fine - Postgres is great at being Postgres. The difference starts with what happens next.

Step 2: The secured CRUD API

Claude then used Magic's CRUD generator to produce the API. Twelve declarative invocations - one per verb per table - produced 722 lines of Hyperlambda, giving us GET, POST, PUT and DELETE endpoints for every table, plus record-count endpoints. Sixteen endpoints in total, live on the cloudlet the moment they were generated.

And here is the Supabase edge, stated plainly.

Every single endpoint declares that it requires the guest role, and the runtime enforces that check before any endpoint logic executes. Claude didn't implement security. It declared it.

On Supabase, securing this API means writing row-level security policies, per table, in SQL, and hoping every piece of generated code respects them - while the service-role key that bypasses everything sits in an environment variable. When an AI writes your application, every generation is a fresh chance to get that wrong. On Magic, the generated code never gets a vote. Access control is a property of the platform, not of the code.

The crm6 contacts table with search, status badges, and per-row actions

Step 3: Email, without a third-party email service

The prompt asked for the ability to send emails to contacts. On the traditional stack this is where you'd add a Resend account, an API key, and an edge function.

Claude instead described the endpoint to Magic's Hyperlambda Generator in plain English: look up the contact's name and email address, throw if the contact doesn't exist, send the email, and only allow guest users to invoke it.

The generator produced the working endpoint in 7.6 seconds. Measured, not estimated.

SMTP is configured once, at platform level. The application - and the AI writing it - never touches a mail-provider credential, because there isn't one in the application.

Sending an email to a contact directly from the CRM

Step 4: The frontend, served by the same platform

No Vercel. No Netlify. No separate hosting product at all.

Claude wrote three files - HTML, CSS, and JavaScript - straight into the cloudlet's file system, and the app was live at its URL the moment the files were saved. Same host as the API, which also means no CORS configuration. The frontend logs in against Magic's built-in JWT authentication, and refreshes its ticket automatically every ten minutes.

The crm6 login screen using Magic's built-in authentication

The app itself got a dashboard with KPI cards, a pipeline-by-stage chart, and upcoming activities.

The crm6 dashboard with KPI cards and pipeline chart

Plus a drag-and-drop deals kanban - drag a card to another stage, and the deal is updated through the same guest-secured API.

The crm6 deals kanban with drag-and-drop stage changes

Step 5: Verification

Generated software that hasn't been verified is just speculation, so the build ended the way it should.

  1. Anonymous requests were fired against the CRUD endpoints and the email endpoint - every one of them rejected with a 401.
  2. The frontend was rendered in a browser and every view checked - login, dashboard, contacts, deals, and activities.
  3. The seeded numbers on the dashboard were checked against the data.

Only then was the job reported as done.

What we never had to do

This is the part worth sitting with. Compared to the Supabase-stack version of this build, here is what simply never happened.

  1. No row-level security policies were written - or gotten wrong
  2. No edge functions were written by hand
  3. No third-party email service was signed up for
  4. No separate frontend hosting was configured
  5. No CORS was configured
  6. No auth library was installed
  7. No service-role key existed for generated code to leak or misuse

One prompt. One platform. One conversation. A working, role-secured CRM.

Wrapping up

The interesting question isn't whether AI can generate code. It's what platform you hand it. Give an AI a stack where security lives inside the code it generates, and every generation is a risk you have to review. Give it a platform where security is enforced by the runtime, and the worst a bad generation can do is fail.

That's why the build you just read about was possible - and why it's reproducible on any Magic cloudlet, today.

If you want to explore Magic Cloud for yourselves, you can find our open source repository below.

If you'd rather have us help you build something similar for your own use case, you can contact us below.

Thomas Hansen

Thomas Hansen

I am the CEO and Founder of AINIRO.IO, Ltd. I am a software developer with more than 25 years of experience. I write about Machine Learning, AI, and how to help organizations adopt said technologies. You can follow me on LinkedIn if you want to read more of what I write.

This article was published 24. Jul 2026

The MCP Deprecation Clock Starts July 28th. Here's Your 12-Month Migration Checklist

On July 28th the largest MCP spec revision ever becomes official, and a 12-month deprecation clock starts ticking on every server you're running today. Here's the checklist - and why the auth migration matters more than the protocol one.

I Wrote, Illustrated, and Published This Article Without Leaving My AI Chat — Here's the Exact Setup

Research, headline, prose, screenshot, cover image, publishing - one Claude session, one MCP connector, zero CMS. This is the log of that session, including the part where we built the missing feature mid-conversation.

From Zero to Production Backend with HTTPS in One Copy-Paste: Magic Cloud on DigitalOcean

The entire deployment is a cloud-init file you paste into a form. API, admin UI, database, and automatic HTTPS - live in 20 minutes on a $12 droplet.

AINIRO.IO's Logo

AINIRO.IO Ltd is an independently owned company in Cyprus, 100% owned and operated by Thomas Hansen, and that's how it stays!

If you're an investor, please click back in your browser! I don't want to hear what you have to say, and I'm not interested in your money!

Copyright © 2023 - 2025 AINIRO.IO Ltd