Mesrai
All use cases
Use case · Legacy Codebases

Change legacy code without fear.

In a ten-year-old codebase, the riskiest part of a change is the code you didn't touch. Mesrai maps how changed code is used across the repository, so refactors and migrations don't break forgotten callers.

Context
Callers across repo
Migrations
Deprecation rules
Noise
Focus on changed code

How teams maintaining legacy code use AI code review

Teams maintaining legacy codebases use AI code review to make changes safer: Mesrai's repository graph finds callers and dependents of the code being changed, flags refactors that alter behaviour, and enforces migration rules such as 'no new code may use the old ORM'. Rules can be scoped to new or changed code, so legacy files aren't flooded with comments.

I.

Why legacy code is hard to change

  • 01

    Nobody knows every caller; the original authors have left.

  • 02

    Tests are thin, so reviewers are the main safety net.

  • 03

    Refactors that look mechanical can change behaviour — ordering, null handling, side effects.

  • 04

    Migrations stall because new code keeps using the old patterns.

II.

How Mesrai helps with legacy code

Caller awareness

See which modules, jobs and endpoints depend on the function you changed.

Behaviour-change detection

Flags refactors that change semantics — swapped conditions, lost side effects, different null handling.

Migration rules

Mark old libraries and patterns as deprecated so new code moves to the replacement.

Noise control

Review only what changed and cap suggestions, so old code doesn't bury the important findings.

III.

Real-world scenarios

2 examples

Illustrative examples of the kind of change teams maintaining legacy code make every week, and the review comment Mesrai would post.

Scenario 01

The refactor that changed behaviour

A cleanup PR converts a callback-based function to async/await.

src/legacy/billing/close-period.ts
invoices.forEach(async (invoice) => {
  await finalize(invoice);
});
await markPeriodClosed(periodId);
MesraiBug agentMUST_FIX

forEach doesn't wait for async callbacks, so markPeriodClosed runs before invoices are finalized — the old version finalized them first. Use for...of or await Promise.all(invoices.map(finalize)).

Result: A 'harmless' modernisation doesn't close billing periods with unfinalised invoices.

Scenario 02

New code on the old ORM

A feature in a half-migrated codebase adds queries with the legacy data-access layer.

MesraiMesrai RulesSUGGESTION

Rule 'ORM migration': new queries must use Prisma (src/db/client.ts). LegacyDAO is deprecated and scheduled for removal in Q3.

Result: The migration stops going backwards with every new feature.

IV.

Set up for a legacy codebase

Start conservative: high-severity findings only, then widen as trust grows.

  1. 1

    Set severity filters to show high and critical findings first.

  2. 2

    Add deprecation rules for the libraries and patterns you're migrating away from.

  3. 3

    Add memories describing fragile areas ('the billing module assumes invoices are finalized in order').

  4. 4

    Pair big refactors with characterisation tests, and review them in small pull requests.

V.

What teams achieve

Safer refactors and migrations

Forgotten callers surfaced before merge

Migrations that move forward

Useful findings without legacy noise

VI.

Legacy Codebases — frequently asked

2 questions
  • Will AI code review flood our legacy code with comments?

    +

    Not if configured for it: Mesrai reviews the changed code, and severity filters and suggestion limits keep comments to what matters.

  • How does Mesrai know who calls a function?

    +

    It builds a repository graph from the syntax tree, mapping imports and call sites across the codebase.

Try it on your next pull request.

14-day free trial · every feature unlocked · no credit card required.

Start free