Written by

Clinovera
Article Clinovera · 2 hr ago 10m read

Proven AI — Modernizing Legacy Systems With AI Coding AgentsContestant

Many organizations that operate systems built on legacy technology stacks are facing significant support and maintenance complexities. They are eager to modernize, but the transition is usually prohibitively complex and expensive. These challenges apply to virtually any legacy tech, while InterSystems-based systems have their own unique nuances.

Key modernization challenges include:

  • Refactoring massive amounts of code, including identifying and removing obsolete "dead code."
  • Managing complex business logic accumulated organically over decades.
  • Decoupling mixed business, presentation, and data layers into separate, isolated tiers.
  • A lack of comprehensive technical and business documentation.
  • Shortage of engineering resources familiar with legacy technologies and internal system architecture.

The talent shortage is especially severe for InterSystems applications, as the pool of qualified developers — particularly those familiar with older versions — is quite small.

Modernization costs can be so high that organizations consider full rewrites or acquiring third-party software, both of which carry significant risks and expenses.

For many InterSystems applications, such a transition also means moving away from the InterSystems stack to more mainstream technologies with larger talent pools.

In this submission, using a large CSP application developed over 20 years ago as a reference, we demonstrate how AI coding assistants, applied through a disciplined engineering methodology, can dramatically reduce refactoring effort and the need for niche InterSystems expertise.

All artifacts for this submission — including the full source code for both the original legacy application and the modernized version — are available for inspection, installation, and side-by-side comparison.

Outcomes — Reference vs. Practical

In this submission, we achieved 100% automated refactoring and modernization of a legacy application using AI coding agents. We also generated all technical and business documentation directly from the source code. While this level of automation is rare in practice, it demonstrates the capabilities of AI coding agents, our tools, and methodology. Typically, full automation is limited by several factors:

  • AI agents can make errors or produce sub-optimal code that requires human oversight.
  • Most projects require functional enhancements, performance tuning, or workflow updates rather than a simple one-to-one migration.
  • Many legacy systems require data model refactoring, schema changes, and complex data migrations.
  • Real-world modernization demands rigorous testing and comprehensive issue resolution.

On typical client modernization projects, we achieve 60–80% AI-driven automation. This still represents a massive improvement over traditional manual processes, often compressing timelines from years to just a few weeks.

Application Details

For this submission, we selected OnFORME (Online Feedback Organization, Requesting and Monitoring for Educators) — an open-source educational software application developed at MIT by Benjamin Spead in 2003–2004 as part of his master's thesis. It was designed to help educators quickly author and publish web-based feedback tools, such as surveys, for students.

We selected it for the following reasons:

  • It is a legacy Caché/CSP application
  • While using older technology, it is a well-written application, with a good quality data model that can be retained and exposed to the front end via the newly implemented API layer.
  • It is large (approximately 17,000 lines of CSP and ObjectScript code), fully functional, and was used in production for a number of years.
  • It is self-contained and easy to install and test by anyone interested in our submission.
  • It has very extensive technical and business documentation — allowing direct comparison with the documentation we produced as part of this submission using our AI-augmented methodology.

Highlights of Our Work for This Submission

  • The application was fully refactored, migrated to IRIS, and transitioned to a modern three-tier stack — React 19 + TypeScript SPA, JSON REST API on %CSP.REST, and the unchanged IRIS data tier.
  • The work was done by an engineer with significant AI expertise but zero knowledge of InterSystems technologies. No manual coding was involved.
  • Most of the functionality of the original application is present in the modernized version, except for a small set of peripheral authoring features.
  • The front-end was significantly reworked and visually improved while preserving the original functionality and workflow.
  • All presentation logic was moved out of CSP and into the front-end; a clean data access layer and a new REST API were authored using our AI-augmented engineering process (see Architecture and Metrics table below).
  • We reverse-engineered the legacy code into a new business specification and technical documentation describing the future state of the application.
  • End-to-end work — from downloading and installing the legacy application to testing and deploying the modernized system — was completed by a single engineer in a few days. Equivalent modernization without usage of AI coding agents would span over many months.

What Was Refactored and What Was Not

We kept the data tier intact and modernized the layers above it. The IRIS database, persistent class hierarchy, SQL access, and authentication model all remain unchanged. We rewrote the layers above the data tier—replacing embedded CSP presentation and legacy business logic with a clean three-tier architecture. This includes a React single-page application and a JSON REST API, all still hosted within IRIS.

After migration from Caché, we took advantage of IRIS’s first-class modern application platform capabilities — REST dispatcher, web app host, SQL engine, scheduled task runner. The modernized application ships from a single Docker image built on intersystemsdc/iris-community, with both the legacy UI and the modern UI reachable side-by-side during the cutover window.

Legacy CSP pages remain available at /feedback, while the new app serves from /app. Both interfaces read and write to the same persistent classes, ensuring data consistency throughout the process.

Then vs. Now — Architecture and Metrics

The table below compares the legacy and modernized application across architecture, technology, and code-volume dimensions. Code-volume figures count source lines committed to the repository (including markup, configuration, and class definitions).

Dimension

Legacy (Caché, ~2003)

Modernized (IRIS, 2026)

Architecture style

Two-tier; presentation, business logic, and data access intermixed in CSP pages and persistent classes

Clean three-tier separation: SPA → REST API → service layer → persistent classes

Presentation tier

50 CSP pages with embedded ObjectScript blocks (<script language="cache" runat="server">)

React 19 + TypeScript single-page application, Chakra UI v3, Jotai state, React Router 7

Presentation LOC

~11,700 lines of CSP markup + embedded ObjectScript

~17,000 lines of TypeScript across 38 routed pages and 20 shared components

API / business tier

None — business logic embedded directly in CSP pages and persistent class methods

%CSP.REST dispatcher with 18 resource classes and 19 pure service classes exposing 129 REST routes (~12,400 LOC)

Data tier (persistent classes)

47 persistent classes (~5,700 LOC) defining the domain model

Unchanged — same 47 persistent classes, accessed by both UIs

Authentication

Session-cookie auth via the CSPSuperPage.OnPreHTTP code generator, with credentials checked against Feedback.Person

Stateless JWT bearer authentication (HS256) implemented entirely within IRIS using its native cryptography primitives; backward-compatible with the existing Feedback.Person credentials so both UIs share one identity model

Authorization model

Feedback.Person.AccessLevel calculated from Roles (Student=1, Instructor=2, Manager=4, Administrator=6, SuperUser=8)

Same six-level ladder, enforced consistently in three places: API RequireMinAccess, frontend <ProtectedRoute>, and sidebar visibility

Routing

Direct CSP file URLs; per-page AccessLevel parameter checked by base class

Frontend client-side routing; backend dispatcher with declarative UrlMap

Front-end interactivity

Server round-trip per action; <CSP:IF> conditional rendering

Client-side reactivity, optimistic updates, no full page reloads

Data exchange format

HTML rendered server-side; form posts

JSON over HTTPS; typed TypeScript clients in web/src/api/

Build / package

Class files compiled in-place inside IRIS

Two-stage Docker build: node:20-alpine builds the SPA bundle, intersystemsdc/iris-community imports classes and serves the bundle

Deployment

Manual install scripts, namespace setup

Single docker build && docker run produces a complete environment in minutes

Documentation

~70-page MIT thesis + installation guide (human-authored over months)

Business specification and technical documentation reverse-engineered from the legacy code in hours, using our AI-augmented methodology

Engineering profile required

Caché ObjectScript, CSP, IRIS internals — a niche, shrinking talent pool

Mainstream React/TypeScript skills for the bulk of the work; minimal IRIS-specific knowledge confined to the API and service classes

 

A few totals worth highlighting from the figures above:

  • Code that stayed on InterSystems and was not rewritten: ~5,700 lines of persistent class definitions — the application's actual domain model. Everything above the data tier was rebuilt from scratch.
  • New code authored for the modern stack: ~29,000 lines (~17,000 TypeScript + ~12,400 ObjectScript) producing 38 user-facing pages and 129 REST endpoints, all delivered through our AI-augmented engineering process.
  • Net effect: the InterSystems-specific surface area an engineer must understand to maintain or extend this application shrank from the entire ~17,000-line legacy codebase to roughly 12,400 lines of well-structured API and service classes — and even that surface uses idiomatic patterns familiar to any REST/service-tier developer.

Methodology For Legacy Application Refactoring And Modernization

Our approach combines AI coding agents with a structured engineering methodology refined across modernization engagements. At a high level, the work proceeds through five phases:

  1. Discovery and reverse engineering. AI-assisted analysis of the legacy codebase produces a future-state business specification that captures intended behavior independent of the legacy implementation.
  2. Target architecture design. A clean blueprint is defined — what stays on InterSystems, what gets rebuilt, and how the two coexist during cutover. Our standard pattern keeps the IRIS data tier intact and rebuilds the layers above it.
  3. Parallel scaffolding. The modern stack is stood up alongside the frozen legacy application, sharing the same IRIS database. Both UIs remain reachable side-by-side throughout the process, making functional comparison and incremental cutover straightforward.
  4. AI-augmented authoring under expert direction. The new API, service classes, and front-end are produced from the specification, working against the existing persistent classes. This phase delivers most of the code volume.
  5. Side-by-side verification and phased cutover. Functional behavior is compared between the legacy and modernized UIs running on the shared data tier, regressions are caught early, and cutover is sequenced to the customer's risk tolerance.

The phases are deliberately described at a high level. The specifics of how each phase is executed — the prompt patterns, the code-review gates, the calibration of human-in-the-loop checkpoints, the playbook for handling platform-specific behaviors, and the conventions that make AI-generated InterSystems code maintainable rather than disposable — are the engineering practices we have developed and refined across our modernization work. They are what turns generic AI coding tooling into a repeatable modernization pipeline.

Where Engineering Expertise Matters

AI coding agents are powerful general-purpose tools, but they are not a substitute for deep engineering judgment. They perform best where the surrounding code, conventions, and patterns are mainstream and well represented in their training data. They require careful direction wherever a platform has unique characteristics — and InterSystems IRIS, by design, has many.

Throughout this work, we encountered places where naively generated code would have failed silently or produced subtly broken behavior: REST dispatcher conventions specific to %CSP.REST, scheduled-task APIs that differ between Caché and modern IRIS Community, privilege contexts that change under REST dispatch, route-ordering rules, and Web Gateway behaviors that materially affect deployment. In each case, the path to a correct solution required a human engineer to recognize the symptom, isolate the cause, and direct the AI toward an idiomatic fix. This is precisely the kind of work that does not scale by adding more AI — it scales by having an engineer with the right judgment in the loop. Our methodology is built around exactly that pairing.

Important Considerations Regarding Application Documentation

It is relatively straightforward to document existing application code with AI coding assistants. While valuable for support and maintenance of existing applications, in the context of application modernization and refactoring such documentation has limited utility:

  • It describes the current state of the code in the legacy application. It is not terribly useful if this code is intended to be significantly refactored and modified.
  • Legacy applications often contain obsolete, poorly written, and even incorrect code; documenting it is of limited value — it needs to be refactored or removed.
  • Most modernization efforts also entail functional and operational improvements (e.g. performance, scalability, accessibility, and more).

Our goal and the major challenge is to reverse engineer existing code into business requirements and technical documentation of the future state that describes how the modernized application should work. Once this is done, the generated specification can be updated with new functional and operational requirements, and serves as the contract from which the new application is built.

Artifacts For This Submission

Legacy Application
Original source code
Original Documentation

Refactored Application
GitHub Repository
Technical Documentation and User Guide
License: MIT (preserves the upstream license)

Working versions of the applications
Both the legacy and modernized UIs ship in a single Docker image. Reviewers can run the entire application locally with one command — see the README for the build-and-run recipe and demo accounts.