Pillar page

Legacy-modernisering

Inkrementell refaktorering från monolit till mikrotjänster, migrering från föråldrad teknik till moderna stackar, molnmigrering — utan driftstopp, med rollback-plan och fullständig revisionsspårning.

Varje företag har något legacy-system. Vissa har flera. En bokföringsapplikation från 2008 som på något sätt fortfarande fungerar. Ett CRM skrivet av konsulter ingen längre minns. Ett lager som körs i Access. Var och en av dem kommer behöva ersättas så småningom — frågan är inte om, utan när och hur.

Legacy-modernisering är en av de svåraste typerna av IT-projekt. Det kräver att man balanserar tre krafter: affärskontinuitet (systemet måste fortsätta köra hela tiden), införande av modern teknik (mikrotjänster, moln, AI) och riskkontroll (varje refaktorering kan förstöra något som fungerat i åratal).

Varför inte bara „skriva om från grunden"?

Enligt vår erfarenhet är 9 av 10 lyckade moderniseringar inkrementell refaktorering, inte omskrivningar. Omskrivningar är konceptuellt lockande („vi börjar med ett blankt papper"), men i praktiken har de tre grundläggande problem:

  • Osynlig affärslogik. Det gamla systemet innehåller år av affärsregler — specialvillkor för de största kunderna, skattefrielsen för specifika branscher, kringgåenden för regleringar från 2015. Det mesta är odokumenterat. En omskrivning måste återskapa allt från människors minnen eller kodanalys.
  • Duplicerat arbete. Medan det nya systemet skrivs kräver verksamheten fortfarande ändringar i det gamla (regleringar, nya kunder, små buggar). Teamet antingen duplicerar arbetet (ändringar på två ställen) eller fryser det gamla systemet (affärsrisk).
  • Big bang-driftsättning. Efter ett års arbete är det nya systemet „nästan klart". Att byta alla användare på en natt genererar monumental risk. Varje oväntat problem innebär att gå tillbaka till det gamla systemet, förlora teammoral och erodera affärsförtroendet.

Inkrementell refaktorering (vanligtvis enligt Strangler Fig-mönstret) löser alla tre: affärslogik upptäcks gradvis, en källa till sanning för varje entitet, driftsättning i steg med feature flags.

Sex moderniseringsmönster

Var och en av dem hanterar en specifik risk. I de flesta projekt kombinerar vi flera och väljer ett mönster per modul.

Strangler Fig

Gradvis „inkapsling" av det gamla systemet med nya komponenter. Den gamla koden körs fortfarande, men varje ny funktion går till en ny mikrotjänst och befintliga moduler ersätts en efter en. Efter 12-24 månader stängs den gamla monoliten av.

Anti-corruption layer

En adapter som skyddar ny kod från det gamla systemets egenheter (oläsbara fältnamn, konstiga datumformat, inkonsekventa typer). All „ful" logik isoleras på ett ställe — ny kod arbetar med en ren domänmodell.

Databasrefaktorering

Mönster från Refactoring Databases (Ambler/Sadalage): expand-and-contract för schemamigreringar, datavalidering innan gamla kolumner tas bort, parallell körning av båda scheman under applikationsmigrering.

Branch by abstraction

Införande av ett abstraktionslager kring den gamla komponenten, parallell implementation av den nya komponenten, gradvis omfördelning av trafik från 0% till 100% (feature flag). Utan en „big bang"-driftsättning.

Shadow mode

Den nya koden körs parallellt med den gamla — båda bearbetar samma requests, men bara den gamla returnerar resultat till användaren. Resultaten jämförs offline. Efter bekräftad kompatibilitet (typiskt 2-4 veckor) växlar vi trafiken till den nya koden.

Event sourcing för migrering

Vi spelar in strömmen av affärshändelser från det gamla systemet och spelar upp den i det nya. Detta möjliggör preliminär validering av den nya arkitekturen utan produktionsrisk och förmågan att återgå till valfritt historiskt tillstånd.

Typisk moderniseringsplan

För ett medelstort system (en monolit på ~200 tusen kodrader, 5-10 affärsmoduler):

  1. Månad 1: Discovery och dokumentation. Reverse engineering av arkitekturen, kartläggning av beroenden, identifiering av dataflöden, dokumentation av affärsprocesser med hjälp av affärsintressenter.
  2. Månad 2: Målarkitektur och pilot. Design av den nya arkitekturen, teknikval, pilot på den enklaste modulen (proof of concept). Första valideringen av tillvägagångssättet.
  3. Månad 3-4: Brytning av den första produktionsmodulen. Strangler Fig-mönster, shadow mode i 2-3 veckor, trafikomställning, hypercare. Första verkliga affärsvärde.
  4. Månad 5-12: Iterativ brytning av efterföljande moduler. Var och en i en 4-6-veckors cykel: refaktorering → tester → shadow → produktion → hypercare. Kontinuerlig förbättring av processen, reducerad tid per modul.
  5. Månad 12-18: Datamigrering och avveckling av monoliten. När alla kritiska moduler är brutna avslutar vi den historiska datamigreringen, stänger av det gamla systemet, arkiverar. Vi firar.

Legacy-system vs. moderniserat

AspektLegacy-system (typiskt)Efter modernisering
Tid att leverera en ny funktion4-8 veckor (hög regressionsrisk)3-7 dagar (automatiska tester minimerar risken)
Testtäckning5-15% (eller ingen)>80%, i CI/CD-pipelinen
Tillgång till utvecklareLåg (föråldrad teknik)Hög (populära, moderna stackar)
SäkerhetGamla bibliotek med opatchade CVE:erOWASP-skanning, gitleaks, automatiserade uppdateringar
SkalningVertikal (mer resurser för monoliten)Horisontell (skalning av specifika mikrotjänster)
ObservabilityLoggar i filer, inga metrikerPrometheus + Grafana + Sentry + SIEM
Compliance (GDPR, EU AI Act, ISO 27001)Krävande, dyrt att bevisaInbyggd i arkitekturen, redo för granskning

Sex typiska risker — och hur vi hanterar dem

Risk: Inga tester i legacy-systemet

Mitigering: Först bygger vi karakteriseringstester (capture tests) — vi spelar in nuvarande systembeteende baserat på produktionsloggar och trafikinspelningar. Först därefter börjar vi refaktorera, med testerna som skyddsnät.

Risk: Kunskap koncentrerad till en person („truck factor 1")

Mitigering: Kunskapsöverföring börjar under projektets första vecka. Alla möten med personen som kan systemet spelas in och transkriberas, nyckelprocesser dokumenteras, arkitektoniska beslut motiveras. Efter projektet förstår hela teamet systemet.

Risk: Tillfällig nedgång i teamets hastighet

Mitigering: Under de första 2-3 månaderna underhåller teamet det gamla systemet + bygger det nya. En naturlig nedgång i ändringstakten. Vi mildrar det genom: prioritering av ändringar som bara går till det nya systemet, frysning av lågprioriterade ändringar i den gamla kodbasen.

Risk: Datamigrering

Mitigering: Varje datamigrering har tre faser: dry-run (på en produktionskopia), staging (i testmiljö med data i verklig skala), produktion (i ett servicefönster eller inkrementellt). Rollback-plan klar före start.

Risk: Organisatoriskt motstånd

Mitigering: Kommunikation med verksamheten från dag ett: varför vi moderniserar, vad som förändras för användaren, vad är schemat, hur vi mäter framgång. Den första iterationen väljs för att snabbt visa konkret värde (t.ex. ett nytt UI eller en snabbare rapport).

Risk: Underskattning av kostnader

Mitigering: Discovery (1-2 veckor) före projektprissättning. 2-3-veckors iterationer med konkreta leverabler — lättare att justera kurs än i ett långt „allt på en gång"-projekt. Budget med en buffert på 20-30% för det oväntade.

Vanliga frågor

Vad är ett legacy-system?
Ett legacy-system är programvara som fortfarande körs i organisationen men bygger på föråldrad teknik, bär på djup teknisk skuld, saknar tester, dokumentation eller utvecklaren som skrev den. Klassiska exempel: en monolitisk PHP 5.x- eller .NET Framework 4.0-applikation, en databas utan migreringar, en jQuery-frontend, FTP-driftsättning. Det fungerar, men varje ändring är högrisk och högkostnad.
Varför modernisera om systemet fungerar?
Tre huvudskäl. Först: underhållskostnaden växer exponentiellt med systemets ålder — färre utvecklare kan tekniken, varje ändring tar längre tid, varje bugg har större spridningsradie. Sedan: säkerhetsrisk — gamla ramverk har opatchade sårbarheter, ingen leverantörssupport, bristande efterlevnad av GDPR/ISO 27001. Slutligen: blockering av affärstillväxt — nya krav (mobil, API, integrationer, AI) är svåra eller omöjliga att lägga till.
Är det inte enklare att skriva om allt från grunden?
Det klassiska dilemmat „rewrite vs. refactor". Omskrivningar är konceptuellt lockande, men i praktiken tar de 2-3 gånger längre tid än planerat, projektet drunknar under vikten av att återskapa osynlig affärslogik, och samtidigt måste det gamla systemet fortfarande utvecklas (duplicerat arbete). Enligt vår erfarenhet: 9 av 10 lyckade moderniseringar är inkrementell refaktorering (Strangler Fig-mönster) — gradvis utbyte av delar av det gamla systemet med bibehållen affärskontinuitet. En omskrivning är bara meningsfull för mycket små system.
Kräver modernisering driftstopp för verksamheten?
I de flesta projekt, nej. Vi använder mönster som tillåter att komponenter byts „live": blue-green-driftsättning, feature flags, dark launches, parallell körning av gammal och ny kod med resultatjämförelse (shadow mode). Korta servicefönster kan behövas för databasmigreringar med betydande schemaändringar, men vi planerar dem i förväg (typiskt nattetid, på helgen) med en fullständig rollback-plan.
Hur lång tid tar en typisk modernisering?
Det beror på skala. En enskild monolitmodul utbruten som en mikrotjänst: 1-2 månader. En större modernisering (5-10 moduler, ny databas, nytt API): 6-12 månader i 2-3-veckors iterationer. En fullständig enterprise-monolittransformation: 18-36 månader, men affärsvärde uppstår redan efter den första iterationen — varje utbruten modul ger omedelbart fördelar (snabbare ändringar, lägre risk, bättre observability).
Från vilka tekniker migrerar vi oftast?
De vanligaste vägarna: PHP 5/7 → PHP 8 eller Python (FastAPI) eller Node.js (Express/Fastify). .NET Framework 4.x → .NET 8 eller Java/Spring Boot. Java EE (JBoss/WebSphere) → Spring Boot eller Quarkus. jQuery + monolitiska mallar → React/Vue/Astro. Oracle DB → PostgreSQL (betydande licensbesparingar). On-premise → moln (AWS, Azure, GCP, lokalt privat moln).
Hur är det med befintliga integrationer med andra system?
Varje befintlig integration kartläggs i discovery-fasen. Migreringsplanen täcker: bevarande av befintliga kontrakt (interna och externa klienter märker ingen förändring), införande av versionering (v1 gamla kontraktet, v2 nya), gradvis migrering av konsumenter till v2, först därefter avveckling av v1. Full bakåtkompatibilitet under migreringen.
Hur minskar ni affärsrisken?
Fem lager: 1) inkrementalitet — vi byter en modul i taget, inte allt på en gång; 2) karakteriseringstester — innan refaktorering fångar vi systemets nuvarande beteende (capture tests), som sedan verifierar att inget har gått sönder; 3) feature flags — ny funktionalitet rullas ut gradvis (1% av användarna → 10% → 50% → 100%); 4) rollback-plan för varje driftsättning (<5 min); 5) hypercare efter utrullning (intensiv övervakning i 2-4 veckor).
Hur är det med systemdokumentationen som inte finns?
Ett vanligt legacy-problem. Första projektsteget: reverse-engineering av dokumentationen. AI-agenter analyserar koden, databasens schema, produktionsloggar och genererar: arkitekturdiagram, endpoint-lista, beroendekarta, beskrivningar av affärsprocesser. Denna dokumentation verifieras sedan med affärsfolk (ser processen ut som vi förstod den från koden). Resultat: komplett dokumentation innan refaktorering startar, användbar inte bara för moderniseringsprojektet utan även för produktteamet.
Hur är moderniseringskostnaden jämfört med att underhålla det gamla systemet?
På kort sikt är modernisering dyrare än underhåll (refaktoreringsinvestering + parallellt underhåll av det gamla systemet). Break-even-punkten (där det nya systemet blir billigare att underhålla än det gamla) inträffar typiskt efter 12-18 månader. Därefter: det nya systemet kostar mindre att underhålla (färre utvecklare, mer automatisering), tillåter snabbare ändringar (kortare time-to-market), minskar risken (bättre observability, fler tester, isolerade fel).

Låt oss börja med en granskning

En enveckas teknisk granskning: kartläggning av nuvarande tillstånd, identifiering av de mest brådskande moderniseringsområdena, en fasad plan med konkreta affärseffekter i den första iterationen.