The legacy reality in insurance

In an insurance core, the product is largely a rules engine: rating tables, underwriting criteria, rounding conventions, jurisdictional variations, commission schedules, and endorsement calculations.

Over many years, those rules accumulate across procedures, triggers, views, and batch chains. The precise scale varies by organization, but the operating pattern is familiar: business logic is distributed and poorly documented, batch sequencing is tightly coupled, integration occurs through shared tables, and regression confidence depends on people rather than repeatable tests.

CharacteristicCommon legacy condition
Business logicDistributed across procedures, triggers, and views with incomplete documentation
Rating and underwritingConditional logic duplicated by jurisdiction or product, with gradual drift
ProcessingNightly policy, billing, and commission jobs with strict sequencing
IntegrationDirect database links rather than stable service contracts
Change confidenceSlow regression cycles because automated coverage is limited
KnowledgeA small number of specialists understand critical procedures

The work is not to migrate the database. It is to migrate the business decisions the database has been making on the insurer’s behalf.

Target-state architecture

The target state separates channels, orchestration, business services, rules, events, and data. Services own workflow and data access; a rules layer owns pricing, underwriting, and eligibility decisions that change frequently or require business approval. The legacy core remains available during transition, but its responsibility shrinks domain by domain.

Target architecture for modernizing a legacy insurance core. Channels reach business services through an API gateway and workflow orchestrator. Rating, underwriting, policy issuance, billing and commission, and claims services all connect to the shared rules layer and evaluate versioned decision graphs through Zen Engine. Services publish domain events to Kafka or Event Hub, while Sybase remains connected through CDC during transition.
Target architecture: every business service connects to the shared rules layer. Decision graphs are governed through GoRules BRMS and evaluated through Zen Engine at the service boundary. Editable Draw.io source
Legacy responsibilityModern homeReason for the move
Workflow and orchestration in stored proceduresSpring Boot or FastAPI business servicesVersioned, testable logic with an explicit service contract
Rating, underwriting, and eligibility rulesGoRules JDM decision graphs, managed in BRMS and evaluated by Zen EngineGoverned rule changes without coupling every change to an application release
Nightly batch chainsKafka or Event Hub with stream processingDomain events become available without an overnight delay
Linked-server integrationREST or gRPC APIs behind a gatewayConsumers no longer depend on physical database schemas
Sybase ASE transactional storageManaged PostgreSQL or an equivalent operational storeA supported platform with standard tooling and an open ecosystem
Reporting queries on the transactional coreA separate analytical store fed through CDCReporting load no longer competes with policy transactions
Manual regression comparisonContract tests and golden-file rule testsChanges can be assessed against known legacy outcomes

From stored procedure to business service

The central modernization task is to separate workflow from decision logic. Services should retain orchestration and data access. Rules that change frequently or require actuarial or underwriting approval should become named, versioned decision graphs with explicit inputs, outputs, tests, and ownership.

Legacy · stored procedure

CREATE PROCEDURE sp_calc_premium
  @policy_id INT
AS
BEGIN
  SELECT @state = state_cd,
         @driver_age = drv_age
  FROM policy_master
  WHERE policy_id = @policy_id

  SELECT @base_rate = rate_amt
  FROM rate_table
  WHERE state_cd = @state

  IF @driver_age < 25
    SET @surcharge = @base_rate * 0.35
  ELSE IF @driver_age > 70
    SET @surcharge = @base_rate * 0.15

  UPDATE policy_master
  SET premium_amt = @base_rate + @surcharge
  WHERE policy_id = @policy_id
END

Modern · service evaluates a published decision

@Service
class PremiumRatingService {
  private final RateTableRepository rates;
  private final ZenEngine rules;

  PremiumQuote calculate(PolicyContext ctx) {
    var base = rates.findLiabilityRate(ctx.state());
    var input = Map.of(
        "driverAge", ctx.driverAge(),
        "baseRate", base,
        "state", ctx.state());

    var result = rules.evaluate(
        surchargeDecisionId, input);

    return PremiumQuote.from(
        ctx.policyId(), base, result);
  }
}

The Java example illustrates the boundary: a configuration-driven decision identifier, an engine call, and a typed result. Exact SDK signatures should be confirmed against the version selected for implementation.

Decision location and environment are configuration

rules:
  engine:
    mode: agent
    agent-url: https://rules-agent.internal.example
    project: auto-policy-rating
    environment: ${DEPLOY_ENV:PROD}
  premium-surcharge:
    decision: auto/liability/age-surcharge
    version: latest-published

The age brackets and surcharge percentages are authored and tested as a decision table. GoRules stores the published model as JDM JSON; business users work through the management interface rather than editing this representation directly.

Conceptual decision table output

{
  "rules": [
    { "driverAge": "< 25",   "surcharge": "baseRate * 0.35" },
    { "driverAge": "> 70",   "surcharge": "baseRate * 0.15" },
    { "driverAge": "[25..70]", "surcharge": "0" }
  ]
}

What becomes explicit

  • Every decision has a stable identifier, owner, version, and test suite
  • The service contract defines the required context and returned result
  • The rule version is retained with the quote for audit and diagnosis
  • Product and jurisdiction variants are managed deliberately

What leaves application code

  • Age bands, thresholds, and surcharge calculations that change often
  • Copy-pasted rule branches across services or stored procedures
  • Hidden database updates inside a calculation
  • Release dependencies for routine approved rule changes

Migration strategy: strangler pattern and CDC

A big-bang rewrite concentrates technical, operational, and regulatory risk into one cutover. A safer approach moves one bounded capability at a time, compares its output against the legacy path, and retires the old responsibility only after agreed evidence is met.

Shadow-mode cutover sequence. A premium quote reaches the new rating service through the API gateway. The service evaluates a published GoRules age-surcharge decision, writes a shadow result to the legacy core, and compares it with changes received through Flink and Kafka before returning the quote and rule version.
Shadow-mode cutover: the service evaluates the published rule, records the rule version, and reconciles the modern result against the legacy path until the agreed variance threshold is met. Editable Draw.io source

The five phases

1
Discovery and rule mining · 6–10 weeks

Inventory the stored-procedure estate

Build a dependency graph and classify procedures as data access, business-rule-bearing, or unused. Rank them by business criticality, change frequency, and blast radius.

2
Foundation · 8–12 weeks

Establish the event, synchronization, and rules platforms

Stand up the event backbone, historical backfill, CDC pipeline, observability, and reconciliation patterns. In parallel, establish the GoRules management workflow and connect the first service to Zen Engine.

3
Incremental extraction · By domain

Separate service workflow from decision rules

Start with a constrained slice such as rating for one product and jurisdiction. Move orchestration and data access into a tested service; move the actual rating decisions into governed decision tables.

4
Parallel run and validation · 4–8 weeks per domain

Prove equivalence before cutover

Run legacy and modern paths against production inputs. Investigate differences and obtain actuarial, compliance, and operational sign-off against explicit acceptance criteria.

5
Decommission · Rolling

Retire responsibility from the legacy core

Disable and archive the superseded procedures, remove the CDC feed when it is no longer needed, and report the remaining legacy surface after every release.

Risks and controls

RiskControl
A rare rule is discovered lateUse shadow reconciliation before retirement and retain a controlled rollback path through an agreed audit cycle
Performance regresses on the new stackLoad-test every extracted service at production-equivalent volume before traffic moves
Data diverges during parallel operationMonitor CDC lag, reconcile business outcomes, and alert on variance beyond the agreed threshold
Regulatory evidence is incompleteVersion every extracted rule and retain its calculation trace, approval, and effective date
Legacy intent is misunderstoodPair domain experts and legacy specialists with the engineers performing extraction; record intent in decision records
Engineers become the gatekeeper for every rate or eligibility changeExternalize frequently changed decisions into governed rules with business ownership, review, and publication controls
The program loses momentumRelease domain by domain and report business outcomes rather than waiting for a full-platform launch

Governance: preserve the reason

The migration is difficult because years of decisions were embedded in code without durable context. Rebuilding the rules in a modern language without recording their purpose only recreates the same risk. Each extracted rule should be paired with a concise decision record: what it does, why it exists, who owns it, the source of authority, and the condition under which it should be reviewed.

What good looks like

Weeks → daysTime required to implement and validate a rate or rule change
Named ownershipEvery consequential business rule has a versioned owner and source of authority
Agreed varianceShadow-mode acceptance thresholds are defined with actuarial and compliance stakeholders
Shrinking legacy surfaceRemaining procedures, jobs, and integrations decline after each domain release

Where to start