1. Introduction

1.1. Overall Description

In dit OOSE project zal team Perlman een HR Portaal realiseren voor JDI. Het doel van dit portaal is om een plek te bieden aan werknemers en werkgevers waar de werkplekken, reiskosten en verlofaanvragen beheerd kunnen worden.  Ook zal er een Slack koppeling komen die bericht kan teruggeven over het resultaat van aanvragen.

1.2. Purpose of this document

Het hoofddoel van dit document is om design beslissingen over het HR portaal vast te leggen. Op deze manier houden we als team een overzicht van de software, en hebben we een overzichtelijke manier om onze ontwerpen naar de opdrachtgever te communiceren. Dit document zal de algemene architectuur van het HR Portaal inzichtelijk maken. Ook zullen dingen als de datastructuur en het interface ontwerp in dit document worden vastgelegd. Verder zal dit document de scope van het project vastleggen, door aan te geven welke dingen wel en niet worden geïmplementeerd.

Aan de hand van dit document zal dus de technische vormgeving van het HR Portaal worden gecommuniceerd, zowel richting de opdrachtgever als binnen team Perlman.

1.3. Definitions, acronyms, and abbreviations

Term

Description

SDD Software Design Description
Design decision Een besluit die het ontwerp van het HR Portaal beïnvloed
Sub system Een los onderdeel dat deel uit maakt van HR-portaal

2. Architectural Overview

Voor het HR-portaal is er een schets gemaakt van de architectuur van onze applicatie, deze ziet er uit als volgt:


Gebruiker: Dit zijn de medewerkers (werkgever, werknemer, product owner, lead link) van JDI die uiteindelijk gebruik gaan maken van het portaal

Front end: Onze front end is gemaakt in Vue.js, dit is een front end framework, dit zorgt voor alle visuele representatie

Backend: De backend is gemaakt in Spring boot, dit is een java-based framework, dit zorgt voor alle achterligende functionaliteit.

Database: De database waar wij gebruik van maken is MySQL, dit zorgt voor alle data opslag.

Zoals ook te zien is maken zowel de front end als de backend gebruik van API's. De API's van de front end zorgen voor valide locaties bij het selecteren en de API van de backend is voor het berekenen van de afstand tussen twee plekken.

3. Detailed Design Description

3.1. Deployment Diagram

Voor de applicatie is ook een deployment diagram opgesteld met daarin alle servers waar de applicatie op komt te draaien. Hierbij zijn een aantal design keuzes gemaakt die in het kopje eronder staan verantwoord.

3.1.1. Design Decisions related to deployment

In het deployment diagram is te zien dat de backend en frontend in dezelfde springboot server staan. Dit is gedaan zodat de hele applicatie op 1 server kan functioneren. Ook staat deze springboot server al in een JDI Server, aangezien dit een plek is waar de applicatie waarschijnlijk op gaat draaien. De database server is echter nog niet bekend en daarom heet die dan ook gewoon database server.

3.2. Design Sub-System Vue.js frontend:

3.2.1. Design Class Diagram

Op basis van de ontwerpkeuze router is er een diagram opgesteld dat inzicht geeft in de paginastructuur uit de router.


3.2.2. Sequence diagrams

Dit onderdeel is niet van toepassing op het front end gedeelte. Er staan sequence diagrammen in het volgende onderdeel over subsystemen.

3.2.3. Design decisions made for the sub-system

Keuze front-end framework

Decision

Description

Problem/Issue

Er moest een front-end framework worden gekozen.

Decision

Voor het front-end is er voor Vue.js gekozen.

Alternatives

Er bestaan andere front-end frameworks zoals React en Angular.

Arguments

Vanuit de opdracht was er al een voorkeur voor Vue.js. Verder zijn er voor- en nadelen van Vue.js onderzocht in het bijbehorende onderzoek.


Losse componenten

Decision

Description

Problem/Issue

Omdat pagina’s vaak vergelijkbare onderdelen bevatten, zou er snel dubbele code ontstaan.

Decision

Er is een duidelijk onderscheid aangebracht tussen enerzijds de pagina’s, en anderzijds de tools & componenten. Op deze manier kunnen tools en componenten geïmporteerd & hergebruikt worden.

Alternatives

In plaats van losse componenten hadden we ook kunnen kiezen om de code te herhalen.

Arguments

Het grote voordeel van losse componenten schrijven is dat ze maar op 1 plek hoeven te worden aangepast, wat efficiënter en minder foutgevoelig is dan dubbele code. Ook zijn de losse componenten een belangrijke onderdeel van het zogenaamde Declarative Rendering, wat inhoudt dat de componenten alleen updaten als hun data veranderd. Dit maakt het laden en navigeren binnen het HR Portaal efficiënter dan als de hele pagina herladen zou worden.


Front-end schetsen

Decision

Description

Problem/Issue

Alle developers moesten een duidelijk beeld hebben van hoe het front-end eruit zou gaan zien, zodat de stijl voor de verschillende onderdelen matched en het er als een geheel uit komt te zien.

Decision

Er is besloten om al vroeg schetsen op te stellen voor alle interfaces die in de front-end te zien zijn. Dit bevatte dingen als de pagina-layout, kleurkeuzes, fontstijl, etc. Hierbij is vooral gekeken naar de bestaande JDI website, zodat het HR Portaal bij de bestaande pagina’s past.

Alternatives

Het alternatief was om direct van start te gaan met de front-end code, zonder eerst schetsen te maken.

Arguments

Het voordeel van de schetsen is dat alle front-end developers in het Perlman ontwikkelteam op dezelfde lijn zaten. Ook konden deze ontwerpen alvast richting de opdrachtgever gestuurd worden, zodat het voor de opdrachtgever duidelijk is wat ze konden verwachten (en eventueel kon er nog feedback op de ontwerpen komen vanuit de opdrachtgever).


Externe tools

Decision

Description

Problem/Issue

Handmatig alle opmaak voor de front-end programmeren kost veel tijd en moeite die beter richting andere taken kan gaan.

Decision

Er is besloten om voor de front-end gebruik te maken van bestaande tools zoals Bulma en FontAwesome. Bulma is een css framework met veel front-end componenten wat het makkelijk maakt om layout’s in elkaar te zetten. FontAwesome is een grote collectie van icoontjes die door het hele HR Portaal gebruikt zijn.

Alternatives

We hadden kunnen kiezen om de css volledig zelf te bouwen, en icoontjes handmatig op te zoeken en in te voegen.

Arguments

Tools zoals Bulma en FontAwesome besparen heel veel tijd. Ook maken ze het makkelijker om een consistente look te verwezenlijken, omdat alle css componenten op hetzelfde achterliggende framework gebaseerd zijn.


Router

Decision

Description

Problem/Issue

Aangezien het portaal een SPA is kan de positie van de gebruiker binnen de app snel onduidelijk zijn. Ook laat de URL niet altijd accuraat zien waar de gebruiker zich bevindt.

Decision

Er is besloten om gebruik te maken van de Vue Router. Dit laat ons zelf routes (en bijbehorende URL’s) binnen het HR Portaal aangeven.

Alternatives

Het alternatief is om geen Router te gebruiken.

Arguments

Door het gebruik van de Router lijkt onze SPA meer op een reguliere website waarbij gebruikers aan de hand van de URL door de app kunnen navigeren.


Opsplitsen netwerkcode

Decision

Description

Problem/Issue

Na de eerste twee sprints werd het duidelijk dat alle netwerk-gerelateerde functies in 1 document zetten geen goed idee was. Ieder nieuwe methode leverde ingewikkelde merge-conflicten op, en het werd zeer lastig om code terug te vinden.

Decision

Er is gekozen om alle netwerk code op te delen in losse documenten met individuele functies.

Alternatives

We hadden de netwerk functies allemaal bij elkaar kunnen laten staan.

Arguments

Nu alle netwerk functies over losse documenten zijn uitgesplitst levert het zelden meer merge-conflicten op, en het is veel makkelijker om code terug te vinden.


3.3. Design Sub-System Spring boot backend:

De backend voor het HR Portaal is geschreven in Spring Boot. De backend is een belangrijk onderdeel van het eindproduct, en in dit hoofdstuk zullen de structuur en ontwerpbeslissingen van de backend worden toegelicht.

3.3.1. Design Class Diagram

Onderstaand is het class diagram voor de gehele backend van het HR Portaal. In dit diagram is gekozen om relaties aan te geven tussen klasses, als deze klasses een variable hebben voor de andere klasse. De DTO's worden veelal gebruikt binnen methodes in de resource klasses; dit wordt niet als relatie weergegeven, maar de DTO's staan wel in de buurt van de resources waar ze worden gebruikt.


3.3.2. Sequence Diagrams

De volgende GRASP principes zijn van toepassing op de sequence diagrammen:

  • Controller - Alle endpoints zijn aangemaakt in de resource classen. Deze laag handelt de UI interactie af.
  • High cohesion & low coupling - Door een hoge samenhang en lage afhankelijkheid zijn de classen minder afhankelijk van elkaar en is het makkelijker om de code uit te breiden
  • Information expert - De verantwoordelijkheden zijn toegekend aan de classen die de meeste informatie hebben om de verantwoordelijkheid te dragen.

Sequence diagram reserveren werkplek


Sequence diagram declareer reiskosten


Sequence diagram werkplek toevoegen


Sequence diagram inloggen

3.3.3. Design decisions made for the sub-system

Decision

Description

Problem/Issue

Backend code moet zoveel mogelijk losgekoppeld worden en los van elkaar werken.
Decision Er is besloten om een lagen-structuur in de backend aan te brengen, waarbij alle features worden opgedeeld over resources, services, dto's, dao's en data mappers.
Alternatives In plaats van de huidige lagen-structuur, had er gekozen kunnen worden om alle code die bij een feature hoort bij elkaar te plaatsen. Dus een folder voor alle componenten die te maken hebben met het reserveren van een werkplek.
Arguments De huidige lagen-structuur geeft duidelijk overzicht van welke componenten in de backend afhankelijk zijn van welke andere componenten. Dit maakt het makkelijker om bestaande code te hergebruiken over meerdere features, en om te garanderen dat de afhankelijkheid binnen lagen klein blijft.

Decision

Description

Problem/Issue

Er moest een framework gekozen worden om de backend in te maken.
Decision Er is gekozen om Spring Boot te gebruiken voor de backend.
Alternatives Het alternatief zou zijn om weer JAX RS te gebruiken net als bij DEA.
Arguments Spring Boot is een volledig framework wat makkelijk te leren en gebruiken is. Ook was de voorkeur vanuit de opdracht dat Spring Boot zou worden gebruikt.

Decision

Description

Problem/Issue

Er moet data in de vorm van JSON worden opgehaald uit- en gestuurd naar de front-end.
Decision Er is besloten om de communicatie met de front-end zoveel mogelijk af te handelen via DTO's. Dit betekend dat er een DTO bestaat om een verlof aanvraag naar de front-end van het verlof overzicht te sturen, en ook een DTO voor de verlofkeuring die vanuit de front-end naar de backend wordt gestuurd (in dit geval wordt er JSON opgestuurd die automatisch naar de gespecificeerde DTO wordt omgezet).
Alternatives In plaats van DTO's zou het mogelijk zijn om de JSON code zelf op te bouwen in de backend. Of om meer path-variabelen te gebruiken.
Arguments Zelf de JSON opbouwen zou een stuk foutgevoeliger zijn, omdat op die manier zelf de syntax moet worden geschreven. Met een DTO wordt dit automatisch gedaan en is het alleen van belang dat de naamgeving overeenkomt tussen de front-end en de backend.

Decision

Description

Problem/Issue

Toevoegen van een werkplek op een niet bestaande locatie zou een error opleveren.
Decision Er worden checks uitgevoerd die kijken of de locatie al bestaat.
Arguments Door checks te doen wordt er gezorgd voor een extra stukje veiligheid in de applicatie.

Decision

Description

Problem/Issue

Verwijderen van een reservering zou dubbele code opleveren, omdat dit erg lijkt op het toevoegen van een reservering.
Decision Tijdens het reserveren wordt er een boolean meegegeven of de reservering verwijderd moet worden. Op deze manier kan aan de hand van dezelfde gegevens efficiënt een reservering verwijderd worden.
Alternatives Het alternatief zou zijn om een nieuwe methode in de werkplek service te bouwen die grotendeels overeenkomt met de bestaande methode.
Arguments De belangrijkste reden om de functionaliteit samen te voegen is dat het dubbele code voorkomt, omdat er maar een methode nodig is in plaats van twee die op elkaar lijken.

Decision

Description

Problem/Issue

Een reis kan worden gedeclareerd met twee locaties, waarbij de afstand door het systeem wordt berekend. Het kan ook worden gedeclareerd met de kilometers, en dan hoeft er niks te worden berekend.
Decision Er is besloten om beide methodes te ondersteunen, afhankelijk van het reistype. Zo wordt een OV reis aan de hand van een afstand gedeclareerd, en voor een reis tussen werklocaties kan door de werknemer gekozen worden of hij/zij de afstand wil declareren, of de locaties.
Alternatives Het alternatief was om de gebruiker niet van een keuze te voorzien, en altijd de afstand door het systeem te laten berekenen.
Arguments Er is besloten om beide methodes te ondersteunen, omdat de automatische berekening gebruikersvriendelijk en betrouwbaar is. Aan de andere kant was in communicatie van de opdrachtgever naar voren gekomen dat ook het declareren aan de hand van kilometers gewenst is. Daarom is gekozen om het allebei te implementeren.

Er is voor gekozen om gebruik te maken van een UUID token. De kans dat er 2 dezelfde tokens worden geregistreerd in het systeem die tegelijkertijd geldig zijn is zodanig klein dat dit dan ook niet wordt afgevangen. 


3.4. Database Design

Voor de database is er als eerst een Conceptual data model opgezet, dit diende als de basis voor het design van de database. Vervolgens is daar dit physical data model uitgekomen:


De database bestaat uit 10 tabellen, elke tabel is onderling gelinkt d.m.v. foreign keys. De tabellen zijn als volgt:

Werknemer:

Kolom Beschrijving
werknemerId het ID van de gebruiker
locatieNaam dit is de locatie naam die is gelinkt aan het adres van de gebruiker in de locatie tabel
voornaam de voornaam van de gebruiker
achternaam de achternaam van de gebruiker
gebruikersnaam de gebruikersnaam van de gebruiker om in te loggen op het portaal
wachtwoord het wachtwoord van de gebuiker, deze is gehashed in de database
aantalUur het totaal aantal verlof uren die de gebruiker nog over heeft
isBeheerder een boolean om aan te geven of de gebruiker een beheerder is of niet
isProductOwner een boolean om aan te geven of de gebruiker een product owner is of niet
isLeadLink een boolean om aan te geven of de gebruiker een lead link is of niet

Werktijden:

Kolom Beschrijving
werknemerId dit is het ID van de gebruiker die is gelinkt aan de werknemer in de werknemer tabel
dag de dag waarop de gebruiker werkt, deze zijn uitgedrukt in 0-4 waarbij 0 is maandag 1 is dinsdag enz.
startTijd de tijd waarop de gebruiker start met werken
eindTijd de tijd waarop de gebruiker eindigt met werken

Locatie:

Kolom Beschrijving
locatieNaam de naam van de locatie, dit is de identifier van de locatie
adres het adres van de locatie, dit is het adres + de plaatsnaam en postcode
coordinaten de coordinaten van het adres
soort de soort locatie, dit kan zijn: 'woonadres' of 'werkadres'

Route:

Kolom Beschrijving
routeNaam de naam van de route, dit is de identifier van de route, deze bestaat uit locatieA +  locatieB
locatieA het beginpunt van de route
locatieB het eindpunt van de route
afstand de afstand van de route berekend door de api

Werkplek:

Kolom Beschrijving
locatieNaam dit is de locatie naam die is gelinkt aan het adres van het kantoor in de locatie tabel
werkplekNaam de naam van de werkplek
soort de soort werkplek
capaciteit de capaciteit van de werkplek

WerknemerOpWerkplek:

Kolom Beschrijving
werknemerId dit is het ID van de gebruiker die is gelinkt aan de werknemer in de werknemer tabel
datum de datum waarop de werknemer op de werkplek is ingeschreven
locatieNaam dit is de locatie naam die is gelinkt aan de locatie naam in de werkplek tabel
werkplekNaam dit is de werkplek naam die is gelinkt aan de werkplek naam in de werkplek tabel

Verlof:

Kolom Beschrijving
verlofId het ID van de verlof aanvraag
werknemerId dit is het ID van de gebruiker die is gelinkt aan de werknemer in de werknemer tabel
startDatum de start datum van de verlof aanvraag
eindDatum de eind datum van de verlof aanvraag
startTijd de start tijd van de verlof aanvraag
eindTijd de eind tijd van de verlof aanvraag
status de status van de verlof aanvraag, dit kan zijn: 'accepted', 'pending on  PO', 'pending on Lead' of 'denied'
verlofUrenTotaal het totaal aantal uren dat is vrij gevraagd
reden de reden van de verlof aanvraag
beschrijving een optionele beschrijving voor de verlof aanvraag
opmerking een opmerking achtergelaten bij het goed/afkeuren van de aanvraag de de PO of Lead

ReiskostenDeclaratie:

Kolom Beschrijving
declaratieId het ID van de declaratie
werknemerId dit is het ID van de gebruiker die is gelinkt aan de werknemer in de werknemer tabel
type dit is het type declaratie die is gelinkt aan het tarief in de tarief tabel, dit kan zijn: 'woon-werk', 'thuis', 'ov' of 'klant'
datum de datum voor wanneer de declaratie geld
afstand de afstand van de declaratie
bedrag het bedrag van de declaratie
opmerking een opmerking bij het aanmaken van de declaratie
bijlage een optionele bijlage van de declaratie

Tarief:

Kolom Beschrijving
type het type voor een tarief, dit kan zijn: 'woon-werk', 'thuis', 'ov' of 'klant'
bedrag het bedrag dat bij het type hoort

Tokens:

Kolom Beschrijving
werknemerId dit is het ID van de gebruiker die is gelinkt aan de werknemer in de werknemer tabel
token het token van de gebruiker, deze wordt aangemaakt bij het inloggen
expires de expire datum van de token

3.4.1. Design decisions related to the database

Hieronder de beslissingen die wij hebben genomen met betrekking tot de database:

Decision

Description

Problem/Issue

Het opslaan van de dag bij werktijden.
Decision Bij het oplsaan van de dag hebben wij ervoor gekozen om dit te doen als een int in plaats van een string met daadwerkelijk: 'maandag', 'dinsdag' etc.
Alternatives Het wel opslaan als strings.
Arguments We hebben hiervoor gekozen omdat het zo makkelijker was voor zowel de frontend en de backend om er doorheen te kunnen lopen met bijv loops.

Decision

Description

Problem/Issue

Het ophalen van een verlof aanvraag of declaratie.
Decision In eerste instantie hadden wij primary keys opgesteld die bestond uit meerde kolommen, uiteindelijk hebben we ervoor gekozen een ID kolom toe te voegen.
Alternatives Het laten als een collectie van kolommen.
Arguments We hebben hiervoor gekozen omdat het zo makkelijker was om ze op te halen en je minder gegevens nodig had in zowel de front als backend om dit voor elkaar te krijgen.

Decision

Description

Problem/Issue

Afstanden berekenen voor een declaratie d.m.v. de Google API.
Decision Wij hebben ervoor gekozen een route tabel aan te maken om zo afstanden van routes op te slaan zodat we de Google API zo min mogelijk aan roepen om requests te besparen.
Alternatives Telkens de API aanroepen om de meest up to date afstand te krijgen.
Arguments We hebben hiervoor gekozen omdat we op deze manier requests besparen naar de API, je kan maar een bepaald aantal requests gratis doen voordat je moet gaan betalen.

Decision

Description

Problem/Issue

Afstanden uit routes halen.
Decision Wij hebben ervoor gekozen om de route tabel los te koppelen van de declaratie tabel, eerst waren deze gekoppeld.
Alternatives Routes wel koppelen aan de declaratie tabel. De foreign key op no action zetten.
Arguments We hebben hiervoor gekozen omdat we de declaraties los wouden hebben staan van de routes, als een route veranderd of weg gaat willen wij dat dit niks veranderd aan de al bestaande declaraties.

Decision

Description

Problem/Issue

Adressen oplaan om de afstanden te berekenen.
Decision Wij hebben ervoor gekozen om ook coordinaten op te slaan.
Alternatives Het adres gebruiken.
Arguments We hebben hiervoor gekozen omdat het met coordinaten is meer precies is en er ook geen probleem kan voorkomen als er 2 straten zijn die hetzelfde heten per ongeluk verward worden.

Decision

Description

Problem/Issue

Start en eindtijd van een verlof aanvraag opslaan.
Decision Wij hebben ervoor gekozen om de start en eindtijd op te slaan als een int.
Alternatives Een start en eind datetime gebruiken in plaats van ze opsplitsen.
Arguments We hebben hiervoor gekozen omdat het berekenen van de uren makkelijker ging met als ze een int waren.

Decision

Description

Problem/Issue

Bij de tabellen locatie, reiskostenDeclaratie, verlof en tarief zijn er types en soorten.
Decision Wij hebben ervoor gekozen om hier checks op te zetten.
Alternatives Geen checks gebruiken.
Arguments We hebben hiervoor gekozen om ervoor te zorgen dat iedereen dezelfde standaard gebruikt en deze overal overeen komen.

Decision

Description

Problem/Issue

Werknemers mogen wel meerdere klanten reizen maken op een dag maar niet meer dan 1 thuiswerk of woon-werk op een dag.
Decision Wij hebben ervoor gekozen om hier checks op te zetten met een functie die kijkt of als de declaratie thuis of woon-werk is, kijkt of er al een bestaat van een van die types.
Alternatives Geen check gebruiken.
Arguments We hebben hiervoor gekozen om ervoor te zorgen dat het inserten hiervan altijd goed verloopt en er geen declaraties in komen die er dus niet in zouden mogen staan.

4. List of Resources


Modeleer tool:

Miro. (z.d.-b). https://miro.com. Geraadpleegd op 12 mei 2022, van https://miro.com/app/dashboard/

UserEditsCommentsLast Update
Thijmen Schoonbeek 161875 days ago
Auto Mation 120942 days ago
Gino Janssen 120875 days ago
Niels Hoeven, van der 110877 days ago
Connor Newton 100875 days ago
Tobias Feld 11875 days ago

  • No labels

1 Comment

  1. <Provide a high level overview of the architectural design, for instance by means of an architectural sketch. Make sure you show at least all sub-systems, and links to external systems. The sketch can be informal. The use of UML is not required.>
    Beschrijving toevoegen en placeholder text weghalen
Write a comment…