4 Solution Strategy - maex0/SoftwareQualityWithCats GitHub Wiki

Technology Stack and Solution Strategy

Next.js, TypeScript and NPM

Next.js is a React framework that allows you to build server-side rendering and static web applications using React. It is used because it is a very popular framework and it is easy to use. It is also very easy to deploy and has a lot of plugins and tools that can be used to improve the development process. Some of the important features of Next.js for this project are:

  • Server-side rendering
  • Static site generation
  • API routes
  • TypeScript support

Instead of JavaScript, TypeScript is used which is a superset of JavaScript that adds static typing to the language. It is used because it makes the code more readable and maintainable.

In addition to that NPM is used as a package manager. It is used to install and manage the dependencies of the project. It is used because it is one of the most popular package managers for JavaScript and it is very easy to use.

For this chapter the solution strategy is to use the Production Checklist and Development reccomendations from the Next.js Documentation (Production Checklist) and the TypeScript Documentation (Do's and Don'ts).

PostgreSQL and Prisma

PostgreSQL

As a database, PostgreSQL is used. It is a powerful, open-source object-relational database system that has a strong reputation for reliability, feature robustness, and performance. It allows a good integration with docker and is easy to deploy.

Prisma

As a ORM, Prisma is used. It is a modern database toolkit that makes it easy to work with databases.

This is the model that is used in the project:

model CatImage {
  id String @id
  url String
  width Int
  height Int
  createdAt DateTime @default(now())
}

Docker and Docker Compose

Docker

Docker is used to containerize the application. This is useful to do production deployments and to ensure that the application runs in the same environment as it was developed. It is also useful to ensure that the application runs in the same environment as it was tested.

Docker Compose

Docker Composer is used to define and run multi-container Docker applications. It is used to define the services that make up the application and how they interact with each other. In this use case it is used to define the database and the application. Health checks are defined in the docker-compose.yml file for checking the health of the application in the CI/CD pipeline or also locally.

Software Quality and Testing

Here are the tools and practices that are used to reach the quality goals of the software defined in 1. Introduction and Goals.

Functional Suitability

Precommits with husky

Before every commit the project is build and unit tested. If the build or tests fail, the commit is rejected. (This must not be a fixed rule, but it is a good practice to ensure that the code is always in a working state.)

Static Code Analysis with Eslint and Prettier

Eslint combined with Prettier is used to enforce a consistent coding style across the project.

Unit tests

For unit tests Jest is used. Here a coverage benchmark of 80% is set (default in the sonarcloud settings). The tests are executed in the CI/CD pipeline. The results are sent automatically to Sonarcloud and display on the status batch in the Readme (see GitHub).

Integration tests

As integration tests are Postman API tests used.

E2E tests

For end-to-end tests Playwright and Cucumber is used.

Performance Efficiency

  • k6 is used for performance tests. Since the application is not deployed on a server, the tests are not executed in the CI/CD pipeline but can be executed locally with npm run test:performance:k6. The results are saved, shown and visualized in the k6 cloud.

  • Lighthouse is used for performance tests. These are also executed in the CI/CD pipeline. The results can be downloaded as an artefact from the pipeline.

Security

  • Dependency Cruiser: The dependency cruiser is used to check the dependencies of the project. It checks if the dependencies are used correctly and if there are any circular dependencies. The result of the analyis is shown in chapter 5. Building-Block-View

  • CodeQL (see GitHub): CodeQL is used to check the code for security vulnerabilities. It is executed in the CI/CD pipeline.

  • Dependabot (see GitHub): Dependabot is used to check the dependencies of the project for security vulnerabilities. It is executed in the CI/CD pipeline.

  • Sonarcloud (see CI/CD Pipeline)

  • Trufflehog (see CI/CD Pipeline)

  • GitHub Policy (see here) and Security Settings

Additional Actions and Tools

CI/CD Pipeline

As a CI/CD pipeline GitHub Actions are used. The differrent pipelines are defined in the .github/workflows folder. The following steps are executed (on different triggers, for more details view the files directly) in the pipeline:

  • Build
  • Jest unit tests
  • Playwright and Cucumber e2e tests
  • Postman API tests
  • Sonarqube scan
  • Lighthouse performance tests
  • Trufflehog (Secret Scan)
  • Dockerfile linting with hadolint: Dockerfile will be linted if changed
  • CodeQL Security Scan
  • Dependabot Security Scan
  • Tag and Release on merge to main (see here)

View the Actions page for all executed pipelines.

GitHub

  • Protect main branch for pushes, only merge with pull request. Require status checks (CI/CD Pipeline) to pass before merging.

  • Show badges for quality indicators on main readme

  • Dependabot (Code security and analysis settings)

  • Email Notifications (e.g. for security alerts)

  • CodeQL (Security Scan)

Copilot and ChatGPT

To double check the quality of the code, GitHub Copilot and ChatGPT are used. Copilot is used to generate code snippets and ChatGPT is used to check the quality of the code. Both tools are used to improve the code quality and to ensure that the code is written in a clean and maintainable way. Here it is important to mention that the output is always checked by the developer of this project and not blindly accepted.