# Welcome, Degenerate

Nothing in this project is set in stone (even this rule). I might not know what I'm doing.

Table of Content:

1. [Currently Most Wanted](CONTRIBUTING.md#currently-most-wanted)
1. [Communication](CONTRIBUTING.md#communication)
1. [Development](CONTRIBUTING.md#development)
   1. [Environment Setup](CONTRIBUTING.md#environment-setup)
   1. [Git](CONTRIBUTING.md#git)
   1. [Database](CONTRIBUTING.md#database)
   1. [Formatting and Linters](CONTRIBUTING.md#formatting-and-linters)
   1. [Testing](CONTRIBUTING.md#testing)
   1. [Updating](CONTRIBUTING.md#updating-dependencies)
1. [Design](CONTRIBUTING.md#design)

## Currently Most Wanted

### User Stories

With the help of [user stories](workspace/user-stories.md), one is able to formulate requirements for the application which then can be implemented. This also includes the design of a GUI.

### Database Schema

Based on the user stories, features, and feature ideas, one of the next steps is to design a [database schema](workspace/schema).

- some initial work is already done
- feedback is especially needed on the following (the rest of the [ideas folder](workspace/ideas) deserves a look, too)
  - [tagging system](workspace/ideas/tagging-system.md)
  - [multiple manga series](workspace/ideas/multi-work-series.md)
  - [multiple story manga](workspace/ideas/multi-story-manga.md)
  - [intellectual property and parodies](workspace/ideas/ip-and-parody.md)
- any other ideas?

### GUI/Prototype

The application needs a graphical user interface. Take a look at the [requirements](workspace/gui/requirements.md) and some [inspiration](workspace/gui/inspiration) (You could also supply more).

The current idea is to build the frontend with [Svelte](https://svelte.dev), not sure if that has relevance here.

### Ideas Folder

The [ideas folder](workspace/ideas) is a collection of possible features for the application. Feedback and discussion is wanted for every idea.

## Communication

Every contribution is valuable. Open a ticket [here](https://git.fuwafuwa.moe/Xymorot/RenaiApp/issues) or write me an [email](mailto:xymorot@mailbox.org).

## Development

### Environment Setup

Things to install:

- [Node.js](https://nodejs.org) (use the version written under `engines` in [package.json](package.json))
- [Git](https://git-scm.com/)

Then [use git to clone this repository](https://www.google.com/search?q=how+to+clone+a+repository+with+git).

Run `npm install` in a terminal window opened to the cloned repository, all dependencies will be installed. You might be required to install external build tools (especially if under Windows) for the compilation of native node modules, mainly sqlite3.

Then run `npm run build` to build the app, and `npm start` to run it.

The `npm run dev` script watches files and rebuilds the app on changes.

You should try to the use the node version `npm run electron-version` reports, since that is the node version the app runs on.

### Git

This project uses Git as its version control software. If you don't know how to use it, [read a quick guide](https://www.google.com/search?q=how+to+git).

The general contributing workflow is like this:

> **fork repository** > **do your changes on the fork** > **create pull request to original repository**

Once you build up enough trust, I might add you as a contributor.

Some additional care has to be taken for the following points:

#### Commit Messages

This project uses [Conventional Commits](https://www.conventionalcommits.org) with the following types:

| type       | description                                                                             |
| ---------- | --------------------------------------------------------------------------------------- |
| `feat`     | implementing a new feature or changes an existing one                                   |
| `remove`   | removing an existing feature                                                            |
| `fix`      | repairing a feature which does not work correctly                                       |
| `refactor` | reworking code so that its function does not change (but could have in unexpected ways) |
| `update`   | updating dependencies and associated code changes                                       |
| `test`     | any of the above, but when it only applies to tests/mocks                               |
| `meta`     | updating something not that is not directly related to function/tests                   |
| `reformat` | rewriting code in a way in which it is impossible for function to change                |

Always try to split up your changes into coherent commits, a single commit should do a single thing. If your commit needs to do more than one thing it should be labeled with the type coming first in this list.

Special cases are **merge commits** and **revert commits**. Git provides a default commit message for these two cases, just leave them if you do nothing else to the committed files.

##### Retired Types

You might find the following types in the git history but their use is discouraged in favor of another type:

| type     | description                                                  | replaced by |
| -------- | ------------------------------------------------------------ | ----------- |
| `doc`    | updating documentation, including code comments              | `meta`      |
| `config` | changing configuration (npm scripts, linters, build process) | `meta`      |

#### Git Hooks

This project uses [Husky](https://github.com/typicode/husky) to define git hooks. The point of the pre-commit hook is to have a clean commits. This means correctly formatted, without linter errors, and with functioning tests. The `npm run fix` script fixes all fixable errors, the tests you have to fix yourself.

### Database

The application uses [SQLite3](https://www.npmjs.com/package/better-sqlite3) as a database, with [TypeORM](https://typeorm.io) as an object-relation mapper.

#### Database Migrations

Migrations are stored in [src/main/migrations](src/main/migrations) and handled by typeorm. Migrations are run on first database connection inside [database.ts](src/main/core/database.ts).

To auto-generate a migration:
`node_modules/.bin/typeorm migration:generate -n <migration name> -c <connection name>`

To create an empty creation which can be filled with custom migration code:
`node_modules/.bin/typeorm migration:create -n <migration name> -c <connection name>`

To run migrations:
`node_modules/.bin/typeorm migration:run -c <connection name>`
This is also pre-defined in the npm script `typeorm:migrate`.

### Formatting and Linters

This project uses [Prettier](https://prettier.io/) for code formatting (and an [.editorconfig](.editorconfig) which you should respect). [ESLint](https://eslint.org/) is used for linting.\
The point of these libraries is to make uniform code possible over various editors. If you are not happy with the rules, do not ignore the warnings! Understand why the rule is there (googling helps) and if you decide the rule should not be active, deactivate it. Also think about if the rule should be deactivated everywhere or not, then configure accordingly. Explain your reasoning in the commit body.

### Testing

The testing framework of choice is [Mocha](https://mochajs.org/). Call `npm run test` to run all tests. Tests are written in typescript and need to be transpiled before testing.

- assertion is (mainly) done by [Chai](https://www.chaijs.com/)
- Electron specific testing is done by [Spectron](https://electronjs.org/spectron)
  - it writes its electron files into a temporary directory, so the local app installation should not be compromised
- spies, stubs and mocks are provided by [Sinon.JS](https://sinonjs.org/)
- HTTP server mocking is done by [nock](https://github.com/nock/nock)
- property based testing is made possible by [fast-check](https://github.com/dubzzz/fast-check)

For the creation of test files look at existing ones, they are named `*.spec.ts`.

#### Mocks

There are 2 ways in which mocks are defined/used:

0. for external modules, in [mocks](mocks)
   - uses the [rewiremock](https://github.com/theKashey/rewiremock) package
   - use this only when there is some magic happening like for electron which normally runs in its own node process
1. for own modules, just beside their file
   - name the file `*.mock.ts` and use existing mock files for orientation on how to build them
   - use sparingly and only when not having a mock makes it more complex e.g. for modules which interact with the file system

#### Tagging

Mocha does [not have a separate tagging feature](https://github.com/mochajs/mocha/wiki/Tagging), but it can filter via title. Use the following tags in your test titles:

| tag         | usage when                |
| ----------- | ------------------------- |
| `@slow`     | test is particularly slow |
| `@spectron` | test uses spectron        |

#### Coverage

Code coverage is provided by [nyc](https://github.com/istanbuljs/nyc). The detailed code coverage can be found under `.nyc_output/coverage/index.html` (open in browser) after running the coverage script `npm run coverage`. The coverage script is separate because it does not allow simple debugging.

### Updating Dependencies

In the best case a simple `npm update` does the trick, but to upgrade to a new major version of a dependency a manual `npm install <package>@<version>` is necessary. All code changes to work with the new dependency must be in the same commit.

#### Electron

Updating Electron also updated the Node.js and Chromium version it uses internally. When upgrading to a new major Node version, the Node.js version in the development environment should also be updated. This also means updating the `node` version key under `engines` in [package.json](package.json).

## Design

Before implementation comes design (at least for a bit, until they run in parallel). The [workspace folder](workspace) is the space where all the documents for application design should go.
