EC × MJ Beauty — a demo
FRIEND
A demo · 2026

Hey — here's what I've been building.

Two small businesses, two custom CRMs, both with AI doing the boring parts. Quick tour.

Slider in the top right ↗ — if anything gets too technical, leave it on Friend. If you want me to go deeper on something, slide it right.

Slider: Friend = plain English, Founder = the actual workflow, Builder = under the hood.

Slider just swaps body copy per slide. Level 3 is the technical layer for when you ask "wait, how does that actually work."

Exterior Completion · Ded's cleaning company MJ Beauty · Maddie's salon
Exterior Completion

Ded runs his cleaning company from Discord.

Pressure washing, window cleaning, spring cleanups in Calgary. Customers text in, quotes go out as a link, money comes through Stripe, and everything important shows up in his Discord with buttons to tap.

Lead → quote → job → invoice → payment, all one CRM. The assistant watches the funnel and pings Ded when something's stuck ("this lead's been quiet 5 days, want me to follow up?"). Recurring window cleans auto-bill via Stripe.

Cloudflare Worker (Hono) + D1, ~70 migrations, Stripe live, Twilio webhooks signed and verified, Discord interactions endpoint for the buttons. Three scoped auth modes (human session, read-only agent, write-capable agent). About a thousand tests gate every PR.

In

SMS, web form, Discord intake.

Out

SMS replies (gated), payment links, public quote/invoice pages.

Where Ded lives

One Discord channel. Lead cards, action buttons, daily digest.

EC · the assistant

It has a job, not a chat box.

The assistant reads incoming texts, drafts the reply, and asks Ded ✅ or ✏️. It mints payment links when jobs finish. It writes a morning digest of what needs attention. That's the loop.

Four narrow specialists (daily digest, intake triage, data extraction, propose-then-confirm ops) and a concierge that dispatches between them. Each one has a defined job and a cost ceiling. Approval gates are non-negotiable, even internally.

Hosted agents on a single approved approved model family. Reasoning, deep-research, and third-party models are out of scope for production code paths. Every AI decision is written to a provenance ledger. Every outbound send needs an explicit approval marker — missing or wrong → blocked + audit alert posted to ops Discord.

// pseudocode — the gate that stops accidents
sendCustomerMessage(to, body, {
  approved:     true,
  approvedBy:   "human",
  actor:        "assistant"
});
// no approval? → block + audit alert
Daily digest Intake triage Data extraction Propose-then-confirm Concierge dispatcher
EC · what's wired in

A handful of things pretending to be one.

Customers text in. Stripe collects. Discord is where Ded works. The website hosts quotes. The CRM in the middle holds it together.

Each integration is owned end-to-end — no Zapier in the loop. SMS comes in via Twilio, gets classified, opens or updates a lead. Quotes generate a public sharable link. Approval mints a Stripe payment link. Recurring services auto-create future invoices. Discord shows the rich card.

Each integration is a Worker route with signed webhooks (Twilio HMAC, Stripe signing secret, Discord ed25519). Idempotency keys on every external mutation. Customer-facing pages, owner dashboard, and the API each run on their own subdomain so blast radius is bounded per surface.

In
Twilio SMS
signed webhook → classifier → lead
Money
Stripe
deposits · payment links · recurring
Ops
Discord
buttons · digests · audit
▼ all routed through ▼
EC CRM
Cloudflare Worker + D1
Hono · ~70 migrations · ~1000 tests
MJ Beauty

A salon CRM that looks like nice stationery.

Maddie's salon. Same idea, built for hair instead of houses: appointments, services, hours, a dashboard that doesn't feel like a spreadsheet. Bookings will come in by Discord and text once those channels are turned on.

Appointment-centric, not project-centric. The dashboard is the centerpiece — designed so a non-technical owner can read her own numbers without anxiety. Anomaly detection on revenue and no-shows, weekly recap, service catalog. Booking automation comes online when Twilio and Discord are wired.

Same stack as EC (Workers + D1 + Hono) with a SvelteKit operator dashboard on Cloudflare Pages. Routes scaffolded for appointments, availability, booking requests, business hours, clients, services, stylists, salon ops, protection rules. Twilio/Discord webhooks scaffolded but inert until credentials provisioned. Honest about v1 status.

House style

Warm parchment, mauve accent, ink-on-paper. Anti-SaaS-blue on purpose.

Dashboard-first

SvelteKit operator app. Fast, calm, readable.

Booking next

Discord DMs + SMS once credentials are live.

MJ · the assistant

Trained on one salon, not "small business" in the abstract.

It speaks Maddie's vocabulary — services, regulars, no-shows — not generic small-business stuff. It'll book appointments, send reminders, and surface things like "Tuesday afternoons are 30% slower this month, want to run a promo?"

Per-business agent workspace: house style, service catalog, owner preferences, financial vocabulary all live in curated docs. Same approval gates as EC — nothing customer-facing sends without Maddie's ✅. Anomaly digests in plain English, not dashboards she has to interpret.

Per-business agent workspace lives in its own repo — curated docs only, no live secrets. Same runtime as EC but isolated: MJ's agent can't see EC data and vice versa. Cross-business contamination would be a product bug. Same model policy inherited from the shared rule.

House style aware Service catalog aware Financial concierge No customer send without ✅
Both businesses share the engine

Same brain, hard walls.

Same engine powers both — but they're walled off from each other. A problem at one doesn't leak to the other. Like one factory making two different cars.

Shared runtime, shared safety rails, shared engineering practices. Data, secrets, Discord channels, and customer surfaces are siloed per business. Mostly: same pattern, different businesses.

Shared agent runtime hosts both. Each business gets its own repo, agent workspace, Cloudflare project, database, Discord surface, and model deployment if needed. Cross-business messages require an explicit named target — there's no shared bus an agent could accidentally fan out to.

Shared

Agent runtime · approval gates · CI patterns · model rules · safety review process.

Siloed

Data · secrets · Discord channels · customer surfaces · model context · audit logs.

What's under the hood

The whole stack on one slide.

All the moving parts, grouped by what they do. Most of these are normal tools that startups use — nothing exotic. The "complicated" part is wiring them together so they behave like one system.

Everything is off-the-shelf except the CRMs themselves. No custom infra, no Kubernetes, no servers to babysit. Cloudflare runs the code, the data, and the static sites — one bill, one dashboard.

Deliberately boring stack. Edge runtime (Workers) instead of containers; embedded SQL (D1) instead of managed Postgres; static asset hosting (Pages) instead of a Next.js server. Trade-off: some platform lock-in to Cloudflare, in exchange for ~$0/mo at this scale and zero ops work.

Runs the code

Cloudflare Workers · Hono · TypeScript

The API for each business. Same language, same framework, both sides.

Stores the data

Cloudflare D1 (SQLite)

One database per business. Migrations versioned in git. Honest, small, fast.

Hosts the pages

Cloudflare Pages · SvelteKit (MJ) · React/Vite (EC)

Public quote pages, owner dashboards, this very deck.

Money

Stripe

Payment links, deposits, recurring invoices, webhooks.

Customer SMS

Twilio

Inbound webhooks (signed), outbound through the approval gate.

Owner ops

Discord (bot + interactions)

Lead cards with buttons, daily digests, audit alerts.

The assistant

Hosted agents on a single approved model family

Custom-built per business. Other models out of scope for production.

Glue / runtime

Internal agent runtime · Node · TypeScript

Runs the assistant, routes messages between channels, holds the safety rails.

Engineering hygiene

GitHub · vitest · CI checks · wrangler

~1000 tests gating every PR on EC. Deploys are one command.

The safety thing

Why this doesn't blow up.

The number one rule: the AI never sends anything to a customer without a human tap to approve. It can draft, propose, prepare — the human always holds the trigger.

Three layers. (1) The autonomous send queue at the OS level is physically disabled. (2) Every send function requires an approval check saying who approved it. (3) Customer-facing messages get a propose→approve UI in Discord with ✅/✏️/❌. Internal sends are audited too. Wrong approval = block + alert.

(1) The autonomous-send process at the OS level is renamed-out so nothing can run it. (2) Every send function requires an explicit approval marker at the call site. (3) Agent-initiated customer sends post a proposal that writes a pending row and a Discord embed with action buttons; approval transitions state atomically and expires after 24 hours.

OS

Autonomous queue physically disabled. No background process can mint sends.

App

Approval check required at every send site. Audit on miss.

Human

Discord ✅/✏️/❌ on every customer message. 24h expiry. Atomic state.

That's the tour

Ask me anything.

Slide the depth control on any earlier slide if you want the technical version. / to flip back.