Giter Site home page Giter Site logo

waecm-group-09's Introduction

Web Application Engineering & Content Management

Branch CI-Status
Master master
Develop develop

Gruppenteilnehmer

Name Matrikelnummer
Sigrid Huemer 51824175
Elena Nuiding 11925876
Maximilian Schönenberg 11931241
Alicia Schwabenbauer 11925878

Technologieauswahl

Frontend

Bei der Frontend Entwicklung wird React mit TypeScript verwendet. React ist vor allem schnell und gut skalierbar. Zudem weist React einen großen Marktanteil auf und ist aus diesem Grund eine Technologie, mit welcher sich Entwickler beschäftigen sollten. TypeScript wiederum hat eine starke Typisierung und verringert somit die Anzahl der Laufzeitfehler. Für das Styling wird Material UI, ein React UI Framework, welches sich an Material Design orientiert, verwendet. Es bietet eine breite Auswahl an vordefinierten Styles und Komponenten, sowie eine gute Dokumentation.

Backend

Im Backend verwenden wir das Framework Nest.js, da dieses design patterns wie MVC und Decorators in Node.js bringt. Nest.js hat eine gute Unterstützung für GraphQL APIs und bietet dafür einige interne Libraries. Ein großer Vorteil ist, dass bei der Verwendung von TypeScript der "code first approach" in Nest.js genutzt werden kann, um stark typisierte GraphQL schemas zu generieren.

Kommunikation

Für die Kommunikation wurde GraphQL verwendet, da es sowohl flexibler als auch effizienter als REST ist. Im Gegensatz zu REST reicht bei einer GraphQL-API eine einzige Anfrage an den Server aus, um alle relevanten Daten zu erhalten. Dadurch löst GraphQL das Problem, dass oft entweder zu viele oder zu wenige Daten abgerufen werden und ist somit ein aufsteigendes API-Konzept.

Datenbank

Bei der Datenbank wurde MongoDB ausgewählt, da ein guter Library-Support für die ausgewählte Backend-Technologie besteht, sowie die Daten - Konfigurationen von Subreddits - gut als Dokument gespeichert und durchsucht werden können.

Continuous Integration

Für die Continuous Integration wurde Github Actions als CI-Technologie und Github Packages als Build-Artefact-Speicher (in diesem Fall als Docker-Registy) ausgewählt, damit auf einer einzigen Plattform das gesamte Projekt gemanaged werden kann. Zudem gibt es dadurch am wenigsten Berechtigungsprobleme.

Linter Aufruf

Der Linter wird im Frontend und im Backend über npm run lint aufgerufen.

Containerisierung

Wichtig: Vor dem ersten Starten die Umgebungsvariablen setzen !

Die Applikation kann mittels docker-compose -f docker-compose-a3.yaml up gestartet werden. Das Frontend ist auf localhost:3000 erreichbar.

Um die Docker-Images von Source zu bauen und zu starten, kann dies einfach mit docker-compose up --build erreicht werden.

In dieser Aufgabe ist zum Deployment die Datenbank MongoDB hinzugekommen. Diese wird beim Starten des Docker-Compose mit gestartet. Nur das Backend kann diese erreichen, da Backend und Datenbank zusammen ein Docker-Netzwerk bilden. Damit die Datenbank persistent ist, wird ein Docker-Volume gemountet.

Das Backend nutzt node:12.2-alpine als Basis-Image, kompiliert dieses zu einem Production-Build und stellt dieses daraufhin in einem neuen Image node:12.2-alpine auf Port 8080 bereit. Für diesen Build wird ein Multi-Stage-Build verwendet, um die Kompilierungszeit (durch Layer-Caching) zu reduzieren, und dennoch ein minimales Build-Image zu erhalten.

Das Frontend wird ebenfalls mit einem Multi-Stage-Build kompiliert und in ein nginx:1.17.9-Image installiert. Mit diesem Build werden ebenso die Ziele verfolgt die Kompilierungszeit (durch Layer-Chaching) möglichst gering zu halten, möglichst wenige Layer im Result-Image zu haben, sowie nicht den Quellcode, sondern nur die kompilierten und gebundelten Dateien im Result-Image zu installieren.

Continuous Integration (CI)

Für die CI wird in diesem Projekt Github Actions verwendet. Diese kompiliert automatisiert jeden Git-Push (sollten mehrere Commits auf einmal gepushed werden, wird nur der letzte gebaut).

Da das Frontend und das Backend als Docker-Images ausgeliefert werden sollen, werden diese direkt mit Docker von der CI gebaut. Die fertigen Images werden auf die Github Packages - Docker-Registry gepushed.

Die gebauten Docker-Images können wie im Bild gezeigt, gefunden werden: Hier sollte ein Bild zu sehen sein!

Sollte es zu einem Fehler während eines Builds kommen, wird der Committer per E-Mail benachrichtigt.

Manuelles Triggern eines Builds

Das manuelle Triggern der Github Actions ist noch ein Feature Request und aktuell noch nicht möglich, jedoch kann ein bereits durchgeführter Commit, erneut durchgeführt werden:

  1. Klicke auf Actions im oberen Reiter.
  2. Wähle einen Build aus.
  3. Klicke auf der linken Seitenleiste auf den Workflow build.
  4. Klicke auf den Button Re-run jobs.

Konfiguration

Die Konfiguration des Backends wird über Environment-Variablen, die in der Docker-Compose-Datei eingetragen werden konfiguriert:

Variable Required Default-Value Description
REDDIT_USERNAME Yes The Reddit Username for the Bot.
REDDIT_PASSWORD Yes The Reddit Password for the Bot.
REDDIT_CLIENT_ID Yes The Reddit Client ID for the Bot.
REDDIT_CLIENT_SECRET Yes The Reddit Client-Secret for the Bot.
COMMENT_LIMIT No 5 Limits the Bot to how many comments per run should be read.
SECONDS_UNTIL_UPDATE No 30 Interval in Seconds for the Bot.
EXTRA_KEYWORD No waecm-2020-group-09 Adds an extra keyword to the filter for subreddit comments.
ANSWERS_PER_RUN No 1 Limits the number of answers of the Bot per run.

GraphQL Dokumentation

Die Dokumentation kann unter der Adresse localhost:8080/graphql im Playground aufgerufen werden.

Der Return Type von jeder Query und Mutation (die Subreddits betrifft) ist SubredditModel:

Variable type Description
_id String ID which is created by the MongoDB at creation
name String The name of the subreddit (e.g. reactjs, test). Has a length of 3-20 letters.
keywords [String] An array with different keywords with each 2-30 letters. The bot responds to comments with those keywords, if the comment also includes the string 'waecm-2020-group-09'.
answer String The answer, the bot gives when commenting. Has 2-300 letters.
active Boolean Switches the bot off and on
description String The short subtitle of the subreddit (is fetched from Reddit)
icon String The icon of the subreddit (is fetched from Reddit)
answeredCommentIDs [String] Saves the IDs of the already answered comments on Reddit.
createdOn DateTime Date, at which the bot was created.

Queries

allSubreddits

Arguments: Keine Arguments - User muss lediglich authentifiziert sein.

Return Type: SubredditModel

currentUser

Arguments: Keine Arguments - User muss lediglich authentifiziert sein.

Return Type: UserModel (in der Tabelle)

Variable Type
username String
picture String
name String
nickname String
family_name String
given_name String

Mutations

getSubreddit

Arguments: _id: String

Return Type: SubredditModel

updateSubreddit

Type in der Tabelle: UpdateSubredditInput

Variable Type Description (ALL OPTIONAL)
name String The name of the subreddit (e.g. reactjs, test). Has a length of 3-20 letters.
keywords [String] An array with different keywords with each 2-30 letters. The bot responds to comments with those keywords, if the comment also includes the string 'waecm-2020-group-09'.
answer String The answer, the bot gives when commenting. Has 2-300 letters.
active Boolean Switches the bot off and on

Arguments: _id: String, input: UpdateSubredditInput

Return Type: SubredditModel

createNewSubreddit

Type in der Tabelle: NewSubredditInput

Variable Type Description (ALL REQUIRED)
name String The name of the subreddit (e.g. reactjs, test). Has a length of 3-20 letters.
keywords [String] An array with different keywords with each 2-30 letters. The bot responds to comments with those keywords, if the comment also includes the string 'waecm-2020-group-09'.
answer String The answer, the bot gives when commenting. Has 2-300 letters.
active Boolean Switches the bot off and on
createdOn DateTime Date, at which the bot was created.

Arguments: input: NewSubredditInput

Return Type: SubredditModel

deleteSubreddit

Arguments: _id: String

Return Type: SubredditModel



Komponenten-Tests

Die Komponenten Tests sind hier zu finden:

  • src/components/AlertWithTitle.test.tsx
  • src/components/PrimaryButton.test.tsx

Aufgabe 3 - Beschreibung der Lösungen

Komponenten-Tests

Wir haben für die Komponenten AlertWithTitle und PrimaryButton Tests geschrieben, da diese nicht von externen State abhängig sind und - wie in der Aufgabenstellung beschrieben - sehr einfach aufgebaut sind. Zum Testen haben wir die react-testing-library verwendet, da es durch diese Library vereinfacht wird, Tests zu schreiben, welche nicht von einzelnen Implementierungsdetails abhängen, sondern rein die Funktionalität testen.

Custom Element

Da es mit TypeScript an dieser Stelle ein paar Schwierigkeiten gab, entschieden wir uns das Custom Element als JavaScript File einzubinden. Damit dieses vorhanden ist, bevor React gestartet wird, wurde das Element in index.tsx noch vor rendern der App eingebunden.

Beim Durchsuchen von GitHub Repos sind wir auf LitElement gestoßen, was das Erstellen von Web Components vereinfachen soll. Wir haben kurz überlegt auf diese Technologie zu wechseln, da wir aber schon fast fertig waren, blieben wir bei der Standard JavaScript API Implementierung von Custom Elements.

Da später noch ein Update zu dieser Aufgabe ins Forum geschrieben wurde, haben wir das Element in ein externes Repo ausgelagert, auf npm gepublished und so eingebunden. Das Repo kann in [GitHub] (https://github.com/aliciaschwabenbauer/custom-banner-web-element) gefunden werden.

Das Element kann einfach über npm install als Dependecy hinzugefügt werden: npm install custom-banner-web-element

Um es in einer React App zu nutzen

  1. ein declarations.d.ts file erstellen:
declare namespace JSX {
    interface IntrinsicElements {
        "custom-banner": any;
    }
}
  1. in dem Komponenten:
import 'custom-banner-web-element'

...

//initialize an object reference 
const ref = createRef(); 

...

// add an event listener for whatever you want to do after accept is clicked 
const el: any = ref.current;
el.addEventListener('on-accept', () => {
    // callback function 
});

...

// render function in return staement(hooks)/render function with reference set from above 
<custom-banner 
          ref={ref} 
          application-name="Name"
          policy-link="Link">
</custom-banner>

Um es in PlainJS zu nutzen, kann einfach das Banner.js file aus dem Repository in das HTML zu übernehmen und mit

<custom-banner 
          ref={ref} 
          application-name="Name"
          policy-link="Link">
</custom-banner>

einzubinden.

waecm-group-09's People

Contributors

aliciaschwabenbauer avatar elenanuiding avatar s1gr1d avatar schoenenberg avatar waecm avatar

Stargazers

 avatar

Watchers

 avatar  avatar

waecm-group-09's Issues

Container Parametrisierung

Add the following parameters to the backend-container:

  • REDDIT_USERNAME
  • REDDIT_PASSWORD
  • REDDIT_CLIENT_ID
  • REDDIT_CLIENT_SECRET

Reddit Bot

  • Pro Subreddit: Abrufen der neuen Kommentare des Subreddits

  • Überprüfung, ob ein Kommentar die konfigurierten Keywords (case-insensitive)
    beinhaltet und nicht schon vom Bot beantwortet wurde.

  • Wenn ein Kommentar die Keywords beinhaltet: Dem Kommentar mit der
    konfigurierten Antwort über die Reddit API antworten.

  • Wurde eine Antwort vom Bot gepostet, muss die ID des Kommentars im
    Backend vermerkt werden, aus 2 Gründen: (1) Zur Anzeige der Anzahl
    der automatischen Bot-Antworten pro Subreddit in der Übersicht derWeb
    App (2) damit beim nächsten Durchlauf ein bereits beantwortetes Kommentar
    nicht nochmals beantwortet wird.

Display dashboard

  • create DashboardElement

  • hole Daten aus Backend

  • zeige alle DashboardElements auf Dashboard Seite an

  • mittels Klick auf Subreddit Link soll sich dessen Seite in neuem Tab öffnen

Cookie Richtlinien Seite mit Checkbox

Auf dieser Seite soll eine simple Checkbox vorhanden sein, welche anzeigt ob der User die Richtlinie akzeptiert hat. Um das Testen zu erleichtern soll die Checkbox auch abgewählt werden können. Beim erneuten Laden der Seite wird folglich der Banner wieder angezeigt.

First adding of subredits

Contains a hint that there are yet no subreddits. Via link the user can navigate to the page for adding a subredit.

Login

  • save token in sessionStorage
  • When the web app is openend it has to be checked, whether the user is already logged in or not. (either display dashboard or login then)
  • clean up code

Speichern der Subreddits (Daten von Reddit)

  • Speichern von Subreddit (in Datenbank)

    • Name von Subreddit
    • Keywords
    • Answer
    • Active
    • Daten von Reddit holen
      • Beschreibung (von Reddit API)
      • Icon (von Reddit API)
  • Löschen von Subreddit

[11] Readme ergänzen

  • Matrikelnummern
  • Containisierung beschreiben (Ports, Start usw. siehe Aufgabenstellung)
  • Technologieauswahlbegründung vervollständigen

Zusätzliche Sicherungen, wie in Aufgabe beschrieben, einbauen

Aus Aufgabenbeschreibung:

  1. Prüfen Sie zusätzlich, ob das Kommentar den Text waecm-2020-group-XX beinhaltet. D.h. der Bot antwortet nur, wenn der Name ihrer Gruppe im Kommentar vorhanden ist.
  2. Posten sie nur maximal eine Antwort pro Durchlauf. D.h. sobald der Bot eine Antwort gegeben hat, wartet dieser bis zum nächsten Durchlauf. Damit stellen sie auch sicher, dass die maximale Anzahl an API Requests pro Minute nicht überschritten wird.

Ich bin mir noch nicht sicher, ob ich 2. richtig interpretiere: Sobal der Bot eine einzige Antwort gegeben hat, soll er abbrechen und bis zum nächsten Durchlauf warten?

Design von Banner (+ responsiveness)

Das Design des Banners ist Ihnen freigestellt. Achten Sie jedoch darauf, dass ihr custom element sowohl auf mobilen Endgeräten als auch auf dem Desktop bedienbar ist und richtig angezeigt wird.

Custom Element erstellen und einbinden

Attribute:

  • application-name: Simpler String welcher den Namen der Applikation übergibt.
  • policy-link: Link zur Datenschutz-Policy
  • on-accept: Event

Entwickeln Sie einen (simplifzierten!) Datenschutz-Banner als Custom Element, welcher dem User beim Einstieg in die Webapplikation angezeigt wird.
Dieser Banner soll einen kurzen Text anzeigen, dem User die Möglichkeit bieten via Link auf die Datenschutz-Policy Seite zu gelangen als auch die Richtlinie mittels Button zu akzeptieren.

Nutzen Sie den on-accept Event um in ihrer Applikation eine simple Notifcation
(e.g. "Datenschutz-Richtlinie zugestimmt") anzuzeigen.

Sie können für den Banner ein eigenes Repository verwenden. Die anderen
Teile der Übung (CI und Tests) haben hier keinen Ein
uss.

Navigation bar

The navigation bar contains the users´ name, a logout button, and two navigation elements (dashboard and settings).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.