Detailed Design Description
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.
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.
Design Sub-System A: Invullen flexwerkplek schema
<Do not really name the section “Sub-System A”, use a name that describes the responsibility of the sub-system, instead. Provide a section for each sub-system. These sections are iteratively added and refined during the sprints. Examples of sub-systems include Persistent Storage, Business Tier, Web Application, Webservice API. The sub-sections below may be extended if you think this is useful for describing the software design. The sub-sections below are only required for object-oriented sub-systems. Use other means to describe non-OO sub-systems (for instance Javascript modules).>
Design Class Diagram
<Object-oriented sub-systems should be described using a class diagram. If classes or interfaces are used across sub-systems, make sure you mention this in the description of the class diagrams. If your system entails layers, make sure you indicate this in the class diagram, e.g. by means of packages. For each class diagram, make sure you also mention the deployment artifact (from the deployment diagram) it is part of.>
Sequence Diagrams
<Provide sequence diagrams for major object interactions within the sub-system. It is ok if sequence diagrams cross sub-system boundaries. Make sure you explain this in the description of the diagram. Sequence diagrams must be consistent with the class diagrams described above. Also, if sequence diagrams cover interaction with users, make sure the diagrams are consistent with SDDs you may have documented as part of the SRS.>
Activity and State Diagrams
<This section is optional. If useful, provide activity and/or state diagrams to describe complex work flows and system state transitions>
Design decisions made for the sub-system
<Describe all design decisions made for the sub-system. Provide at least decision descriptions for all frameworks, libraries and other technologies used. Other decisions may be related to software patterns, system-structure, adapted principles or the like.>
Decision | Description |
---|---|
Problem/Issue | A short description of the design problem. |
Decision | A short description of the design decision. |
Alternatives | What are the alternatives for this decision? Are there any alternative diagrams to support this? |
Arguments | Which criteria were crucial for the decision? |
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.
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.
Sequence Diagrams
Sequence diagram reserveren werkplek
Sequence diagram declareer reiskosten
Sequence diagram werkplek toevoegen
Sequence diagram inloggen
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 bijvoorbeeld alle code die bij een feature hoort bij elkaar te plaatsen. Dus bijvoorbeeld 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 bijvoorbeeld 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 bijvoorbeeld 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 bijvoorbeeld 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 bijvoorbeeld 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.
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 |
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. |