Skip to content
Get in touch

Case study · Heavy-equipment manufacturing

Migrating a business-critical manufacturing app from Lovable to an enterprise-grade platform, with zero downtime

A manufacturer's team built a prototype in Lovable that became the production-floor system every crew depends on. Our engineers moved it to a new API backend on Azure with Microsoft sign-in, kept the UI people knew, and switched over with zero downtime after weeks of shadow running.

Illustration: an assembly line with work orders moving through production stations
  1. 01 · Context and stakes

    The client is a US manufacturer of large machinery: heavy equipment with engine, mechanical and electrical systems, and the logistics to deliver it. They run a few factories with a couple of hundred people on the floor, on revenue above $100M a year, and the MES has hundreds of daily users.

    No off-the-shelf manufacturing execution system (MES) fit how they build, so their team built a prototype in Lovable, an AI app builder, with a React front end and a Supabase backend. It went into production, and every crew and manager came to rely on it daily.

    The prototype did its job, then outgrew its platform. The app became hard to change safely, had no architecture the client's IT could own, was not built for production security, and used password sign-in. It ran fine until it didn't, and the client decided to migrate.

    When the MES is down, crews lose their work orders and managers lose sight of production. The whole migration cost less than the business would lose in a short outage of the MES. That was the real comparison: not migration against doing nothing, but migration against the next failure.

  2. 02 · Constraints

    • Nothing could change for the floor. People knew the screens; a new UI meant retraining across a few factories.
    • The system had to stay up throughout.
    • Development could not stop. The client team kept fixing bugs and shipping small features in Lovable while we worked.
    • It had to fit the client's Microsoft environment, from sign-in to where the data lives.
  3. 03 · Architecture

    Before: the React app generated in Lovable, calling a Supabase project (Postgres, password auth, server functions) directly from the browser.

    After: the same React UI, talking to a proper API instead of the database. The API is a Next.js server running as a containerized web app on Azure App Service (Web App for Containers), with Prisma over a managed Azure SQL database. The Supabase functions became API endpoints, and sign-in moved to Microsoft Entra ID. Azure DevOps pipelines build, test and deploy every change, and the system runs with high availability and backups.

    Before: prototype platform

    1. Browser

      • React app

        Generated in Lovable

      Down to Supabase, via: Password sign-in, database calls from the browser

    2. Supabase

      • Postgres

      • Auth

      • Server functions

    After: Azure, Microsoft sign-in

    1. Browser

      • React UI

        The same UI as before

      Down to API, via: Microsoft Entra ID single sign-on

    2. API

      • Next.js server

        Container on Azure App Service. Role check on every endpoint.

      Down to Data, via: Prisma

    3. Data

      • Azure SQLManaged

        High availability, automated backups

    After: reporting

    1. Product manager

      • Claude

        With a reporting skill

      Down to Access.

    2. Access

      • MCP serverRead-only

        Authorization, roles, query validation

      Down to Data.

    3. Data

      • Azure SQL

        The same database as the app

    During the migration: code

    1. Source

      • Lovable code

      Down to Migration.

    2. Migration

      • Migration tool

        Run by our engineers, with coordinated AI agents, skills and PRDs

      Down to Checks, in order.

    3. Checks, in order

      • Pull request

      • Tests

      • Engineer review

      Down to Release.

    4. Release

      • Azure DevOps pipeline

        Deploy

    During the migration: data

    1. From

      • Supabase

        Prototype data

      Down to To, via: One-way sync script

    2. To

      • Azure SQL

    The prototype platform before, the Azure platform after (app and reporting), and how code and data moved across during the migration.
  4. 04 · Decisions

    1. Keep the UI exactly as it was

      Considered
      A redesign during the rebuild; keeping the React UI.
      Chose
      The same React UI, with every change behind it.
      Why
      Crews across a few factories knew the screens. No retraining, and a cutover the floor would not notice.
      Trade-off
      We inherited front-end structure we would have designed differently. UI improvements became a separate, later decision.
    2. A repeatable migration tool, not a manual rewrite

      Considered
      Freezing Lovable and rewriting by hand; unsupervised AI agents; a tool our engineers operate, with coordinated agents and reviewed output.
      Chose
      A hybrid tool run by our engineers: coordinated AI agents rewrite from our PRDs and skills, and engineers review every pull request.
      Why
      Development in Lovable could not stop. A tool can rerun on every change the client team made; a one-off rewrite cannot.
      Trade-off
      The tool, PRDs and skills had to exist before the first migrated screen, and every output still needs an engineer's review.
    3. One-way mirror, then a single cutover

      Considered
      Two-way sync with a gradual move; factory-by-factory phases; a one-way mirror and one hard switch.
      Chose
      One-way sync from Supabase into Azure SQL during a couple of weeks of shadowing, then one big-bang cutover.
      Why
      Two-way sync between two different databases is where records get lost or duplicated. One direction kept a single source of truth until the switch.
      Trade-off
      Everything rode on one switch, and going back afterwards would mean reconciling data written in the new system.
    4. Azure, Azure SQL and Entra ID, to match the Microsoft environment

      Considered
      Moving Supabase to a self-managed setup; Postgres on another cloud; the client's own Microsoft stack.
      Chose
      A Next.js API in containers on Azure App Service, Prisma over managed Azure SQL, Entra ID single sign-on and Azure DevOps pipelines.
      Why
      People already have Microsoft work accounts, so access follows the client's own accounts and their IT runs familiar tools.
      Trade-off
      Postgres to SQL Server meant translating the schema and queries, and replacing what Supabase gave for free, such as built-in auth.
    5. An MCP server to replace live-data prompting

      Considered
      Dropping it; fixed dashboards; direct database access for Claude; a governed MCP server.
      Chose
      An MCP server on the new system, with a reporting skill, query validation, authorization and role-based access.
      Why
      Dashboards answer only the questions someone predicted, and direct database access would undo the security work.
      Trade-off
      The skill and validation rules need upkeep as the data model changes, and numbers that matter still get checked by a person.
  5. 05 · Security

    • Microsoft Entra ID single sign-on

      Replaces in-app passwords. Access follows the client's own work accounts.

    • Role-based access on the server

      Every API endpoint checks the caller's role; the UI is not the enforcement point.

    • No database access from the browser

      The front end talks only to the API.

    • Guarded MCP server

      Read-only: a tool for reading and digesting data, never changing it. Authorized users only, the same roles as the app, and every query validated before it runs.

    • Azure DevOps CI/CD with automated tests

      Every change, including each migration-tool pull request, is tested and reviewed before deploy.

    • Secrets kept out of the code

      Injected per environment, never stored in the repository.

    • High availability and backups

      Azure SQL with high availability and automated, point-in-time backups.

  6. 06 · Delivery

    1. Eject and design. We took the React code out of Lovable into a normal Git repository. Our engineers designed the target first: API, SQL Server data model, roles, and how the existing UI would call it.

    2. A migration tool, not a one-off rewrite. We built a hybrid migration tool for our engineers to operate. They run it, choose what to migrate next and steer it. Inside, a team of AI agents coordinates the work, splitting it up, rewriting the ejected code from PRDs and skills our engineers wrote, and checking each other's output: database calls become API calls, server functions become endpoints, password sign-in becomes Entra ID. Each result lands as a pull request, runs the tests and is reviewed by an engineer before it merges. The agents write code; our engineers own the system.

    3. Shadow running. For a couple of weeks the new system shadowed the live Lovable app. A sync script mirrored data one way, from Supabase into Azure SQL, so the new system could be checked against the old one on current production data. The client team kept working in Lovable, and the tool carried each fix and small feature across.

    4. One cutover, zero downtime. The final data mirror ran beforehand. The cutover itself was a rollout of the new system and a domain switch: people signed in with their Microsoft accounts and kept working, with no downtime. At no point did both systems take writes. We also had a rollback plan, which we never needed: inside the Lovable app we built backend endpoints that could both export data and ingest it, so any records written in the new system could have been restored to Lovable if we had to switch back.

    5. Restoring lost insight. In Lovable, the product manager could prompt against live data for reports, feature adoption and business metrics. Risky but useful, and the migration took it away. We built an MCP server on the new system with a skill that teaches Claude the data model. He now does his reporting in Claude, under proper access controls.

    The system is now in maintenance mode.

  7. 07 · Results

    • Changes the floor had to learn

      at cutover

      None: same screens, same workflows

    • Sign-in

      since cutover

      Before: Passwords in the appAfter: Microsoft Entra ID single sign-on

    • Backend

      since cutover

      Before: Supabase, on the prototype platformAfter: Next.js API on Azure App Service, Prisma, managed Azure SQL

    • Release path

      since cutover

      Before: Publish from the prototype platformAfter: Azure DevOps pipelines with automated tests and review

    • Downtime at cutover

      at cutover

      None: rollout and domain switch after a couple of weeks of shadow running

    • Ad-hoc reporting on live data

      since the MCP server shipped

      Before: Prompting the prototype directlyAfter: Claude via an MCP server with role checks and query validation

    • The whole migration, 3 engineers over 3 months, cost less than the business would lose in a short outage of the MES.
    • Bug fixes and small features made in Lovable during the migration were carried into the new system, so the client never had to freeze development.
    • The system is now in maintenance mode on infrastructure the client's IT can operate.
    • The product manager does his reporting in Claude, inside the same access rules as the app.
  8. 08 · Team

    3 Blackbird engineers, working with the client's product team, who built the original prototype and own the product.

    Who owned what: we owned the architecture, the migration tool, the new backend, the pipelines, the cutover and the MCP server. The client owned the product and every change made in Lovable along the way.

    What we'd do differently

    Not much. If we ran it again, we'd give the migration tool more agents and more compute from day one, so more of the rewrite runs in parallel while our engineers review each pull request.

10 Start

Have a similar problem? Let's talk about how.

Tell us what you're working on. We'll tell you honestly whether we're the right team for it.