ID: S202512221450 Status: school Tags: Avans 2-1 LU1, Presentatie

Avans 2-1 POC presentatie

Welkom bij de Avans Elective Hub. Dit is de Proof Of Concept voor de nieuwe keuzen module app van avans.

Stack keuze

Mijn app is gemaakt met React en NestJS en een zelfgehoste MongoDB container op mijn Docker vps. Bij het uitzoeken van frameworks had ik 2 dingen die ik belangrijk vond: het moest goed werken op mobile. Het moest werken met MongoDB en TypeScript. Nu bleek al snel dat een framework niet bepaald hoe goed iets werkt op mobile, en dat de frontend niks te maken heeft met de database die je kiest. Hoe ben ik dan wel op gekomen op React? Nou in de meeste frameworks zit niet echt een verschil, de grootste reden dat developers tegenwoordig een framework aan zullen raden is hun eigen bias. Dus toen ben ik gaan kijken naar de onderzoeks vragen.

CriteriumReactAngularSvelteVue
1. Leesbaarheid & Voorbeelden8/106/109/109/10
2. TypeScript Ondersteuning8/1010/109/109/10
3. Community Grootte (Actief)10/107/106/108/10
4. Framework Onderhoud & Updates9/109/108/109/10
5. CLI & Startsjablonen8/109/108/109/10
6. Documentatie Kwaliteit8/109/109/109/10
7. Bundle Size Performance7/104/1010/108/10
8. Extensibility & Libraries10/108/107/109/10
9. Bedrijfsadoptie & Jobmarkt10/107/105/108/10
10. Toekomstbestendigheid (2026-2029)9/108/107/109/10
TOTAAL87/10077/10078/10087/100

Nu zie je hier dat Vue en React bovenaan staan, maar wat was dan de doorslaggevende klap? BIAS. Ik had bij het eerste onderzoek alleen artikelen gelezen van React developers wat er voor zorgde dat mijn data een BIAS had naar react toe, en pas bij de herkansing kwam ik er eigenlijk as achter hoe dicht de frameworks op elkaar staan. De belangrijkste verschillen tussen React en Vue zijn dat React een grotere community heeft met dus ook meer plugins en bedrijfsadoptie, waar vue meer / betere documentatie heeft, meer ssjablonene en meer voorbeelden. Achteraf gezien zou ik zijn gegaan voor Vue omdat ik daar nog geen kennis mee had, maar ik ging niet voor de herkansing helemaal opnieuw beginnen.

Hoe zit het met de backend? Nou daar is het verschil een stuk groter.

CriteriumExpressNestJSFastify
1. Leesbaarheid & Voorbeelden9/108/108/10
2. TypeScript Ondersteuning5/1010/108/10
3. Community Grootte (Actief)10/108/106/10
4. Framework Onderhoud & Updates8/109/108/10
5. CLI & Startsjablonen3/1010/104/10
6. Documentatie Kwaliteit8/1010/108/10
7. MongoDB Integratie & ORM Support8/109/108/10
8. Built-in Testing & DI4/1010/106/10
9. Bedrijfsadoptie & Jobmarkt9/108/105/10
10. Toekomstbestendigheid (2026-2029)8/109/108/10
TOTAAL82/10091/10073/100

NestJS heeft een betere typescript ondersteuning, betere documentatie en heeft ingebouwde testing dan express js en fastify.

Onion architectuur

Mijn project heeft de ONION architecture toegepast. Dit zijn de lagen:

  1. Domain, dit zijn de Entities en interfaces. data structuur en niks meer.
  2. Application, dit zijn de use cases en de DTOs. Use cases zijn single responsability en afhankelijk van de entities en interfaces van laag 1.
  3. Infrastructure, De repositories en de mappers. Mappers worden gebruikt om te converteren tussen de Entities van laag 1 en de database modellen. Ook is er een persistence module die de dependency injection regelt.
  4. Presentation, dit zijn de controllers die dus alles aansturen gebaseerd op webrequests.

Nu is het onion architectuur een beetje misleidend, want het doet zich voor alsof het allemaal lagen zijn die op elkaar liggen, maar dan kom je aan bij de Infrastructure laag en dan klopt het niet echt, want de infrastructure laag zorgt er voor dat de dependency injection van de domain in de application laag werkt, dus eigenlijk moet de infrastructure laag tussen application en domain, als je kijkt in de logica van ā€œalleen depending op lagen er onderā€, maar dat klopt dan ook weer niet, dus daarom duurde het even voordat het klikte, en vind ik dat de bovenstaande schemas accurater zijn.

Realisatie

In mijn Proof of concept kan je inloggen als docent, admin en student. Als docent kan je modules toevoegen en studies aanpassen. Als admin kan je de vertalingen van de website aanpassen. Als student kan kan je een studie selecteren, en dan gebaseerd op je studie krijg je aanbevolen keuzen modules. Dit werkt zo want aan de studie en keuzenmodules hangen tags en op die manier ā€œcross referencenā€ we de modules aan je studie. Dit vond ik het logischte voor deze POC want ik ging geen AI maken voor de POC.

Verder kan je als student ook favorieten selecteren, modules bekijken, filteren op modules. Ook is het mogelijk om deze app te installeren als PWA.

Voor het eindproduct moeten we denken aan de gebruiksvriendelijkheid, dus ik heb me veel gefocussed op het vertalen van alles. Alle text in de app is aanpasbaar door een admin of docent. En het nut hiervan is dat je engels en nederlands kan kiezen. dit vodn ik belangrijk aangezien avans ook veel engelse studenten heeft.

Requirements

Ik heb een hele waslijst met functionele requirements:

EpicRequirementBeschrijving
1FR1.1Student kan een lijst van beschikbare keuzemodules bekijken
1FR1.2Student kan keuzemodules filteren op studiepunten (15 of 30 EC)
1FR1.3Student kan keuzemodules filteren op niveau (NLQF-5 of NLQF-6)
1FR1.4Student kan keuzemodules filteren op tags
1FR1.5Student kan alle beschikbare tags bekijken
2FR2.1Student kan gedetailleerde informatie over een keuzemodule bekijken (beschrijving, EC, type)
2FR2.2Student kan keuzemodules aan favorieten toevoegen
2FR2.3Student kan ā€œmeer infoā€ knop gebruiken voor aanvullende details
3FR3.1Student kan keuzemodules als favorieten opslaan
3FR3.2Student kan keuzemodules uit favorieten verwijderen
4FR4.1Student kan aanbevolen keuzemodules zien op basis van studierichting
4FR4.2Aanbevelingen worden gegenereerd via een statisch/mock algoritme
5FR5.1Gebruiker kan tussen Nederlands en Engels schakelen
6FR6.1Student kan de app op telefoon installeren als PWA
7FR7.1Communicatie tussen frontend en backend gebruikt JWT voor beveiliging
7FR7.2Geen secrets of API-sleutels zijn hardcoded in code
7FR7.3Mislukte requests worden elegant afgehandeld met duidelijke foutmeldingen
8FR8.1Student kan een account registreren
8FR8.2Docent kan een account registreren
8FR8.3Student kan inloggen op account
8FR8.4Docent kan inloggen op account
8FR8.5Gebruiker blijft ingelogd na browser sessie sluiten
8FR8.6Gebruiker kan uitloggen
8FR8.7Gebruiker ziet duidelijke foutmeldingen bij mislukte login
9FR9.1Docent kan nieuwe keuzemodules toevoegen
9FR9.2Docent kan bestaande keuzemodules bewerken
9FR9.3Docent kan keuzemodules verwijderen
10FR10.1Docent kan vertalingen van keuzemodules bewerken
10FR10.2Docent kan vertalingen van website UI bewerken
10FR10.3Docent kan ongebruikte vertalingen bekijken
10FR10.4Docent kan ongebruikte vertalingen verwijderen
11FR11.1Student kan een studierichting selecteren
11FR11.2Docent kan nieuwe studies toevoegen
11FR11.3Docent kan studies bewerken
11FR11.4Docent kan studies verwijderen
11FR11.5Student kan eigen ingeschreven studierichting bekijken

Non functional requirements:

EpicRequirementBeschrijving
5NFR5.1Applicatie ondersteunt meerdere talen (Nederlands, Engels)
6NFR6.1Applicatie functioneert als Progressive Web App
6NFR6.1aApp kan offline werken met caching
6NFR6.1bApp kan op homescreen geĆÆnstalleerd worden
7NFR7.1JWT tokens beveiligen API communicatie
7NFR7.2Geen hardcoded secrets in broncode
7NFR7.3Graceful error handling voor alle requests
8NFR8.1Sessies blijven behouden over browser refresh
8NFR8.2Foutmeldingen zijn duidelijk en informatief

Testing

Testing was een belangrijk en nieuw deel, ik had al een keer eerder gewerkt met cypress, de front-end testing. Maar nog niet met een built-in testing framework zoals in NestJS zit.

Cypress

Ik gebruik Cypress om testen uit te voeren op de website. Hiermee kan ik testen of dat de functionaliteit het zelfde blijft. Zodra ik push naar main stuur doen we een cypress test, en als die een ā€œsuccessā€ teruggeeft wordt mijn website gedeployed met CICD.

Waar test ik op? de meeste van mijn testen zijn om te kijken of dat je wel weggestuurd wordt als je een pagina bekijkt waarvoor je rechten moet hebben, wanneer je die rechten niet hebt. Een student die de beheer pgina bekijkt, of niet ingelogd zijn op de profiel pagina.

Unit testing

In de backend gebeurt iets soortgelijks, wanneer ik push naar main worden testen uitgevoerd, en als die goed zijn dan pas wordt de rest van de CICD gedaan. De backend testen zijn een feature van NestJS.

image of the unit tests that succeeded and currently is running a deploy

Waar test ik op? De grootste gedeelte van mijn testen zijn validatie van het json formaat dat de api endpoints teruggeven. Maar ook tesen op de gebruikers input om te kijke of de limitaties nogsteeds werken. Op elk endpoint zijn er testen toegevoegd.

CICD

Ik heb alles zelfgehost behalven de react app. De mongodb container draait op mijn VPS. Ik verind hiermee via de mongodb compass app, en in de backend via Mongoose. Mijn backend wordt ook gedraaid op deze VPS. Zodra ik commit op Main doet CICD mijn unit testen, en als die succeeden dan maak ik een Docker container. Daarna gaat de CICD via SSH mijn VPS in en deployed hij de nieuwe docker container. Op deze manier gaat het compleet automatisch. Mijn frontend wordt gehost op github pages, aangezien het een statische front-end is. Maar het is een half uurtje werk om dat om te zetten op een vergelijkbare manier als de backend. Het is wel belangrijk om te vermelden dat er geen credentials staan in mijn CD, dezen staan allemaal in de repository secrets.

Ook is het mogelijk om een andere versie die niet de nieuwste is te deployen als een rollback nodig is, want we gebruiken dockerub.

image of dockerhub

Database

Ik gebruik mongodb, maar ik heb het ingedeeld als een relationele database. Ik weet dat het idee van mongodb is dat je veel data er gewoon in kan kwakken, maar ik heb de approach gekozen die voor mij het logischte leek qua uitbereidbaarheid en leesbaarheid. Ik heb hierbij wel lijsten gebruikt met ID’s naar andere elementen. En achteraf gezien zou ik de studie en keuzenmodule collectie samen kunnen voegen. Maar hier heb ik niet aan gedacht tijdens het ontwerpen.

De reden dat ik overal ID’s gebruik in plaats van het behouden van data is omdat ik niet hou van duplicate data, ik heb tijdens dit project ook met de vertalingen het zo gedaan dat vertalingen hergebruikt worden als ze het zelfde zijn. Dit is gedaan uit de reden dat als ik 1 aanpassing maak ik het overal aangepast wil hebben, en omdat ik efficient wil omgaan met opslag.

Demo

Als we gaan kijken kunnen we inloggen als henk, henk is een student, Henk kan dus ook niet het management tabje zien. Als we gaan naar het profiel zien we dat henk architectuur studeert. Als we dan gaan kijken bij de aanbevolen modules zien we een 40% match met interieur ontwerp. Dit komt omdat de tags van de module overeen komen met die van zijn studie. Nou willen we dat natuurlijk in het echte project doen met AI. Nu we kijken naar deze module kunnen we hem toevoegen aan onze favorieten. en als we dan terug gaan naar de lijst zie we hem bij favorieten staan. nu is deze demo vanaf de geinstalleerde app, want we hebben PWA support. als ik nu itlog en inlog als mara zen we de beheer functies. Hier kunnen we bijvoorbeeld de keuzen modules aanpassen. Verder kunnen we ook de studies aanpassen, of de vertaling van de app.

Wat zou ik anders doen

De volgende keer zou ik beter onderzoek willen doen naar het framework want mijn informatie was vooral BIASED door react developers. Ook zou ik van tevoren een database schema maken waardoor ik dingen die erg op elkaar lijken kan samenvoegen, want mijn studie en keuzenmodule collectie zijn grotendeels het zelfde.


References