• No results found

Back-end 

In document ReWarden (pagina 47-59)

4.3 “Aan welke voorwaarden moet de interface voldoen, zodat regels op een overzichtelijke en duidelijke manier 

5. Ontwerp en realisatie 

5.2.2. Technische toelichting 

5.2.2.4. Back-end 

De back-end van de applicatie is opgezet met een Rails JSON API, in dit hoofdstuk  wordt beschreven hoe de afhandeling van data gaat vanaf het moment dat deze  aankomt bij de controller van de API. 

5.2.2.4.1. Framework/programmeertaal 

De back-end is gebouwd met het Rails framework versie 6, deze versie is gebouwd  met de programmeertaal Ruby. Rails 6 is afhankelijk van een minimum versie 2.5 van  Ruby, om te kunnen draaien. Voor deze versie is Ruby 2.7 gebruikt. 

5.2.2.4.2. Rails 

Rails is een webframework dat gebruikt kan worden met een geïntegreerde  front-end of, wanneer de ‘--api’ flag aan het genereer commando van een nieuwe  applicatie wordt meegegeven, als JSON API. Omdat het gebruik van een losse  front-end applicatie meer flexibiliteit biedt, is in dit geval voor het laatste gekozen.  Voor dit project worden Rails Models gebruikt om de kenmerken en logica van de  back-end modellen te definieren en controllers voor het afhandelen van verzoeken  van de client applicatie. Meer informatie over de mogelijkheden die Rails biedt en de  manier waarop de API gebruikt kan worden is te vinden op: 

https://api.rubyonrails.org/​ en ​https://apidock.com/rails/browse 

5.2.2.4.3. Ruby 

Het Rails framework is gebaseerd op de programmeertaal Ruby, waarvan de maker  tracht om het er simpel uit te laten zien, met complexe mogelijkheden ‘onder de  motorkap’. Één van de belangrijkste concepten van Ruby is dat alles een object kan  zijn met zijn eigen attributen en acties. Waarbij bijvoorbeeld zelfs een getal een  object is met instantie variabelen en functies. Op ​https://docs.ruby-lang.org/en/2.7.0/  kan de documentatie van Ruby v2.7 gevonden worden.   

5.2.2.4.4. Database 

Het Rails framework beschikt met ActiveRecord over een prima database beheer  systeem. ActiveRecord is een zogenaamd Object Relational Mapping systeem dat  zorgt voor: 

- Beschrijving van modellen en hun data. 

- Beschrijving van de relaties tussen deze modellen. 

- Validatie van modellen voordat ze in de database worden opgeslagen.  - Database operaties kunnen doen op een object georiënteerde manier.  Postgres is een database die goed samengaat met Rails en ActiveRecord. Tevens  wordt deze door de opdrachtgever bij meerdere projecten reeds gebruikt. Daarom is  deze ook voor dit project gebruikt.  

5.2.2.4.5. Postgres 

Postgres is één van de meest gebruikte databases ter wereld. Het is een open source  object-relationele database, gebaseerd op SQL, waardoor objecten, klassen en 

Postgres kan gevonden worden op: ​https://www.postgresql.org/docs/​. 

5.2.2.4.6. Klassen & relaties 

In onderstaand klassendiagram worden de model, en dus database relaties binnen  de back-end applicatie weergegeven: 

 

   

Het model van de database in het systeem is gebaseerd op de datastructuur die is  ontworpen om regels in op te kunnen slaan. Binnen het systeem zijn er drie ‘hoofd’  tabellen: 

- Rule 

Een regel heeft een naam en en versie en één of meerdere Antecedenten en  één of meerdere Consequents (als relatie met het Action model).  

- Antecedent 

Hiervoor zijn de subclasses gespecificeerd die voorkomen in de datastructuur.  Zodat herkend kan worden wel type Antecedent het betreft.  

- Action 

Onderdeel van Rules als has_many attribuut ‘consequents’ 

5.2.2.4.6.1. Antecedents  - Event 

Dit antecedent type komt in iedere regel minimaal één keer voor. Een Event  heeft één of meerdere ‘event_attributes’, dit kunnen variabele waardes zijn  bijvoorbeeld wanneer een gebruikers id verwacht word. Of vaste waarden.  Wanneer er een ‘isAdmin’ Event attribute verwacht word bij een logged_in  event die true moet zijn. 

- Counts 

Counts kan tellen of een andere antecedent meer dan één keer voorkomt.  Bijvoorbeeld bij de regel ‘wanneer een logged_in event drie keer voorkomt’.  Dan heeft een Counts antecedent een amount van 3 en een Event met name  “logged_in” 

- Duration 

start_antecedents zijn de trigger voor het expertsysteem om de timer, 

gespecificeerd in ‘interval’ te starten. De timer wordt beeindigd wanneer deze  afloopt of alle end_antecedents zijn voorgekomen. 

- TimeUnit 

Deze start een timer gedurende een dag, week of maand. Als de timer afloopt  kijkt het expersysteem voor welke target_attributes van de Actions die aan de  regel verbonden zijn deze voorwaarde als true geevalueerd kan worden. Deze  krijgen dan de action_attributes uitgekeerd. 

  - NEq  - Eq  - GreaterThan  - GreaterThanOrEquals  - LessThan  - LessThanOrEquals 

Dit zijn alle zogenaamde vergelijkings antecedenten. Deze hebben een max  van twee ‘compare_attributes’, waarmee afgedwongen kan worden dat het  variabele attribuut ‘user_id’ die in twee antecedenten voorkomt, overeenkomt  middels de Eq antecedent, of juist niet met de NEq antecedent. 

 

- Action 

Een Action heeft één of meerdere ‘action_attributes’ dat bijvoorbeeld een  badge of een certificaat kan zijn die het platform kan toekennen. Daarnaast  één of meerdere ‘target_attributes’ waaraan de action_attributes worden  toegekend. 

 

 

 

6. Conclusie 

Het belangrijkst bij het doen van een onderzoek is uiteraard het trekken van 

conclusies en bediscussiëren van de uitkomsten van het onderzoek. In dit hoofdstuk  worden de conclusies puntsgewijs behandeld en worden aanbevelingen gedaan voor  verdere ontwikkeling van het project. 

6.1. Discussie 

Bij het ontwerpen van de datastructuur is geen rekening gehouden met het 

evaluatiemechanisme in het expertsysteem, zoals de data nu gestructureerd is, is het  mogelijk om allerlei soorten antecedenten aan een regel toe te voegen, waarbij  volgorde bijvoorbeeld bepalend kan zijn voor de manier van evalueren. Aangezien  niet getest kon worden met een expertsysteem kan niet gegarandeerd worden dat  het geheel een werkbaar systeem zal vormen of dat er mogelijk nog aanpassingen  nodig zijn aan de datastructuur. Daarnaast is voor nu aangenomen dat, wanneer er  het antecedent type period gebruikt wordt, de periode ingaat wanneer het 

expertsysteem begint met evalueren van events voor deze regel. Wellicht dat hier in  de toekomst nog een start- en einddatum aan toegevoegd kunnen worden zodat er  meer controle is over wanneer een regel actief is en wanneer niet. Op basis van de set  gedefinieerde regels is een aanname gedaan dat alle antecedent types zijn verwerkt  in het schema, mogelijk kunnen er nog regels bedacht worden waarvoor andere  antecedent types nodig zijn. Het huidige schema biedt in ieder geval een goede basis  om mee te beginnen en er is rekening gehouden met mogelijke uitbreidingen. Op  dit moment is er geen rekening gehouden met mogelijke wijzigingen van regels, of  het aan- en uitzetten van regels aan de kant van het expertsysteem. Zodra in de  webapplicatie een regel gewijzigd en opgeslagen wordt, betekent dit niet direct dat  het expertsysteem hier ook van op de hoogte is, dat kan zorgen voor 

miscommunicatie waardoor uiteindelijk onverwachte resultaten zouden kunnen  voorkomen, dat badges niet uitgekeerd worden terwijl dat wel zou moeten.  

6.2. Aanbevelingen 

De belangrijkste aanbeveling is, voordat er verder ontwikkeld wordt, een 

testopstelling te realiseren waarin het domein gesimuleerd wordt met een platform  dat events verstuurd, een expertsysteem dat deze events kan evalueren en de  applicatie behorende bij dit project om regels mee te maken en naar het  expertsysteem te verzenden. Hierdoor zullen eventuele haken en ogen die zijn  ontstaan door de ontwikkeling van het expertsysteem en de regel beheer applicatie  gelijktijdig te laten plaatsvinden, snel naar voren komen. Daarnaast wordt er een  vorm van authenticatie voor de applicatie geadviseerd, om te voorkomen dat  ongewenste gasten zomaar de applicatie kunnen benaderen wanneer deze op een  productieserver draait.   

7. Bronvermelding 

1. Nerds & Company, ‘​website’​, geraadpleegd op 11-02-2020: 

https://nerds.company/ 

2. Wikipedia, ​‘No-code development platform’, ​geraadpleegd op 14-02-2020: 

https://en.wikipedia.org/wiki/No-code_development_platform 

3. Wikipedia,​ ‘Low code’​, geraadpleegd op 14-02-2020: 

https://nl.wikipedia.org/wiki/Low_code 

4. E-learning.nl, ​‘Wat is e-learning?’, ​geraadpleegd op: 31-05-2020: 

https://www.e-learning.nl/Achtergrond.aspx 

5. M. Fowler (2005), ‘​Event sourcing’​, geraadpleegd op 21-02-2020: 

https://martinfowler.com/eaaDev/EventSourcing.html 

6. Microservices.io, ‘​Event sourcing’, ​geraadpleegd op: 21-02-2020: 

https://microservices.io/patterns/data/event-sourcing.html 

7. Medium, ‘​Event sourcing is awesome!’, ​geraadpleegd op: 24-02-2020: 

https://medium.com/jettech/event-sourcing-is-awesome-c4fe25ad24cd 

8. Wikipedia, ‘​Business rules’, ​geraadpleegd op 11-03-2020: 

https://en.wikipedia.org/wiki/Business_rule 

9. Wikipedia, ​‘Expertsysteem’​, geraadpleegd op: 27-02-2020: 

https://nl.wikipedia.org/wiki/Expertsysteem  

10. H. Streck (2016), ‘​Gamification’, ​geraadpleegd op 23-02-2020: 

https://www.managementboek.nl/code/inkijkexemplaar/9789492221322/gamifi

cation-horst-streck.pdf 

11. M. Jacobs, A. Coppens, R. Niels, N. Verhoeven e.a. (2015), ‘​Proeven van 

onderzoek: De methodenkaart in de beroepspraktijk van ICT & Media’​, 

geraadpleegd op 11-03-2020: 

https://www.researchgate.net/publication/277003225_Proeven_van_Onderzoe

k_De_Methodenkaart_in_de_Beroepspraktijk_van_ICT_en_Media 

12. A. Abraham (2005), ‘​Rule-Based Expert Systems’, ​geraadpleegd op 31-03-2020: 

http://03.softcomputing.net/fuzzy_chapter.pdf 

13. P.J.F. Lucas & L.C. van der Gaag (1991), ‘​Principles of Expert Systems’,  geraadpleegd op 22-03-2020: ​https://www.cs.ru.nl/P.Lucas/proe.pdf  14. Wikipedia, ​‘XML-Schema’​, geraadpleegd op 01-06-2020: 

https://nl.wikipedia.org/wiki/XML_Schema 

15. Medium, ​‘How to use YAML Schema to validate your YAML files’,   geraadpleegd op 01-06-2020: 

https://blog.picnic.nl/how-to-use-yaml-schema-to-validate-your-yaml-files-c82

c049c2097 

16. JSON Schema,​ ‘website’​, geraadpleegd op 10-03-2020: 

https://json-schema.org/ 

17. JSON Schema, ​‘getting started’​, geraadpleegd op 10-03-2020: 

https://json-schema.org/learn/getting-started-step-by-step.html 

18. JSON Schema, ​‘properties’, ​geraadpleegd op 10-03-2020: 

https://json-schema.org/understanding-json-schema/reference/object.html#p

roperties 

19. Wikipedia, ​‘Grafische gebruikersomgeving’​, geraadpleegd op 15-04-2020: 

https://nl.wikipedia.org/wiki/Grafische_gebruikersomgeving 

20. Scrumguide, ​‘Wat is scrum?’​, geraadpleegd op 01-06-2020: 

https://scrumguide.nl/wat-is-scrum/ 

21. Trello, ​‘website’​, geraadpleegd op 01-06-2020: 

https://trello.com/nl/tour 

22. VSCode, ​‘website’​, geraadpleegd op 01-06-2020: 

https://code.visualstudio.com/ 

23. GitHub, ​‘website’​, geraadpleegd op 01-06-2020: 

https://github.com/ 

24. Docker, ​‘website’​, geraadpleegd op 01-06-2020: 

https://www.docker.com/products/docker-desktop 

25. C’t, ​‘Docker met Linux in de praktijk: de kracht van containers’​, geraadpleegd  op 01-06-2020: 

https://www.ct.nl/achtergrond/docker-containers-onder-linux-praktijk/  

26. Medium (2019), ​‘Phoenix vs. Rails benchmarks’​, geraadpleegd op 01-06-2020: 

https://medium.com/@elviovicosa/phoenix-vs-rails-benchmark-2019-f0e68336

d557 

 

 

8. Bijlagen 

{

​"$schema": ​"http://json-schema.org/draft-07/schema#"​,

"$id": ​"http://github.com/nerds-and-company/rewarden-specifications/schema.json"​, "title": ​"Rule schema"​,

"description": "A schema to which rules for the Rewarden system must resolve", "type":​ "object"

"properties": {

"name": { "type": "string" },

"version": { "enum": [​"0.1"​, ​"0.2"​] }, "antecedents": { "type": ​"array"​, "contains": { "$ref": ​"#/definitions/requiredAntecedent" },

"items": { "$ref": ​"#/definitions/antecedent"​ }, "minItems": 1 }, "consequents": { "type": "array", "contains": { "$ref": ​"#/definitions/action" },

"items": { "$ref": "#/definitions/action" }, "minItems": ​1

},

"additionalProperties": ​false​,

"required": ["name", "version", "antecedents"], }, "definitions": { ​ "requiredAntecedent": { "type": "object", "oneOf": [ { "$ref": ​"#/definitions/antecedents/event"​ }, { "$ref": "#/definitions/antecedents/duration" }, { "$ref": "#/definitions/antecedents/period" }, { "$ref": ​"#/definitions/antecedents/time_unit"​ }, { "$ref": ​"#/definitions/antecedents/count"​ } ] }, "antecedent": { "type": "object", "oneOf": [ { "$ref": ​"#/definitions/requiredAntecedent"​ }, { "$ref": ​"#/definitions/antecedents/equal"​ }, { "$ref": ​"#/definitions/antecedents/not_equal"​ },  

{ "$ref": "#/definitions/antecedents/greater_than" }, { "$ref": ​"#/definitions/antecedents/greater_than_or_equal"​ }, { "$ref": ​"#/definitions/antecedents/less_than"​ }, { "$ref": "#/definitions/antecedents/less_than_or_equal" } ] }, "antecedents": { "event": { "type": ​"object"​, "properties": {

"type": { "const": ​"event"​ }, "name": { "type": "string" }, "attributes": {

"type": ​"array"​,

"items": { "$ref": ​"#/definitions/eventAttribute"​ }, "minItems": 1

} },

"required": ["type", "name", "attributes"], "additionalProperties": ​false

},

"duration": { "type": "object", "properties": {

"type": { "const": ​"duration"​ },

"interval": { "type": ​"integer"​, "minimum": ​1​ }, "start_antecedents": {

"type": ​"array"​,

"items": { "$ref": ​"#/definitions/antecedent"​ }, "minItems": 1

},

"end_antecedents": { "type": ​"array"​,

"items": { "$ref": "#/definitions/antecedent" }, "minItems": ​1

} },

"required": ["type", "interval", "start_antecedents", "end_antecedents"], "additionalProperties": ​false

},

"​period​"​: {

"type": "object", "properties": {

"type": { "const": ​"period"​ },

"interval": { "type": "integer", "minimum": 1 }, "antecedents": {

"type": ​"array"​,

"items": { "$ref": ​"#/definitions/antecedent"​ }, "minItems": 1

"required": [​"type"​, ​"interval"​, ​"antecedents"​], "additionalProperties": false }, ​"​time_unit​"​: { "type": ​"object"​, "properties": {

"type": { "const": ​"time_unit"​ },

"interval": { "enum": [​"hour"​,​ "day"​, "week"​ ​, ​"month"​, ​"year"​] }, "amount": { "type": ​"integer"​, "minimum": ​1​ },

"antecedents": { "type": ​"array"​,

"items": { "$ref": ​"#/definitions/antecedent"​ }, "minItems": ​1

} },

"required": [​"type"​, ​"amount"​, ​"antecedents"​], "additionalProperties": false

},

"count": {

"type": ​"object"​, "properties": {

"type": { "const": ​"count"​ }, "antecedents": {

"type": ​"array"​,

"items": { "$ref": "#/definitions/antecedent" }, "minItems": ​1

},

"amount": { "type": "integer", "minimum": 1 } },

"required": [​"type"​, ​"antecedents"​, ​"amount"​], "additionalProperties": ​false

},

​ "equal": {

"type": ​"object"​, "properties": {

"type": { "const": "equal" }, "compares": {

"type": ​"array"​,

"items": { "$ref": ​"#/definitions/compareAttribute"​ }, "minItems": 2

} },

"required": ["type", "compares"], "additionalProperties": false

},

​ "not_equal": { "type": "object",

"properties": {

"type": { "const": ​"not_equal"​ }, "compares": {

"type": "array",

"items": { "$ref": ​"#/definitions/compareAttribute"​ }, "minItems": ​2

} },

"required": [​"type"​, ​"compares"​], "additionalProperties": ​false

},

"greater_than": { "type": ​"object"​, "properties": {

"type": { "const": ​"greater_than"​ }, "compares": {

"type": ​"array"​,

"items": { "$ref": ​"#/definitions/compareAttribute"​ }, "minItems": 2

} },

"required": [​"type"​, ​"compares"​], "additionalProperties": false

},

​ "greater_than_or_equal": { "type": ​"object"​,

"properties": {

"type": { "const": ​"greater_than_or_equal"​ }, "compares": {

"type": "array",

"items": { "$ref": "#/definitions/compareAttribute" }, "minItems": ​2

} },

"required": [​"type"​, ​"compares"​], "additionalProperties": ​false

},

"less_than": { "type": ​"object"​, "properties": {

"type": { "const": ​"less_than"​ }, "compares": {

"type": ​"array"​,

"items": { "$ref": ​"#/definitions/compareAttribute"​ }, "minItems": 2

} },

"required": [​"type"​, ​"compares"​], "additionalProperties": false  

"type": ​"object"​, "properties": {

"type": { "const": ​"less_than_or_equal"​ }, "compares": {

"type": ​"array"​,

"items": { "$ref": "#/definitions/compareAttribute" }, "minItems": ​2

} },

"required": ["type", "compares"], "additionalProperties": ​false } ​}, "action": { "type": ​"object"​, "properties": {

"type": { "const": "action" }, "rule_name": { "$ref": ​"#/name"​ }, "attributes": {

"type": ​"array"​,

"items": { "$ref": "#/definitions/actionAttribute" }, "minItems": ​1

},

"targets": { "type": "array",

"items": { "$ref": ​"#/definitions/actionAttribute"​ }, "minItems": ​1

} },

"required": [​"type"​,​ "rule_name", ​ ​"attributes"​, ​"targets"​], "additionalProperties": ​false }, "eventAttribute": { "type": ​"object"​, "oneOf": [ { "$ref": "#/definitions/eventAttributes/variable" }, { "$ref": ​"#/definitions/eventAttributes/value"​ } ] }, "eventAttributes": { "variable": { "type": ​"object"​, "properties": {

"type": { "const": "variable" }, "name": { "type": ​"string"​ }, "key": { "type": ​"string"​ } },

"required": ["type", "name", "key"], "additionalProperties": ​false }, "value": { "type": ​"object"​, "properties": {

"type": { "const": ​"value"​ }, "name": { "type": "string" },

"value": { "type": [​"string"​, ​"number"​, "integer"​ ​, ​"boolean"​, ​"null"​] } },

"required": [​"type"​, ​"name"​, ​"value"​], "additionalProperties": false } }, "actionAttribute": { "type": "object", "properties": {

"type": { "type": ​"string"​ }, "id": { "type": "string" } },

"required": [​"type"​, ​"id"​], "additionalProperties": ​false } } }    

In document ReWarden (pagina 47-59)

GERELATEERDE DOCUMENTEN