Skip to content

jsep/wikidiscover

Repository files navigation

Wikidiscover

Wikidiscover is a tool to help you discover new Wikipedia articles based on your interests.

Frontend: https://wikidiscover.fly.dev/
Backend: https://backend-wikidiscover.fly.dev/
LibreTranslate: https://libretranslate-wikidiscover.fly.dev/

Setup

Prerequisites

  • Node.js
  • Docker

Running the project

To run the project locally, follow these steps:

npm run dev

This will start the frontend and backend servers together with a LibreTranslate and a Redis server.

App

Architecture

The project is divided into main parts:

  1. Frontend: ReactJS with Vite
  2. Backend: Node.js API with NestJS
  3. Mobile App: Capacitor
  4. LibreTranslate API
  5. Redis

The frontend and backend are deployed to Fly.io. Upstash is used for the Redis.

CI/CD integration

This project uses GitHub Actions for CI/CD. The frontend and backend are deployed to Fly.io. The LibreTranslate API has also been deployed to Fly.io.

  • Automated tests
  • Automated deployment to Fly.io
  • Preview deployment per pull request
  • Production is deployed on merge to main

Development principles

  • Explicit is better than implicit
  • Separate concerns
  • TDD
  • Type safety - no any
  • Always return a result from actions that can fail

Frontend: ReactJS

The frontend is a TypeScript ReactJS app with Vite as the build tool. It displays a grid of cards from the Wikipedia Featured Content API.

This app loads content in the 300+ languages supported by Wikipedia. More details are in the backend section and how it leverages the LibreTranslate API.

It loads the selected date's feature article in the selected language. If, however, the article is not available in the selected language, it will be translated using the LibreTranslate API.

If the article is not available, it will show the featured image, the "In the news" content, or the most-read article of the day.

All the labels in the app are translated to the selected language. If LibreTranslate does not support the selected language, the app will default to English.

The app loads more content as you scroll down the page.

Frontend Architecture

Cornerstone Data Models

Data Models

Data Transfer Objects (DTO)

We are not in control of the data that comes from the outside world. Theses are straight data objects that we get from the API, and we don't have control over.

Programmers Model (PM)

Here we process the data from the DTOs and prepare it for the view and/or business logic.

View Model (VM)

We use the objects we control (PM) to extract just enough data for the view and nothing more, and we pass it to the component

Respository

Repository comunicates with the gateways and creates the PMs

Gateways

Gatesways are anythig that communicates with the outside world, like the API, the local storage, etc.

Presenters

Presentres are responsible for the view logic, like infinite scroll, pagination, they use the repositories to get the PMs and generte the VMs for the components.

Components

Only display the data, they don't have any logic.

Architecture

User Interface

  • UI elements for date selection
  • UI elements for language selection
  • Fetch and display content based on selections
  • Infinite scrolling
  • Loading screen while fetching data
  • Error screen for errors

Card Content

  • Display title
  • Display thumbnail (if available)
  • Display brief description
  • Display views count for most-read articles
  • Display date for the featured content

Interaction

  • Open content in a new tab on card click
  • Mark clicked cards as read with a visual indicator
  • Persist 'read' status in local storage

Backend: Node.js API with NestJS using TypeScript

The backend is a proxy for the Wikipedia Featured Content API. It also offers seamless translation for the featured content via the LibreTranslate API. It translates all the labels used in the app to the selected language.

The backend also has a Redis cache for the response from the Wikipedia API to reduce the number of requests to the Wikipedia API.

Wikipedia Featured Content returns the following types of content:

  • Daily featured article
  • In the news
  • On this day in history
  • Daily featured image
  • Most-read articles (300+ languages supported)

However, not all content is available in all languages. Only the most-read article is available in all languages. This is where the LibreTranslate API comes in. It translates the content to the selected language.

LibreTranslate deployment has support for 44 languages (only two are not available from the libretranslate.com version).

The translation works as follows:

  1. If the content is available in the selected language, it is returned as is.
  2. If the language is not English and is supported by LibreTranslate:
    • Fetch the English content from Wikipedia, since all the featured content is available in English.
    • If content is not available in the selected language (Featured Article), it will be translated to the target language from English.
    • The same goes for image, news, and on this day content.
  3. All the labels used in the app are translated to the selected language. If LibreTranslate does not support the selected language, the app will default to English.

Features

  • /feed: Proxy to Wikipedia API, accepts GET requests, validates parameters, standard error response
  • Local development and testing environment with Docker and docker-compose
  • Use Redis to cache responses from Wikipedia API

Mobile App

It is a Capacitor app that uses the same codebase as the web app. It is compatible with both Android and iOS.

  • Tested the app on iOS

Mobile App

Missing features

  • [] Persists logs using SQLite
  • [] E2E testing with Cypress