Most migration projects treat "zero data loss" as a checkbox at the end. You run the ETL, count the rows, match the control totals, sign the report. If the numbers line up, you declare victory and go home.
FENIKS was not that project. Migrating a regulated insurance core platform from AS400 to Oracle is not about moving rows — it is about preserving the legal, accounting, and actuarial meaning of every record across two fundamentally different worlds. And once you internalize that, you stop asking "did we lose data?" and start asking "can we even prove we didn't?"
Those are very different questions.
The AS400 Trap: Data That Looks Simple Until It Isn't
AS400 systems in Turkish insurance carry twenty, thirty years of accumulated semantics. Packed decimals. EBCDIC encoding quirks. Date fields stored as integers because someone in 1998 decided Y2K was solved with a CHAR(7). Premium calculations rounded with banker's rounding in some modules, half-up in others, and nobody documented which.
When you migrate to Oracle, you discover things like:
- A
POLICY_NOfield that is technically VARCHAR but has three different formatting conventions depending on which branch entered it between 2003 and 2011 - Currency amounts stored in minor units in one table and major units in another, with no schema-level indicator
- Soft deletes implemented via a status flag in one module and via row removal with audit log entries in another
- Composite keys that are documented in COBOL copybooks, not in the database itself
If you treat this as an ETL problem, you will lose data. Not rows — meaning. And in a regulated environment, losing meaning is worse than losing rows, because lost rows get caught by reconciliation. Lost meaning gets caught by a regulator two years later.
Zero Data Loss Is an Architecture, Not a Test
The core decision on FENIKS was made early: we would not validate data fidelity at the end. We would make it structurally impossible to lose data along the way.
That meant a few non-negotiable commitments:
Bidirectional traceability at the record level. Every row in Oracle had to carry, permanently, the identity of its AS400 origin — not in a migration log, but in the schema itself. If a policy was queried in 2027, an auditor could trace it back to the exact AS400 record, file, and timestamp it came from. No exceptions, no "we'll add that later."
Reconciliation as a continuous service, not a phase. Instead of running a one-time row-count comparison after migration, we built reconciliation as a long-running process that operated during, after, and beyond the cutover. Financial totals, policy counts, claim reserves, and premium accruals were reconciled at multiple granularities — entity, branch, product line, accounting period — and the deltas were exposed as data, not buried in reports.
Semantic transformation, explicitly versioned. Every rule that transformed an AS400 value into an Oracle value was code, versioned, and reviewable. Not a stored procedure that someone tweaked under pressure at 2 AM. If a rounding convention changed between iteration 4 and iteration 5, we could replay the migration and see exactly which records were affected.
Idempotent reruns. The migration had to be re-executable without corrupting state. This sounds obvious until you've watched a team panic-patch a production migration at midnight and realize the second run will double-insert claims.
What Actually Goes Wrong (And Why End-Validation Catches None of It)
A few examples from the trenches:
- Premium accruals at month boundaries. AS400 calculated accruals using a day-count convention that drifted by one day in leap years for certain product types. The Oracle target used a corrected convention. Row counts matched. Total premium matched within rounding. But individual policy accruals were off by 1/365 in a subset — small enough to pass aggregate reconciliation, large enough to mismatch with the general ledger over a quarter.
- Soft-deleted policies resurrected by referential repair. A naive migration would re-link claims to canceled policies because the FK existed. We caught this because the architecture forced us to preserve the lifecycle state of every record, not just its current value.
- Currency precision loss in commission calculations. Packed decimal to NUMBER conversions look harmless until commissions chain through three calculation steps and the cumulative error breaches the threshold the actuarial team uses to sign off on portfolios.
None of these would have been caught by a row count. All of them would have been caught by a regulator.
The Real Definition of Zero Data Loss
Zero data loss in a regulated financial migration means three things, and only three things:
- Every source record is accounted for — preserved, transformed, or explicitly and traceably excluded with a documented reason.
- Every transformation is reproducible — given the source, the rules, and the version, you can produce the same target. Forever.
- Every business invariant is preserved — the general ledger ties. The reserves tie. The premium register ties. Not approximately. Exactly, to the kuruş.
If you cannot demonstrate all three on demand, years after cutover, you did not achieve zero data loss. You achieved zero data loss that you noticed.
The Lesson Worth Taking
The teams that fail at large-scale migration are not the ones with weak ETL. They are the ones who treated fidelity as a verification step instead of a design constraint. By the time validation runs, the architectural decisions that determine whether you can prove zero data loss have already been made — months earlier, often by people who didn't know they were making them.
FENIKS worked because we accepted, on day one, that the migration was not a project to move data. It was a commitment to preserve meaning across a system boundary that nobody had crossed before in this organization. Everything else — the tooling, the schedules, the cutover plans — followed from that commitment.
Migrate from that posture, and zero data loss stops being a claim you defend. It becomes a property you can prove.