Adding AI features to an existing SaaS without a rewrite
How to add AI features to an existing SaaS without a rewrite: a clear service boundary, tenant-scoped data, per-tenant rollout and humans confirming changes.
By Hamza Ghouri
Plenty of founders thinking about AI already have a product. It works, customers pay for it, and the question is how to add AI features to an existing SaaS without a rewrite or a risky big-bang release. The good news is that you rarely need to touch the core. Recently I added an in-app AI assistant to a multi-tenant vehicle reconditioning platform (the Recond Flutter app), and I work on a compliance and risk platform where an AI analyst proposes conclusions for people to accept. In both, the AI sits on top of a platform that already has its own data, tenants and permissions. Here is the approach I'd use.
Treat AI as a service boundary
The first decision is where the AI lives. My answer: behind a boundary, as a client of your existing system with the same rules as any other client.
In practice that means:
- The AI reads through your existing data layer. It calls the same services or repository functions your API uses, so tenant scoping, soft deletes and permissions apply automatically. It never gets its own database connection with broader access.
- The AI writes through your existing commands. If the assistant creates a record, it goes through the same validation and business logic as the "Create" button. No side doors.
- The model call is isolated. One module owns prompts, the model API and timeouts. The rest of the app calls a function and gets a result or a clear failure.
This is what makes "without a rewrite" possible. Your domain model, your auth and your audit trail stay exactly where they are. The AI feature is a new consumer of them.
Multi-tenancy is the first thing to get right
On a multi-tenant platform, the worst AI bug is cross-tenant leakage: one customer's data showing up in another customer's prompt or answer. The model has no idea what a tenant is, so isolation has to be enforced before anything reaches it.
Rules I'd hold to:
- Resolve the tenant from the authenticated session, never from anything the model or the user's message says.
- Filter every lookup by tenant in the query itself.
- Keep caches, embeddings and conversation history scoped by tenant id in their keys or rows.
- Check permissions before work starts. On the compliance platform, an agent permission gate runs before the database transaction opens, so a request the user is not allowed to make never gets as far as touching data.
If your platform already has these patterns (and a mature multi-tenant SaaS usually does), reuse them. I wrote more about the underlying design in multi-tenant SaaS architecture lessons.
Let people confirm what the AI changes
The fastest way to lose trust in a new AI feature is to have it change data on its own. Both products follow the same principle: the AI proposes, a person decides.
In the Recond assistant, when the agent wants to create a record it renders a create card, and the user confirms or cancels it. A cancelled card stays cancelled, so a later message cannot quietly revive it. On the compliance platform, the AI analyst reads key risk indicator (KRI) breaches and drafts reassessment conclusions, and a person accepts them before they count.
That pattern costs very little to build and buys a lot: users can try the feature without fear, and the AI can be wrong occasionally without causing damage. More on designing those flows in human-in-the-loop AI.
Fit the AI into the existing UI
An assistant bolted on as a separate chat page tends to go unused. One that understands the app's own objects gets used. Some of what went into the Recond assistant:
- Replies stream in, and the UI shows what the agent is doing while it works, so a few seconds of tool calls never look like a frozen screen.
- The streamed reply is paced so it reads as typing instead of arriving in bursts.
- Answers render the app's own records as detail, state and list cards, each with an Open button that jumps to the record.
- Follow-up suggestion chips sit above the composer, and messages have timestamps and search.
Those details matter because they connect the AI back to the screens people already know.
Roll it out gradually, behind a boundary you control
Here is how I'd structure the endpoint for a new AI feature in an existing Express backend: tenant from the session, an availability check per tenant, data loaded through tenant-scoped queries, a hard timeout, and a clean failure the UI can handle.
import express from "express";
import { Pool } from "pg";
const pool = new Pool();
const app = express();
app.use(express.json());
declare function callModel(input: string, signal: AbortSignal): Promise<string>;
app.post("/api/records/:id/summary", async (req, res) => {
const tenantId: string = res.locals.tenantId; // set by the existing auth middleware
try {
const flag = await pool.query(
"SELECT 1 FROM tenant_features WHERE tenant_id = $1 AND feature = 'ai_summary' AND enabled",
[tenantId]
);
if (flag.rowCount === 0) return res.status(404).end();
const record = await pool.query(
"SELECT id, title, notes FROM records WHERE id = $1 AND tenant_id = $2",
[req.params.id, tenantId]
);
if (record.rowCount === 0) return res.status(404).end();
const draft = await callModel(JSON.stringify(record.rows[0]), AbortSignal.timeout(20_000));
res.json({ status: "proposed", draft });
} catch {
res.status(503).json({ status: "unavailable" });
}
});
A per-tenant switch lets you enable the feature for one friendly customer, watch it, and widen the rollout. It also gives you an off switch that does not need a deploy. A few more habits:
- Protect the API. Model calls are slow and expensive, so rate-limit AI endpoints per tenant or user. The compliance platform rate-limits its API in Nginx at a level the app can sustain.
- Move slow work off the request. Bulk summaries or document analysis belong in a background job with a status the UI can poll or stream.
- Spec it first. The Recond assistant was built spec-first, with numbered specs and amendments as it grew. AI features change shape quickly, and a written spec keeps the team aligned on what "done" means.
Where I'd start
Pick one workflow where users already do repetitive reading or drafting, and add AI there as a proposal they confirm. Route it through your existing data layer and permissions, scope everything by tenant, put it behind a per-tenant switch and a timeout, and widen the rollout as it proves itself. If you have a SaaS and want a feature like this scoped, take a look at my services.