
Legacy Support
We modernise existing applications in stages, protecting the processes, data and integrations that still matter to the business.
Modernisation is not the replacement of everything old. An application used for years may contain essential business rules, unusual exceptions, customer data and integrations whose replacement would create more risk than value. A sensible decision starts with what the business needs to improve: faster service, lower operational risk, easier releases, a safer integration or room to develop a particular area.
Technology serves that purpose. A newer framework, cloud platform, microservices, a new frontend or AI is not, by itself, a reason to rebuild.
Before changing anything, establish which workflows are critical, where the application owns data, which integrations affect the outcome, and which problems are proven rather than assumed. An audit brings together production behaviour, support requests, code, dependencies, data and deployment practice. If the system is already failing in production, stabilise it first: improve failure visibility, protect important workflows and make recovery predictable.
Existing system + business goals
│
▼
audit and risk review
│
┌────────┴────────┐
▼ ▼
stabilisation selected change
│ │
└────────┬────────┘
▼
deploy and verifyThe outcome need not be a full rewrite. The best decision may be to leave a stable module in place, remove one bottleneck or separate an integration more clearly.
A safe phase has a clear purpose and boundary: reporting, catalogue handling, data import or invoicing, for example. The boundary should say which system is the source of record, who may change the data, how a failed synchronisation is handled and when the old module can be retired.
Old and new code can run together when routing is deliberate, data ownership is not duplicated and results can be compared. This is neither a promise of no downtime nor a universal pattern. Replacing a small module in one step, or undertaking a broader rewrite, can be safer in some circumstances. The decision follows scope, risk and dependencies.
User
│
▼
Controlled request routing
├── existing module ──┐
└── modernised module ┼── shared rules and access control
│
one named system of record
│
compare outcomes → retire the old moduleImagine a hypothetical Symfony application handling checkout, payments, invoices, notifications and an operations panel. It is not a GiSoft client case. Checkout may work well while payment calls are scattered through controllers and invoicing becomes stuck after timeouts.
The first change does not have to replace the application. It can retain the order form and pricing rules, introduce a payment adapter, persist the authoritative order state and run invoicing as a controlled background job. An email notification should not decide whether an order is paid.
Checkout and order rules ── persisted state ──► invoicing
│ │ │
▼ ▼ ▼
payment adapter operations view accounting system
│
└── response validation, timeouts, attempt historyA timeout does not automatically mean that a payment or invoice failed. A safe retry needs durable state, concurrency control, database uniqueness constraints and compatible provider behaviour. An order identifier alone does not provide idempotency. If an external action may already have happened, checking its status or applying a correction can be safer than retrying blindly.
Upgrading PHP, Symfony, Laravel or dependencies may improve maintainability and security, but it still requires compatibility checks, protection of critical rules and a sound deployment path. Not every application needs a new frontend, containers or separate services. A server-rendered interface or jQuery can remain an appropriate choice if it serves users well and does not block the required work.
The same applies to the database. Analyse performance, data ownership, migration quality and the ability to reverse a local change before moving data. Direct SQL can be appropriate. When replacing a module, versioned migrations, an agreed source of record and controlled imports are safer than permanent two-way synchronisation with no owner.
Characterisation tests capture current behaviour before refactoring. The most valuable tests cover checkout, pricing, permissions, payments, invoices and critical integrations. After deployment, check configuration, migrations, workers, scheduled jobs and production signals as well as the code.
Rolling back code does not reverse a captured payment, an email or a document delivered to an ERP. Such effects need forward recovery: a verified end state, a safe correction and clear ownership. Monitoring should connect technical signals with the business case identifier without needlessly recording sensitive data.
Modernisation also covers authentication, server-side authorisation, roles, organisation isolation, secrets and current integration credentials. Changing framework or infrastructure does not provide these properties automatically.
GiSoft prioritises modernisation by business value, risk, frequency of the problem, dependencies and the cost of continued maintenance. A small, verifiable change suits a narrowly bounded problem. Module replacement fits a clear responsibility. A broader rewrite is considered where boundaries, data or security make safe incremental work impractical.
AI can be useful within a controlled workflow, but is not a reason to rebuild. First come clear data sources, permissions, audit trail and the application’s responsibility for final actions.
The result is more than new code: it is a measurable plan stating what changed, how workflows were protected, how the release was verified, what risk remains and why the next step is worthwhile.