04 · AI & Real Estate

Unblocking a real-estate marketing SaaS, then shipping its second life.

Three weeks from handover to live. Five months of engagement after that, six tools across four marketing surfaces shipped. I joined the RealClear build through Zeroic to fix the API, Stripe and subscription layer that had stalled the launch; the work expanded as the product grew.

RealClear app dashboard showing the catalog of AI marketing tools (LinkedIn, Facebook, Instagram, Email, Real Estate Listing, Review Responder) next to the signup screen

A SaaS that needed someone to finish it

RealClear was an AI marketing platform built for real estate agents who wanted to produce listing copy, social posts, and review responses without learning how to write prompts for ChatGPT. The user picks a tool, answers a structured questionnaire about the property and the tone, and the platform writes the marketing content. Six tools across listings, social, blogging, and branding. Free, Standard, and Pro tiers.

The build started inside Zeroic, the agency I was contracting through, and stalled before launch. The integration layer between Bubble.io, the LLM providers, and Stripe was not fully wired. Subscriptions were unreliable. The free-tier and free-trial logic had gaps. The team needed someone to take the project the rest of the way to a live deploy and then keep shipping as new requirements landed.

I joined as the lead Bubble.io engineer on the project. The brief from Zeroic was small at first: fix the API integrations, get Stripe stable, and ship. The brief from the client, once we were live, grew from there.

The RealClear dashboard showing a grid of AI marketing tools (LinkedIn Thought Leadership, Facebook Content Generator, Email Newsletter Creator, Instagram Caption Generator, Real Estate Listing, Review Responder) next to the Signup screen

The catalog the user sees on first sign-in. Six tools, four marketing surfaces, one shared questionnaire engine underneath.

What was scoped to me

The work split cleanly into three buckets. I owned them end to end across the five-month engagement:

  1. AI tools for Free, Standard, and Pro tiers. Build the six marketing tools, gate each one by plan, and make the prompt configuration data-driven so the founders could tune output quality without redeploying. The questionnaire-to-prompt mapping ran through OpenAI for the default model and OpenRouter for the alternates, so plan upgrades unlocked richer model choices.
  2. The billing and subscription layer. Stripe checkout, upgrades, downgrades, free trial, free tier, and the edge cases (paused subscriptions, mid-cycle plan changes, failed cards, refund handling). The version I inherited had the happy path working and most of the unhappy paths broken.
  3. Onboarding and the AI Training flow. A guided first-run for independent agents that captured brokerage affiliation, team vs. independent status, and brand voice samples so the AI tools generated copy aligned to the agent's style from message one.

The work was Bubble.io-first, with the LLM providers and Stripe accessed through the API Connector. No separate backend, no orchestration layer outside Bubble.

The onboarding flow inside RealClear, showing brokerage affiliation and team-vs-independent questions on a progress-tracked wizard with the AI Training section visible in the sidebar

The onboarding flow that fed the AI Training layer. The questions seeded a per-agent style profile so the tools did not start from a generic baseline.

The first three weeks: unblock and ship

The first deploy was the bottleneck and the first proof of value. I scoped the initial sprint tightly: stop building new features, finish the ones that were 80 percent done, and get the app into production with paying customers using it.

The work in shape:

  • API Connector calls cleaned up so every LLM request had retry and timeout handling, not just the happy-path response handler.
  • Stripe checkout and subscription webhooks rewritten so plan state on a Bubble user record always matched Stripe’s source of truth, even when the user upgraded mid-cycle or a card declined on renewal.
  • Free-tier and free-trial logic consolidated into the plan-gate stack (Option Set + entitlements data type + Privacy Rules + reusable element + workflow Only when conditions) so the same checks fired everywhere that mattered, instead of being duplicated per page.
  • Deploy itself: production environment provisioning, domain wiring, the live smoke pass.

Three weeks from handover to a live, billable app. The client did the launch. The team kept shipping.

Plan gating as a layer, not a sprinkle.

The version I inherited had plan checks scattered across pages and workflows. Same logic, slightly different shape every time, drifting out of sync as new tools were added. The rewrite folded the checks into a stack that ran from the database up to the UI.

An Option Set named the three plans (Free, Standard, Pro). A separate data type held the tool entitlements per plan, joined to the Option Set by a relation field, so updating a plan’s tool list was a row edit instead of a code change. Privacy Rules on the Tool data type enforced read access at the database layer. Conditional Visibility on the tool cards and page elements handled the client-side state. Reusable elements with Custom Events wrapped the gated actions so every entry point fired the same check. Workflow Only when conditions caught the rest at the backend-trigger level.

The point is not any one construct. The point is that every entry point (a tool card, a workflow, a backend run) read from the same source of truth instead of reimplementing the check. Boring infrastructure that decides whether a paywall holds under traffic, and almost never gets retrofitted cleanly once a product is live.

The RealClear Social Media tool sub-catalog showing LinkedIn Thought Leadership, Facebook Content Generator, Instagram Caption Generator, and Email Newsletter Creator cards, each carrying a Pro badge that gates the tool by plan

The plan-gate, visible. Pro badges on every card in the Social Media sub-catalog. The badge is one Conditional Visibility check away from the entitlements table that sits under the whole stack.

Two LLM providers, one prompt surface.

The product defaulted to OpenAI for content generation and used OpenRouter for the alternate model choices that came with higher tiers. The same prompt template fed both, with the provider chosen at call time based on the user’s plan. Cost was a real constraint for the founders, so the architecture had to let them swap or downshift models without touching the questionnaire UX.

The split kept the door open: a model that got cheaper or better next quarter could slot in by changing one configuration row, not a deploy.

Stripe subscription edge cases as first-class workflows.

The unhappy paths got their own backend workflows. Mid-cycle plan upgrades that prorate correctly. Downgrades that take effect at the next renewal. Failed-card retries that pause the plan instead of silently dropping the user back to Free. Refunds that emit the right event back to the app.

I cannot share the specifics of what was broken when I joined under the NDA terms with Zeroic. I can say the post-launch Stripe support load went to roughly zero, which is the only metric that matters for a billing layer.

Streaming, via a plugin, because Bubble didn't ship it natively.

LLM responses for marketing copy feel slow if the user stares at a spinner while the model generates 300 words. Streaming, where the text appears token by token as the model writes it, makes the wait feel like the model is thinking with the user instead of at them. Bubble.io’s API Connector at the time did not support streaming responses; calls were treated as request-response, with the workflow blocking until the full body came back.

The workaround was a third-party streaming plugin from the Bubble marketplace. It opened the connection to the LLM provider, surfaced the token stream into a Bubble custom state, and let the page render the partial text as it arrived. Not elegant, but the experience went from “wait twenty seconds” to “watch the copy write itself.” A small UX choice that changed how the product felt to use.

The five-month scope

The first deploy was the start, not the end. As the product reached real users the founders had new requirements every couple of weeks: tightening the prompt configuration so the AI Training feedback actually fed back into output quality, building the onboarding wizard, adding the “time saved” counter in the sidebar so the user could see the value the product was creating, hardening the live deploy against the edge cases real customers found.

I stayed on the project for five months total, shipping iteratively against the Zeroic-client backlog. The cadence was small commits, frequent deploys, and tight feedback loops with the Zeroic team and the client.

What changed

First deploy 3 wk from handover to live
Engagement 5 mo via Zeroic
Tools shipped 6 across 4 marketing surfaces

The product is no longer live. The marketing site at realclear.ai is archived; the app at app.realclear.ai has been retired. The work shipped, the launch held, the post-launch billing layer carried the load. The decision to close the product came later and was the founders’ call, not a reflection of the engineering.

The pattern of the engagement is the part I would do again. Walk into a stuck project, scope the smallest unlock that gets to a live deploy, stabilize the boring infrastructure first, then keep shipping until the requirements stop arriving. Three weeks to value, five months to graduation.