Veel softwareontwikkelingsproblemen worden ten onrechte toegeschreven aan de snelheid en competentie van ontwikkelaars.
Een manager of oprichter klaagt erover dat het te lang duurt om functies te ontwikkelen. De communicatie met de leverancier is moeilijk of voelt versnipperd. Bugs en problemen komen terug nadat wijzigingen zijn aangebracht. De toepassing en workflows breken te vaak. Het bedrijf wil schalen, maar er zijn serieuze twijfels en vertrouwensproblemen met het platform. Op het eerste gezicht lijkt dit op een leveringsprobleem, dat mogelijk opgelost kan worden door de leverancier te vervangen of meer ontwikkelaars aan te trekken, in de hoop om sneller functies en wijzigingen aan te brengen.
In dit geval zou dat helemaal de verkeerde diagnose en oplossing zijn geweest.
De klant in deze analyse is een logistiek bedrijf met veel operationele activiteiten en een aangepaste toepassing gebaseerd op het Laravel-framework in het centrum van zijn bedrijfsvoering. Het platform hanteerde klantonboarding, verzend- en taakplanning, toewijzing van chauffeurs en/of partners, statusupdates, prijsberekeningen, facturering, betalingsverwerking, intern taakbeheer, een admin-dashboard en andere geïntegreerde functionaliteiten.
Met andere woorden, dit was geen bijtoepassing voor enkele niche-operaties binnen de organisatie. Het was de operationele ruggengraat van het bedrijf.
Het probleem was echter niet alleen dat de ontwikkeling traag was en de communicatie een uitdaging. De toepassing was uitgegroeid tot het ontwikkelingsmodel in oorsprong ontgroeid was: Het was begonnen door één ontwikkelaar, uitgebreid door anderen en later bewerkt door een extern team. Elke groep had bijgedragen aan het systeem, maar er was geen consistente technische eigendom gedurende die periode over het gehele platform. Na verloop van tijd werd de codebase steeds complexer en werden er steeds meer verwikkelingen geïntroduceerd, waardoor de codebase moeilijker te analyseren was voor wijzigingen en daardoor moeilijker te veranderen.
Dit is een gevaarlijke fase voor een bedrijf: De software is te belangrijk om te negeren, te groot om zomaar opnieuw te schrijven en te onstabiel om zonder tussenkomst te schalen en wijzigingen aan te brengen. Het kiezen voor het volledig vervangen van de software door een ander generiek product brengt verborgen risico's met zich mee en gaat gepaard met de kosten van het opnieuw opleiden van personeel en het vinden van oplossingen voor zeer specifieke workflows. Bovendien zou het betekenen dat jarenlange investeringen in het huidige platform worden opgegeven, wat zeer waarschijnlijk niet eens nodig is.
De klant dacht dat ze een probleem hadden met het leveren van functies
Toen de klant contact met ons opnam, waren de zichtbare klachten al te bekend: Het duurde te lang om functies te ontwikkelen. Bugs kwamen terug nadat ze waren verholpen. Nieuwe wijzigingen verstoorden bestaande functionaliteit. Wijzigingen verstoorden vastgelegde bedrijfslogica of deden niet precies wat de klant had afgesproken. De toepassing werd onbetrouwbaar bij intensiever gebruik. De communicatie met de vorige leverancier was altijd uitdagend en het was moeilijk voor de klant, die geen technische achtergrond had, om zijn ideeën en wensen duidelijk over te brengen. Dit resulteerde in onnodige correctie-iteraties die kostbaar waren. De oprichter wilde schalen, maar de software trok de aandacht steeds terug naar dagelijkse brandbestrijding.
Dit waren echte problemen, absoluut. Maar het waren ook symptomen, niet de oorzaak.
De gevolgen voor het bedrijf waren ernstiger dan een vertraagde backlog. De oprichter besteedde te veel tijd aan het oplossen van softwareproblemen en uiteindelijk aan het beheren van de leverancier, in plaats van het bedrijf te laten groeien. Operationele fouten beïnvloedden de klanttevredenheid, het team begon het vertrouwen in het platform te verliezen. Het schalen van het bedrijf zou niet alleen het gebruik vergroten, maar ook alle deze problemen verergeren.
Veel bedrijven bevinden zich in dit stadium en beginnen na te denken over een vervangend systeem. Het vervangen van het hele platform is echter vaak niet de eerste optie, noch een noodzakelijke stap. Een herschrijving is duur, risicovol, traag en verstorend. Als het huidige systeem nog steeds waardevolle en geldige bedrijfslogica bevat en echte operaties ondersteunt, is de eerste prioriteit meestal triage en stabilisatie.
Dit was de aanpak die wij hebben gekozen.
Wat we binnen de Laravel-toepassing hebben gevonden
De applicatiestack toen wij het overnamen bestond uit Laravel 8, PHP 8.0, een hybride VueJS frontend en MySQL. Het omvatte betalings- en factureringsintegraties, achtergrondtaken, communicatie met externe API's en bedrijfskritische workflows rond logistieke operaties.
Laravel 8 was al verouderd toen, maar de versie van het framework was niet het meest urgente probleem. De diepere problemen waren architectonisch en operationeel:
- Kritieke bedrijfslogica zat in zeer grote controllers
- Dezelfde bedrijfsregels waren op verschillende manieren geïmplementeerd in verschillende delen van het systeem.
- Er waren geen betekenisvolle geautomatiseerde tests rond kernworkflows.
- Het databaseschema was gegroeid zonder een duidelijk architectonisch model.
- Migraties waren fragiel.
- Queue- en taakbeheer was onbetrouwbaar.
- Mislukte achtergrondtaken konden incorrecte operationele records produceren of operationele gegevens in een gedeeltelijk afgewerkte staat achterlaten.
- Fouten in externe API's werden niet consistent afgehandeld.
- Observabiliteit was minimaal tot niet aanwezig.
- Queue-fouten waren vaak onzichtbaar totdat een klant of operator iets verkeerds opmerkte.
- Betalingen en factuurstaten konden onbetrouwbaar worden.
- De codestijl en implementatiekwaliteit varieerden sterk over verschillende delen van de codebase.
- Er was geen duidelijk technische eigenaar verantwoordelijk voor de langetermijngezondheid van het platform.
De meest verrassende ontdekking was dat een kritieke workflow voornamelijk bestond uit één enorme controller waarvan delen werden gebruikt door andere controllers. Die controller deed te veel, was verstrengeld in andere logica, bevatte gedupliceerde logica en mengde bedrijfsbeslissingen met implementatiedetails.
Die soort structuur creëert een verborgen belasting voor elke toekomstige wijziging: Een ontwikkelaar kan mogelijk snel een functie toevoegen een keer of twee, maar op de lange termijn wordt elke wijziging gevaarlijker omdat niemand makkelijk kan voorspellen wat er anders kan misgaan.
Het echte probleem was eigendom, niet competentie
Het zou makkelijk, maar lui en wellicht onrechtvaardig zijn om dit te kaderen als "de vorige ontwikkelaars hebben slecht werk verricht en waren incompetent."
Dat is niet de nuttige les die je uit dit verhaal moet halen.
De nauwkeurigere diagnose is dat het systeem door verschillende handen was gegaan zonder één verantwoordelijke technische eigenaar. Verschillende bijdragers losten directe problemen op, maar niemand was verantwoordelijk voor het hele systeem als langetermijnbedrijfsactiva.
Die onderscheid is veel belangrijker dan mensen beseffen.
Een ontwikkelaar voegt een functie toe. Een leverancier sluit een ticket af. Maar een bedrijfskritische platform vraagt om iemand die de architectuur, betrouwbaarheid, deployments, algemene observabiliteit, technische schuld en de afwegingen tussen bedrijfsdruk en technische risico's beheert.
Zonder die verantwoordelijkheid kan een Laravel-toepassing wel groeien, maar dat gebeurt onevenredig. Controllers raken overbelast. Bedrijfsregels verspreiden zich door de applicatie. Code wordt gedupliceerd. Wachtrijen worden fragiel. Integraties worden onvoorspelbaar. Releases worden riskant. En uiteindelijk wordt de oprichter of hoofdmanager het aanspreekpunt voor elk softwareprobleem.
Op dat moment heeft een bedrijf niet alleen extra ontwikkelcapaciteit nodig: het heeft technische verantwoordelijkheid en eigenaarschap nodig.
Waarom we stabiliseerden voordat we upgraden
Een veelgemaakte fout met verouderde Laravel-toepassingen is om direct te springen op modernisering van het framework en de infrastructuur: Laravel upgraden, PHP upgraden, packages vervangen, de frontend opkuisen, infrastructuur verplaatsen, modules herschrijven.
Die dingen zijn misschien wel nodig, zeker op de lange termijn, maar de volgorde is belangrijk.
In dit geval zou een te vroegtijdige upgrade het risico hebben verhoogd in plaats van verminderd. De codebase had een onregelmatige kwaliteit, onvoldoende testdekking, fragiele bedrijfslogica en beperkte tot geen observabiliteit. Een framework-upgrade onder die omstandigheden zou, en deed dat in onze ervaring vaak, nieuwe bugs introduceren zonder het team een betrouwbare manier te geven om ze te detecteren voordat ze in productie gaan. Het updaten van frameworks, packages en omgeving zou ervoor zorgen dat de situatie erger in plaats van beter wordt, wat meer frustratie veroorzaakt voor de mensen die proberen hun werk te doen met de software en een negatieve ervaring geeft voor de klanten van dit bedrijf.
Dus besloten we om eerst triage te doen en te stabiliseren.
Het doel was niet om het systeem perfect te maken. Het was om de belangrijkste workflows voldoende betrouwbaar te maken zodat het bedrijf kon doorgaan met groeien. Dat betekende zich richten op de delen van de applicatie waar falen de hoogste bedrijfskosten had.
De eerste stabilisatiefase
De eerste fase duurde ongeveer zes weken.
Tijdens die periode richtten we ons op het verminderen van de hoogste operationele risico's en het zichtbaar maken van onzichtbare problemen.
Het werk omvatte:
- De codebase en productierisico's auditeren.
- Proper foutopsporing en observabiliteit introduceren.
- Mislukte taken, trage queries, gebruikersfouten, betalingsproblemen, factureringsfouten en deploymentsproblemen zichtbaar maken.
- Wachtrij- en taakbeheer stabiliseren.
- Het afhandelen van falen van externe API's verbeteren.
- Kritieke bedrijfsworkflows refactoren.
- Gedupliceerde bedrijfslogica uit controllers verplaatsen naar serviceklassen.
- Regressietests toevoegen rond de belangrijkste workflows.
- Een veiliger ontwikkelings-, test- en productie-deploymentsproces creëren.
- GitLab CI/CD-automatisering introduceren.
- Deploymentsverantwoordelijkheid overnemen.
- Code-standaarden en een meer gestructureerd leveringsproces vaststellen.
Dit was geen glamoureus werk, maar wel noodzakelijk werk. Voordat we meer functies toevoegen en het systeem upgraden voor de veiligheid, moest het systeem eerst veiliger worden om te wijzigen.
Het wachtrijprobleem was niet alleen technisch
Het systeem voor achtergrondtaken was een van de belangrijkste gebieden die gestabiliseerd moesten worden.
Taken mislukten stilzwijgend of negeerden fouten. Sommige taken hadden neveneffecten die in grensgevallen problemen veroorzaakten in andere delen van de software. Fouten in externe API's werden niet goed afgehandeld. Mislukte taken vereisten soms handmatige tussenkomst en databasecorrecties. Wachtrijwerkers werden niet goed bewaakt. Er was geen betrouwbare monitoring om aan te geven wanneer operationele processen in de achtergrond waren vastgelopen.
Voor een logistiek platform is dat een ernstig risico.
Een mislukte achtergrondtaak is niet alleen een technische fout. Het kan een verkeerde status betekenen, een ontbrekende melding, een onderbroken factureringsstroom, een vertraagde operationele taak of een fout die de klant ziet.
Zodra observabiliteit werd geïntroduceerd, kon het team zien wat er eigenlijk in productie gebeurde. Mislukte taken, fouten, trage queries, betalings- en factuurproblemen, problemen gerelateerd aan implementaties en fouten die gebruikers zien, werden zichtbaar.
Die zichtbaarheid veranderde de aard van het werk.
In plaats van te wachten tot de klant symptomen rapporteerde, konden we direct grensgevallen identificeren, de bedrijfslogica strakker maken, terugkerende foutpunten verhelpen en het platform verbeteren met bewijsmateriaal uit de praktijk.
De kernbedrijfslogica herstructureren
De eerste grote herstructureringsinspanning richtte zich op het ontwarren van de grote controllers die de centrale bedrijfslogica afhandelden. Het probleem was niet alleen de omvang. De controllers bevatten gedupliceerde logica, inconsistenties en verschillende interpretaties van dezelfde bedrijfsregels.
Dat maakte het platform kwetsbaar.
Wanneer er een nieuw functieverzoek binnenkwam, was het risico niet alleen of de nieuwe functie gebouwd kon worden. Het risico was of de wijziging per ongeluk de prijsberekening, planning van taken, statusbeheer, toewijzingslogica, facturering of een andere gerelateerde workflow zou breken.
We verplaatsten gedupliceerde logica naar gespecialiseerde serviceklassen en begonnen met het toevoegen van regressietests rond belangrijke workflows. Het doel was niet academische codezuiverheid. Het doel was operationele controle over de software en het werk dat ermee werd verricht.
Het bedrijf moest door kunnen gaan met het aanvragen van wijzigingen. Het platform moest die wijzigingen ondersteunen zonder bestaande logica te breken.
Onderhoudbaarheid moest commercieel worden, niet alleen theoretisch.
Het leveringsmodel veranderde net zo veel als de code
De technische werkzaamheden waren natuurlijk op belangrijke manieren van belang, maar de grotere verandering was de technische eigendom.
Binarika werd verantwoordelijk voor de technische implementaties, implementaties, functiebeoordelingen, technische schuldprioritering en het evenwicht tussen bedrijfsdoelen en technische risico's.
De communicatie veranderde ook. In plaats van gefragmenteerde leveranciercommunicatie was er direct contact met de oprichter en het operationele team. Dit hielp ons te begrijpen wat de belangrijkste processen en workflows in het bedrijf waren. Backlogbeheer werd gestructureerd. Implementaties werden veiliger. Ontwikkelings-, test- en productieomgevingen werden onderdeel van een gecontroleerd proces in plaats van een bron van onzekerheid.
GitLab CI/CD-automatisering hielp discipline af te dwingen voordat er in productie werd geïmplementeerd. Tests, kwetsbaarheidscontroles, nalevingscontroles en implementatiecontroles werden onderdeel van de leveringsworkflow.
Dit is het deel waar veel bedrijven al te vaak onderschatten.
Een fragiele toepassing wordt zelden alleen opgelost door codewijzigingen. Ook het werkmodel rondom de code moet hiervoor worden aangepast.
Belangrijke vragen voor elke maatwerksoftware zijn: Wie bepaalt wat eerst wordt opgelost? Wie beoordeelt of een functie veilig is om uit te brengen? Wie is verantwoordelijk voor productieproblemen? Wie legt technische risico's uit aan het bedrijf? Wie zorgt ervoor dat technische schuld wordt afgelost voordat het een groeihinder wordt?
Zonder duidelijke antwoorden zullen dezelfde problemen blijven terugkeren.
Waarom dit geen volledige herschrijving was
De klant vroeg niet om een herschrijving, en wij adviseerden dit ook niet. Ook adviseerden wij niet om het hele platform te vervangen. Dat zou een grote financiële en operationele last hebben opgelegd en verbeteringen hebben uitgesteld die het bedrijf veel eerder nodig had.
In plaats daarvan kwamen we overeen over een meer praktische aanpak: waar nodig de kernbedrijfslogica refactoren, eerst de hoogst-risico workflows stabiliseren en het platform geleidelijk verbeteren.
Deze aanpak bracht natuurlijk ook risico's met zich mee, die we duidelijk hebben gecommuniceerd. Stabiliseren en moderniseren van een bestaand systeem vereist discipline. Je moet binnen grenzen werken en het vliegtuig verbeteren terwijl het nog vliegt. Maar voor deze klant was het absoluut de verantwoordelijkste route.
Een goede technische partner zou een door oprichters geleid bedrijf, of elk ander bedrijf voor die zake, niet moeten dwingen tot de duurste technische optie, alleen omdat het op papier schooner is. Dat is een academisch gedreven schok met weinig basis in de praktijk. De juiste oplossing moet rekening houden met bedrijfsrealiteit, cashflow, operationele druk en het feit dat het systeem al dagelijks wordt gebruikt.
Meer dan twee jaar later is Binarika nog steeds eigenaar en beheerder van het platform.
Dat is het punt en belangrijkste conclusie. De samenwerking was geen eenmalige opruimactie, maar een langdurige technische eigendom en strategische partnerschap met de klant.
Wat er veranderde na stabilisatie
Het platform werd niet perfect. Geen echte productiesysteem wordt dat ooit. Maar de operationele realiteit veranderde op een betekenisvolle manier.
Bugs en fouten werden zeldzaam in vergelijking met de vorige situatie. Toen ze wel optraden, waren ze direct zichtbaar en geprioriteerd, en vaak opgelost voordat de klant besefte dat er een probleem was. Functielevering werd sneller omdat wijzigingen werden aangebracht op een stabieler basis. Nieuwe functies hadden minder kans om bestaande bedrijfslogica te breken dankzij uitgebreid geautomatiseerd testen. Releases werden voorspelbaarder door CI/CD-automatisering.
De oprichter hoefde niet meer dagelijks betrokken te zijn bij softwareproblemen. Het operationele team herwon vertrouwen in het systeem. Het platform kon een grotere operationele omvang aan. Nieuwe automatiseringen werden mogelijk, waaronder interne taakgeneratie, rapportage en beheersworkflows, operationele herinneringen en escalaties, toewijzingsworkflows en geautomatiseerde meldingen.
Toen de tijd daar rijp voor was na stabilisatie en het invoeren van uitgebreid geautomatiseerd testen, verhoogden we het platform stap voor stap naar recentere frameworkversies en omgevingsupdates naar een veilig, actueel en stabiel platform, zonder nieuwe bugs en problemen te introduceren en, belangrijker nog, zonder het werk van het team van de klant te verstoren.
Het systeem werd ook goedkoper en makkelijker te beheren dankzij verbeterde implementatie- en infrastructuurkeuzes.
Het belangrijkste was dat het bedrijf zich weer kon richten op zijn kernactiviteiten. Het logistieke bedrijf kon zich weer op logistiek concentreren, terwijl Binarika zich weer op de software kon richten.
Die verdeling van verantwoordelijkheden is vaak waar de echte waarde ontstaat.
De les voor bedrijven met maatwerksoftware
Als uw organisatie afhankelijk is van een maatwerksoftwaretoepassing, zoals het bedrijf in deze analyse van de maatwerk-Laravel-toepassing, is langzame functielevering misschien niet het echte probleem.
Het echte probleem kan zijn dat de toepassing zijn oorspronkelijke ontwikkelmodel te groot is geworden.
Dit komt vaak tot uiting door bekende symptomen:
- Functies kosten te veel tijd om te ontwikkelen.
- Bugs komen steeds terug.
- Nieuwe wijzigingen verstoren bestaande workflows.
- Achtermijnprocessen mislukken stilzwijgend.
- Bedrijfsregels zijn inconsistent.
- Niemand vertrouwt volledig op de gegevens.
- Releases voelen riskant aan.
- De oprichter wordt te vaak betrokken bij softwarebeslissingen.
- Het team begint een volledige vervanging te overwegen omdat het huidige systeem onbeheersbaar lijkt.
Misschien is een (gedeeltelijke) herschrijving nodig. Misschien is een framework-upgrade nodig. Misschien is modernisering van de infrastructuur nodig.
Maar de eerste vraag moet eenvoudiger zijn:
Wie is verantwoordelijk voor het systeem, technisch, operationeel en commercieel?
Als het antwoord onduidelijk is, zal het toevoegen van meer ontwikkelaars het onderliggende probleem niet oplossen. Het kan het systeem zelfs moeilijker te controleren maken.
Een bedrijfskritische platform zoals deze Laravel-toepassing heeft meer nodig dan het afhandelen van tickets. Het vereist technische verantwoordelijkheid, observabiliteit, architectuurdiscipline, veilige implementaties, regressiebescherming en een roadmap die softwarebeslissingen koppelt aan bedrijfsdoelstellingen.
Dat is waar hulpwerkzaamheden overgaan in een langdurige samenwerking.
Niet omdat het oorspronkelijke systeem waardeloos was. Niet omdat eerdere ontwikkelaars incompetent waren. Maar omdat het bedrijf een fase had bereikt waar de software een ander niveau van verantwoordelijkheid nodig had.
Voor bedrijven en organisaties in die positie is het doel niet om de code perfect te maken.
Het doel is om de controle terug te winnen.