White-labeling van een Laravel-supportportaal

Ik breidde een bestaand Laravel-portaal uit met instellingen voor teksten, afbeeldingen en een eigen huisstijl.

Full-stack webontwikkeling 8 min leestijd

Start: white-labeling als afstudeeropdracht

Voor mijn afstuderen aan de Associate degree Informatica moest ik zelfstandig een softwareproject uitvoeren en mijn werk onderbouwen, van onderzoek en ontwerp tot bouw en oplevering. Ik deed dat binnen een bestaand supportportaal. Na een eerste oriëntatie en gesprekken met betrokkenen werd white-labeling de opdracht: de applicatie geschikt maken voor een andere huisstijl. Een beheerder moest daarvoor de portaalnaam, teksten, afbeeldingen en een beschikbaar thema kunnen aanpassen via een instellingenpagina.

Projectverloop Van opdracht tot oplevering
  1. Start
  2. Beheren
  3. Analyseren
  4. Ontwerpen
  5. Realiseren
  6. Adviseren
Van de opdracht en vijf beroepstaken naar de afsluiting van het project.

Ik analyseerde, ontwierp en bouwde deze uitbreiding, inclusief opslag, invoercontrole en tests. Ook breidde ik autorisatiecontroles uit op meerdere plekken in het portaal. Het resultaat liet zich in mijn eindpresentatie eenvoudig aanwijzen: een nieuwe menuoptie die naar de instellingenpagina leidde. Om die pagina te bouwen moest ik begrijpen hoe de bestaande Laravel-applicatie werkte en waar mijn uitbreiding op moest aansluiten. De oorspronkelijke applicatie en de keuze voor Laravel waren al gegeven.

White-labeling De huisstijl aanpassen via instellingen
Bestaand portaal
Huisstijl A
  • Dashboard
  • Tickets
  • Gebruikers
  • Projecten

Vaste teksten en afbeeldingen voor één huisstijl.

Met mijn uitbreiding
Huisstijl B
  • Dashboard
  • Tickets
  • Gebruikers
  • Projecten
  • InstellingenNieuw

Teksten, afbeeldingen en themakeuze via instellingen.

Via de instellingenpagina
Teksten
Portaalnaam, contactadres en voorpaginatekst
Afbeeldingen
Logo, favicon en voorpagina-afbeelding
Thema
Keuze uit geregistreerde thema’s
Instellingen opslaan
Mijn uitbreiding voegde beheerbare teksten, afbeeldingen en themakeuze toe aan het portaal. Voor een nieuw thema bleef een ontwikkelaar nodig.

Beheren: het werk organiseren

De opleiding vroeg naast de software om deelproducten zoals een analyse, systeemontwerp en implementatieplan. In mijn plan van aanpak bracht ik die werkzaamheden bij elkaar en verdeelde ik ze in taken. Zo werkte ik tijdens het project ook aan de onderbouwing en overdracht van wat ik bouwde.

Die taken plande ik in Jira, in sprints van twee weken. Ik besprak de voortgang en het vervolgwerk aan het einde van een sprint en had iedere week overleg met mijn begeleider. Toen de autorisatieopdracht groter werd, splitste ik het werk verder op en plande ik opnieuw.

Beheren · Plan van aanpak De software en de onderbouwing samen uitwerken
StageprojectWhite-labeling
  • BeherenPlan van aanpak · Scrum
  • AnalyserenRequirements · CEM
  • OntwerpenSysteemontwerp · Implementatieplan
  • RealiserenGeprogrammeerde schermen · Basisapplicatie
  • AdviserenInfrastructuuradvies · Architectuuradvies
Uitwerken in sprints van twee weken

Ik plande taken in Jira en stelde de planning bij na voortgangsgesprekken. Iedere week besprak ik mijn werk met mijn begeleider.

De tien deelproducten zijn hier per beroepstaak gegroepeerd. De vertakkingen tonen hoe het werk bij elkaar hoort; de volgorde in de tijd is niet weergegeven.

Analyseren: van praktijksituatie naar requirements

Om de opdracht te begrijpen verzamelde ik informatie in gesprekken en draaide ik mee met supportmedewerkers. Die gesprekken maakten duidelijk waar de huisstijl in het portaal moest doorwerken. De huisstijl moest aanpasbaar worden terwijl de bestaande ticketfuncties behouden bleven. Dat betekende dat ik verder moest kijken dan de instellingenpagina: een aangepaste naam of afbeelding moest ook elders in het portaal terugkomen.

Ik beschreef de relevante feiten en relaties in een Conceptual Enterprise Model (CEM). Daarbij gebruikte ik CogNIAM, een methode voor feitgebaseerde modellering. Vanuit die analyse werkte ik de requirements uit: wat moest een beheerder kunnen wijzigen en welke voorwaarden golden daarvoor? Dat maakte de opdracht concreet in onder meer een portaalnaam, contactadres, voorpaginatekst, afbeeldingen en themakeuze. Aan die requirements koppelde ik acceptatiecriteria waarmee de gewenste handelingen konden worden gecontroleerd.

Analyseren · CogNIAM en CEM Van gesprekken naar een controleerbare eis
Verzamelen

Gesprekken en meewerken met supportmedewerkers.

Verwoorden

De relevante begrippen, feiten en relaties beschrijven.

Analyseren

Feiten en relaties samenbrengen in een CEM.

Requirement

Een beheerder kan de portaalnaam aanpassen.

Acceptatiecriterium

Controleren of de beheerder de portaalnaam kan wijzigen.

Ik beschreef en analyseerde de verzamelde informatie en werkte daaruit requirements en acceptatiecriteria uit. De portaalnaam laat die stap zien.

Ontwerpen: een ontwerp dat bij Laravel past

Bij het technische onderzoek trof ik bestaande rollen, permissies en mediaopslag aan. Mijn uitbreiding moest met die onderdelen samenwerken. Ik tekende de gegevens, handelingen en componenten uit en besprak het ontwerp met mijn begeleider. Mijn eerste klassendiagram sloot nog onvoldoende aan op Laravel. Ik herzag het om de verantwoordelijkheden beter te verdelen over modellen, weergaven en controllers.

Met UML (Unified Modeling Language) werkte ik uit welke klassen samen de instellingenmodule vormen. In het herziene klassendiagram verbond ik het instellingenmodel met de controller, het formulier en de seeder die beginwaarden invult. De requestklasse voor het controleren van wijzigingen kreeg daarin ook een plek. Het diagram hielp om die samenhang te bespreken tijdens het uitwerken van de module.

UML · Klassendiagram De verantwoordelijkheden in de instellingenmodule
De verantwoordelijkheden in de instellingenmodule Bij het bijwerken gebruikt SettingController de SettingUpdateRequest. Het oorspronkelijke model verbindt Setting met de controller, SettingsForm en SettingTableSeeder. gebruikt associatie associatie associatie SettingUpdateRequest Controleert de aanvraag Bundelt regels en foutmeldingen SettingController Toont de instellingenpagina Verwerkt de wijziging SettingsForm Beheert de formuliervelden Verbindt gegevens met de weergave Setting Model voor instellingen Registreert de bijbehorende media SettingTableSeeder Vult de begininstellingen
Rechthoek · klasse met verantwoordelijkheid Doorgetrokken lijn · associatie Gestippelde pijl · gebruikt een andere klasse
De verantwoordelijkheden in de instellingenmodule · Deze vereenvoudigde uitsnede van het UML-ontwerp laat zien hoe de onderdelen samenhangen. De teksten beschrijven hun taak; code en een definitief databaseschema zijn hier niet weergegeven.

Deze uitsnede beschrijft de verantwoordelijkheden in het ontwerp. De bewaarde ontwerp- en codebeelden zijn niet overal gelijk bijgewerkt; daaruit is dus geen definitief databaseschema af te leiden.

Realiseren: de instellingenmodule bouwen en toetsen

Van schermontwerp naar instellingenformulier

Ik begon de interface met een schermontwerp in Penpot. Na het inrichten van mijn lokale ontwikkelomgeving werkte ik dat uit met Blade en Livewire binnen het bestaande Laravel-portaal. Met Blade bouwde ik de weergavecomponenten; Livewire verbond de formuliergegevens met die weergave en verzorgde het dynamische deel van de interface.

Via de nieuwe menuoptie kwam een bevoegde beheerder bij de opgeslagen instellingen. Daar kon die bijvoorbeeld een naam wijzigen, een logo uploaden of een thema selecteren. Bij het versturen controleerde een Form Request de invoer, waarna de controller de waarden en afbeeldingen verwerkte voor gebruik in het portaal. In het formulier nam ik meldingen op voor ongeldige invoer en verwerkte wijzigingen.

Het activiteitendiagram werkte de beheerhandeling uit, inclusief de foutpaden. Als ophalen mislukte, moest een melding volgen en kon de beheerder de instellingen opnieuw openen. Bij een opslagfout ging de handeling terug naar het bewerken. Validatie en autorisatie stonden in dit oorspronkelijke ontwerp nog niet als afzonderlijke stappen; die licht ik hieronder toe.

UML · Activiteitendiagram Een wijziging opslaan, met ruimte voor fouten
Een wijziging opslaan, met ruimte voor fouten Een beheerder opent de instellingen. De applicatie haalt de waarden uit de database. Bij een ophaalfout volgt een foutmelding en kan de beheerder opnieuw openen. Na bewerken slaat de applicatie de wijziging op. Bij een opslagfout volgt een foutmelding en kan de beheerder opnieuw bewerken; bij succes volgt een bevestiging. Beheerder Applicatie Database nee ja nee ja Instellingen openen Instellingen opvragen Waarden ophalen Foutmelding tonen Waarden bekijken en bewerken Wijziging versturen Wijziging opslaan Foutmelding tonen Bevestiging tonen Ophalen gelukt? Opslaan gelukt?
Kolom · verantwoordelijke partij Afgerond blok · activiteit Ruit · beslissing ● Start · ◉ Einde
Een wijziging opslaan, met ruimte voor fouten · Het oorspronkelijke activiteitendiagram bevat terugkeerpaden voor fouten bij ophalen en opslaan. Validatie en autorisatie staan daar nog niet als afzonderlijke stappen in en worden in het artikel toegelicht.

Instellingen centraal bewaren en opvragen

De portaalnaam en andere instellingen waren op verschillende plaatsen nodig. Ik voegde een instellingenmodel met een tabel toe aan de bestaande database, legde de tabelstructuur vast in een migratie en vulde de beginwaarden met een seeder. Een helperfunctie bundelde vervolgens het ophalen van instellingen. Daardoor hoefde ik die opvraaglogica niet in iedere controller of weergave opnieuw te schrijven.

Instellingen worden vaak gelezen en relatief weinig gewijzigd. Vanuit die gedachte nam ik caching op om databaseverzoeken te beperken. De bewaarde codebeelden tonen een cache-opvraag met een databasefallback en het schrijven naar de cache na het opslaan. Hoe de cache volledig werd gevuld en ververst, is daarmee niet vastgesteld; ook heb ik geen meting van snelheidswinst.

Validatie bij de aanvraag houden

Een tekstveld, afbeelding en themakeuze vragen elk om andere controles. Voor uploads golden bijvoorbeeld grenzen aan bestandstype en grootte, terwijl het gekozen thema in de configuratie moest bestaan. Ik bracht de regels en foutmeldingen onder in een Laravel Form Request: een aparte klasse die de aanvraag controleert voordat de controller de wijziging verwerkt.

Validatie kon ook in de controllermethoden staan. In mijn verantwoording beschreef ik het risico dat de regels dan over meerdere methoden verspreid zouden raken. Met de Form Request hield ik ze bij elkaar en bleef de controller gericht op het verwerken van de invoer. Voor afbeeldingen maakte ik een uploadvak waar een beheerder bestanden naartoe kon slepen; voor de opslag sloot ik aan op de bestaande mediaoplossing.

Wat de tests lieten zien

Ik schreef unit- en featuretests voor het instellingenmodel en de controller, zodat ik opslag en verzoekafhandeling na wijzigingen opnieuw kon controleren. De bewaarde PHPUnit-run bevatte mijn uitbreiding én bestaande tests van het portaal en eindigde met 58 geslaagde en 9 mislukte tests. Bij drie zichtbare fouten was een externe testafbeelding niet bereikbaar. Van alle negen fouten samen zijn de oorzaak en het eventuele herstel niet volledig vastgelegd.

Daarnaast hield ik de acceptatie van de requirements bij. De acceptatietabel registreert verschillende instellingenhandelingen als afgerond, met beperkingen bij het beheer van rollen en permissies. Dat is een afzonderlijke registratie van geaccepteerde handelingen; zij verandert de uitslag van de geautomatiseerde tests niet. Geen van beide is voor deze terugblik opnieuw uitgevoerd.

Realiseren · Testen Wat de testuitvoer en acceptatietabel vastleggen
Bewaarde PHPUnit-uitvoer
58 geslaagd
9 mislukt

De run omvatte unit- en featuretests voor onder meer opslag en autorisatie, met zowel bestaande tests als tests voor mijn uitbreiding.

Bij drie zichtbare fouten was een externe testafbeelding onbereikbaar. De oorzaak en het herstel van alle negen fouten zijn niet volledig vastgelegd.

Geregistreerde acceptatie
OnderdeelRegistratie
InstellingenhandelingenAfgerond
Beheer van rollen en permissiesBeperkt

De acceptatietabel registreert afgeronde instellingenhandelingen en beperkingen bij rollen- en permissiebeheer. Dit is een afzonderlijke registratie naast de testuitslag.

De bewaarde PHPUnit-run bevat mijn uitbreiding en bestaande portaaltests. Daarnaast staat de geregistreerde acceptatie. Deze gegevens zijn voor de terugblik niet opnieuw getoetst.

Autorisatie uitbreiden binnen het portaal

De toegang tot de instellingen moest aansluiten op de bestaande rollen en permissies. Tijdens het werk werd deze taak groter: ik werkte ook aan controles elders in het ticketsysteem. Daarvoor gebruikte ik policies om regels rond modellen te bundelen en gates voor afzonderlijke acties. Zo kon ik de controles binnen de bestaande Laravel-structuur organiseren.

Mijn presentatie en stageverslag beschrijven die bredere uitvoering. De bewaarde codefragmenten laten daar een deel van zien; volledige dekking van alle routes en permissies is daarmee niet aangetoond.

Een thema kiezen en een thema toevoegen

Voor de thema’s bouwde ik voort op de bestaande Tailwind-opzet, met een apart bestand met kleurvariabelen per thema. Een beheerder kon op de instellingenpagina kiezen uit de geregistreerde thema’s. Voor een nieuw thema moest een ontwikkelaar eerst de configuratie en een bijbehorend CSS-bestand toevoegen. In het implementatieplan beschreef ik die stappen, zodat duidelijk was welk werk via de beheerpagina kon en waarvoor nog ontwikkeling nodig was.

Adviseren: de oplossing onderbouwen en overdragen

Om de technische samenhang uit te leggen werkte ik een architectuuradvies uit met het C4-model. Op componentniveau liet ik zien hoe de routes, controller, autorisatie, het formulier en de opslag samenwerkten.

C3 · Componentdiagram Hoe mijn module aansluit op het bestaande portaal Instellingenmodule
  1. Persoon Beheerder

    Past de huisstijl aan via de instellingenpagina.

    De beheerder gaat via de routes naar de instellingenpagina.
  2. Bestaande frameworkvoorziening Routes

    Leidt de aanvraag naar de instellingencontroller.

    Binnen Bestaande Laravel-applicatie. De route roept de instellingencontroller aan.
  3. Component · mijn uitbreiding Instellingencontroller

    Verwerkt de handelingen op de instellingenpagina.

    Binnen Bestaande Laravel-applicatie. De controller laat de toegang controleren via de autorisatievoorziening.Via het instellingenmodel verwerkt de controller de gegevens.De controller geeft de gegevens door aan het instellingenformulier.
  4. Bestaande basis · door mij uitgebreid Autorisatie

    Breidt controles uit op basis van bestaande rollen en permissies.

    Binnen Bestaande Laravel-applicatie.
  5. Component · mijn uitbreiding Instellingenmodel

    Beheert de instellingen en hun afbeeldingen.

    Binnen Bestaande Laravel-applicatie. Via het model worden instellingen uit de database gelezen en opgeslagen.Het model koppelt afbeeldingen aan de bestaande mediaopslag.
  6. Component · mijn uitbreiding Livewire-formulier

    Koppelt de ingevoerde gegevens aan de weergave.

    Binnen Bestaande Laravel-applicatie. Het Livewire-formulier koppelt de gegevens aan de Blade-weergave.
  7. Component · mijn uitbreiding Blade-weergave

    Toont velden, afbeeldingen en meldingen aan de beheerder.

    Binnen Bestaande Laravel-applicatie.
  8. Bestaande gegevensopslag Database

    Bewaart ook de toegevoegde instellingen.

  9. Bestaande voorziening Mediaopslag

    Bewaart de afbeeldingen van het portaal.

Onderdeel · type in het blok Extern onderdeel Systeem- of containergrens Gerichte relatie · uitleg bij de pijl
Hoe mijn module aansluit op het bestaande portaal · Dit onderdeel van het architectuuradvies plaatst mijn instellingenmodule binnen het portaal. Routes, frameworkvoorzieningen, database en mediaopslag vormden de bestaande basis.

Het diagram bevat zowel mijn uitbreiding als de bestaande voorzieningen waarop die steunde. In de onderbouwing legde ik mijn keuzes voor onder meer de helper en Form Request uit. Het implementatieplan maakte de overdracht praktisch: hoe richt je de opslag in met de migratie en seeder, voeg je een thema toe en controleer je de uitbreiding?

Mijn begeleider reviewde mijn code en gaf feedback op het schermontwerp en de documentatie. Ik verwerkte die opmerkingen tijdens het project. Volgens mijn stageverslag werd mijn ontwikkelbranch samengevoegd met de gezamenlijke ontwikkelbranch. Bij de eindpresentatie demonstreerde ik de uitbreiding en lichtte ik mijn technische keuzes toe. Daarmee leverde ik de beheerpagina, de onderbouwing en de implementatie-instructies samen over.

De oorspronkelijke applicatie is voor deze terugblik niet opnieuw uitgevoerd. De documentatie, presentatie en bewaarde code- en testbeelden onderbouwen de interne integratie en demonstratie; productiegebruik is niet vastgesteld.

TERUG NAAR SITE