# The FDE system design round: design around the customer's legacy system, don't rebuild it

> FDE job ads say plainly that you will work inside decisions other people have already made. An architecture drawn on a blank page is an architecture for a customer who does not exist.

Original: https://fdetimes.net/en/guides/fde-system-design-legacy-integration/

Picture the prompt: the customer is an insurance company whose policy management system has run on-prem for years, and the operations team lets nobody change it. They want a service that triages insurance claims. You have 45 minutes and a whiteboard.

Many engineers reach straight for a clean architecture: an API gateway, microservices, a new database, and a proposal to "gradually move everything over". In a standard SWE round that answer may be enough. For an FDE role, it skips exactly the work the job ad describes.

Praxent's FDE job ad explicitly asks for clean integration with the systems you are actually given, legacy cores included, and says outright that you work inside decisions other people have made.

So the sensible way to prepare is to assume the interviewer wants to see how you design around constraints, not how good you are at wishing them away.

**Key point:** In the field, the customer's constraints do not get in the way of the design; they are the problem you are asked to solve.

## Why is "rewrite it cleanly" the wrong answer?

Martin Fowler warns against the all-at-once rewrite: it sounds simple, but in his observation most such plans end in failure. The approach he favours is incremental modernisation, and it has a name: Strangler Fig.

According to Microsoft's Azure architecture documentation, Strangler Fig gradually replaces pieces of an old system's functionality with new applications and services. Meanwhile, the old system keeps running the functions that have not yet moved. The core mechanism is a façade, a proxy layer that sits in front of the legacy back end and decides whether each request goes to the old application or the new service.

But every pattern has preconditions. Microsoft states that Strangler Fig may not be suitable if you cannot access the legacy system's source code and there is no other integration point you are allowed to change, such as the database. That is the first question to ask in the interview.

## Start with questions, not drawings

For the insurance prompt above, spend the first five minutes asking. Can the policy system's code be changed? If not, can you read its database? In which direction does the internal network allow connections? Who approves access, and how long does that usually take?

The last question is not filler. Appsierra, a company that supplies FDEs, argues that access provisioning, security reviews and customer approvals often take longer than finding the engineer.

That is a vendor's view rather than independent data, but if you build review time into your plan, you show that you understand where real projects actually stall.

Suppose the interviewer answers: no code changes, database reads allowed, no inbound firewall rules. Those three answers decide most of the architecture.

## Worked example: building the data path layer by layer

Start with the network. When the firewall will not open inbound, you place an agent inside the customer's network and let it make outbound connections only. Palantir Foundry did exactly this: an agent inside the customer network continuously polled Foundry over a one-way outbound HTTPS connection to pick up jobs.

Its documentation now marks this agent worker architecture as legacy, but the principle of opening no inbound ports is still worth following when you sketch your design.

Next comes capturing events. Because you cannot change the code, you cannot insert a "send an event when a new claim arrives" call into the application. For components that cannot be modified, Microsoft suggests capturing events from the database itself, for example with change data capture reading the transaction log, so the application code is never touched.

The events now reach you, but they still carry the shape of the old system. Microsoft warns that legacy systems often have messy schemas and outdated APIs. Without an isolation layer, the new design gradually absorbs the old system's semantics. That isolation layer is called an anti-corruption layer (ACL).

Imagine the old claims table has abbreviated column names, numeric status codes and amounts stored as integers multiplied by 100. The ACL is the only place that knows those conventions:

```python
# ACL: translate a legacy record into the new service's model
STATUS_MAP = {"01": "submitted", "02": "in_review", "09": "closed"}

def to_claim(row: dict) -> Claim:
    return Claim(
        claim_id=row["CLM_NO"].strip(),
        policy_id=row["POL_REF"].strip(),
        status=STATUS_MAP.get(row["ST_CD"], "unknown"),
        amount=Decimal(row["AMT_X100"]) / 100,
    )
```

The triage service works only with `Claim` and never reads `ST_CD`. This is also the heavy lifting in real life: Appsierra describes FDE integration work as reconciling the customer's real schemas, naming conventions and data gaps with what the product needs.

Finally, the façade. On day one, only one path moves to the new service; everything else still goes to the old system:

```python
MIGRATED = {"/claims/triage"}

def route(path: str) -> str:
    return NEW_SERVICE if path in MIGRATED else LEGACY
```

Moving another function over means adding one line to `MIGRATED`, and rolling back is just as easy.

## Every layer has a price: say it up front

Name the costs before you are asked. Microsoft states that an ACL adds latency to calls between the two systems. If triage has to return a result immediately to an agent who is on the phone with a customer, that latency has to fit in your budget.

If the old system runs in batches or is slow, you have another option: an event-driven ACL through a queue such as Service Bus, Event Grid or Event Hubs.

According to Microsoft, this decouples the new system from the old system's throughput limits. The price is that data arrives later and is only consistent after a delay (eventual consistency), and you should say so clearly.

## Traps to avoid

The first trap is applying Strangler Fig without checking its preconditions. If the customer lets you touch neither the code nor the database, the façade has nothing to hold on to, and you should say so plainly rather than force the pattern in.

Another trap is an ACL that exists only as a box on the diagram. If any service other than the ACL still reads the old status codes, legacy semantics have leaked into the new system. And do not forget the people: if nobody approves access, even the most elegant architecture stays on paper.

For your career: when reading job ads, phrases such as "legacy cores", "on-prem" or "existing systems" are good hints about what the system design round will cover. On your CV, do not just list technologies. Write lines like "brought data out of system X via CDC with no code changes on the customer side", because that is exactly the kind of integration FDE job ads describe.

This week's exercise is simple: take the insurance prompt above, change one answer to "no database reads allowed", and solve it again. If you can still explain why the architecture has to change, you are practising exactly the skill FDE job ads are looking for.

**Try this week:**

- Pick a legacy system at your company and answer four questions: can the code be changed, can the database be touched, in which direction does the network allow connections, and who has to approve access.
- Solve the claims triage prompt yourself in 30 minutes, timed, and spend the first 5 minutes only asking about constraints.
- Rewrite one line of your CV using this template: which system you integrated with, through which integration point, and what you did not have to change on the customer side.

## Sources

- [Strangler Fig Pattern - Azure Architecture Center | Microsoft Learn](https://learn.microsoft.com/en-us/azure/architecture/patterns/strangler-fig)

- [Anti-Corruption Layer Pattern - Azure Architecture Center | Microsoft Learn](https://learn.microsoft.com/en-us/azure/architecture/patterns/anti-corruption-layer)

- [Strangler Fig Application (Martin Fowler)](https://martinfowler.com/bliki/StranglerFigApplication.html)

- [Agent architecture - Palantir Foundry documentation](https://palantir.com/docs/foundry/data-connection/architecture)

- [Forward Deployed Engineers - Appsierra](https://www.appsierra.com/services/forward-deployed-engineers)

- [Forward Deployed Engineer at Praxent | Torre](https://torre.ai/post/6WZzzL0W-praxent-forward-deployed-engineer)
