
Our Approach
Before proposing a change, we establish how the application supports the organisation’s day-to-day work.
Before choosing technology, we establish how the application supports the organisation’s daily work. We want to know what makes customer service difficult, which operations must keep running and what the change should achieve. A new framework, a rewrite or AI may help, but their usefulness depends on the problem we find.
We ask why change is needed: slow order handling, difficult deployments, manual corrections or a report the team does not trust. A specific problem lets us judge whether upgrading Symfony will help or whether another action is needed. We also establish constraints, such as accounting deadlines or a sales campaign during which payment changes need particular care.
We then follow the chosen workflow from beginning to end. We check who starts it, where decisions are made and how the team knows a case is complete. Work outside the application screen is part of that review.
Business workflow
├── application
│ ├── data
│ ├── integrations
│ └── background jobs
└── decisions and manual stepsWe speak with process owners, customer support, finance and the team maintaining the application. We compare their observations with documentation, code, data and logs. The documented process, today's practice and future requirements may differ. A discrepancy is not necessarily a defect.
We look for rules that were never documented. An apparently unused status may mark an invoice awaiting review before an accounting export. Before removing it or migrating the data, we confirm its purpose with finance. A migration needs to preserve what the information means, as well as its stored values.
Permissions also need checking: who can read data, change it or approve an operation? Boundaries between organisations and approvals outside the interface matter. Showing a button does not replace server-side access checks.
The technical review covers the parts relevant to the workflow: module dependencies, tests, configuration, deployments and background jobs. One fault may only need a single operation traced; wider modernisation calls for a broader investigation. We match the scope to the decision the client needs to make.
Consider a hypothetical older Symfony application. To the customer, the sequence is simple: payment, invoice and confirmation. Behind the screen, confirmation from the payment provider may arrive later, a worker creates the invoice in the background, and the accounting export runs to a schedule.
Order
↓
Payment confirmation
↓
Order status updated
↓
Job in the invoice queue
├── success → invoice and notification
└── failure → retry or manual reviewWhen changing providers, we check this whole route. A repeated payment notification must not create a second invoice, and queue failures need to be visible to the team. We establish who reviews unresolved cases and checks they are complete before export. A working order form alone tells us none of this.
For connections to CRM, ERP, email or payment services, we establish what data is exchanged and which system holds the authoritative version. We also check what happens when the provider does not respond. Unclear data ownership can leave two systems overwriting each other's corrections.
We examine the state after a failure: what has been saved, whether the operation can be retried and who is allowed to do so. Repeating an import or changing customer details after an order requires care over actions already taken. The team needs enough information to resume work without duplicating documents or bypassing a required check.
Manual steps can be necessary safeguards. A large payment may need approval, or ambiguous data may need someone to investigate. We establish the purpose and the responsible person before proposing automation.
We also examine deployments. After an application update, a worker may still be running an earlier version or configuration. Orders can then follow new rules while invoices are processed under old ones.
A slow portal may not need rewriting. One possible cause is a single screen that loads the full order history and waits for a CRM response while the rest works well. Improving the query or the way it communicates with the CRM may be enough.
We also assess the consequences for the organisation. A stopped queue might leave paid orders waiting for invoices, with the team only discovering the problem when customers complain. That gives a clearer reason to prioritise the work than a list of technical errors alone.
A dependable, understood module is worth keeping if it does not block needed changes. Age alone does not justify replacement. We focus effort where failures or limitations hinder daily work and development.
The recommendation sets out the work and what should remain unchanged, such as pricing rules, permissions or historical reporting. We compare cost, risk and the ability to reverse a change. Where work can proceed in stages, we identify the first step and the conditions for moving on.
Observed problem
↓
Verified cause
↓
Business impact
↓
Keep / stabilise / improve / replaceThe objective should make the result testable. “Allow a change of payment provider without altering orders, invoices or customer accounts” says more than “introduce a new architecture” and provides a condition for completing the work.
We agree the deliverables before the review. Depending on the problem, we prepare:
We use the access needed for the agreed purpose. If documentation is missing or a historical decision cannot be reconstructed, we explain the gap and its effect on the recommendation. The client can then decide whether to proceed or resolve that uncertainty first.