# Pacifico API

For initial setup, see the end of the file.

## Docker-Compose

The API runs under the service name `api`. For development we will also give a ccontainer name to make writing the READMEs easiert. It is called `portal-api`. On production this name will be auto-generated to prevent docker name collision. This also means you cannot start two instances of our services locally.

### Installing packages

When installing new packages, please exec into the docker container beforehand. Do not run `yarn add` on your machine.

`docker exec -it portal-api bash`
And install again:
`yarn add ...`

### EsLint

For Eslint to work you need to install the packages locally. It is fine to run `yarn install`on your machine (outside of the container). Just never so `yarn add...` there.

For now manually, run the linter and formatter before commiting or at the end of your work on a branch:
`yarn run fixAndFormat`

Manually check any lint errors and fix them before commiting. It is recommended to not commit any errors (only warning).

You can run the linter standalone with: `yarn run lint:fix`
And format after: `yarn run format`.

The linter itself is not formatting, so it is required to format after the linter fixed code.

### Debugging

If you use VS code and want to attach your debugger to node within the api docker container, add the following to your launch.json:

```json
{
  "configurations": [
    {
      "name": "Docker: Attach to Node",
      "type": "node",
      "request": "attach",
      "port": 9229,
      "address": "localhost",
      "restart": true,
      "localRoot": "${workspaceFolder}/services/backend",
      "remoteRoot": "/app"
    }
  ]
}
```

Make sure to start the backend with the `dev:inspect` command and to map the port 9229:9229 in the docker-compose(.override).

For the auto-restart to fully work, we need to add a start delay. Create a `tasks.json`file besides your `launch.json` with the following content:

```json
{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "delay",
      "type": "shell",
      "command": "${workspaceFolder}/delay-api-debugger.sh",
      "problemMatcher": []
    }
  ]
}
```

If you have permission errors, make sure the delay shell script is executable under `app/api`

```
chmod +x delay-api-debugger.sh
```

### Shared Folder

The shared folder is mounted during container build. To make your IDE work with the given path INSIDE of api, while shared is still located outside of api, you need to symlink it.

```
cd app/api
ln -s ../shared ./shared
```

## Initial Setup

### Fill the database / Adding fixturees

Assuming you have already built and started all containers in the root of the
mono repo, run the following commands to fill the mongodb with the initial dev example data.

As a prerequisite, you need to install 'jq' on your dev machine (e.g. with `brew` on mac)

```bash
# generate a token with the login-dev command (path expects you to be on root level)
token=$(./app/api/bin/login-dev)

# import the fixtures by calling the api endpoint POST /core/system/fixtures
# e.g. with curl
curl -X POST \
  -H "$token" \
  -H 'Accept-Version: 1.0' \
  -H 'Content-Type: application/json' \
  -d '{"useDeprecatedVersionAndDeleteDatabase": true}' \
  http://localhost:8082/core/system/fixtures
```

The token generation will only work if there are NO users in the database. If you want to call the fixture endpoint anyway, you need to use an auth token of one of the exisiting user. Or delete all users from the database, e.g. with the ui tool `mongoCompass`.

Also note, that you are required to run database migrations as the deprecated fixture flow is not up to date. See below.

### Run migrations

TODO: On API container startup migrations will run. So usually there is no need to interact with them unless you are developing.
NOTE: Currently all migrations have to be executed by hand!

Exec into to api container: `docker exec -it portal-api bash` and run all yarn scripts related to migrations there. You can run migrations from your machine as well, but due to package differences, it is recommended to do this sensible job from within the docker environment!

To create a new file use this command: `yarn run migrate:create name-your-file`

This applies all migrations that had not run yet: `yarn run migrate:up`. Run this also when you have set up your database with fixture data, as the old fixture flow is a bit deprecated. It will be replaced in the future.

This reverts changed until a given script name (or all if none is given): `yarn run migrate:down`

Migration status: `yarn run migrate:status`

## Troubleshooting

### On Login: 429 - Too many Retries

Due to security reasons the login api logs and blocks too many failed login attempts. Just for consistency this also happens for local development.

But you can easily use the admin endpoints to remove these entries, if you need to. Normally calling this should be suitable (locally)

`DELETE http://localhost:8081/core/admin/cache/blocks/172.20.0.1`

Or you can delete all entries:

`DELETE http://localhost:8081/core/admin/cache/blocks`

You can always see the tracked attempts with this (to retrieve your key (ip address) for the first command):

`http://localhost:8081/core/admin/cache/blocks`

### Error when building the image or running any commands

```
error /app/node_modules/bcrypt: Command failed.
Exit code: 1
Command: node-pre-gyp install --fallback-to-build
Arguments:
Directory: /app/node_modules/bcrypt
Output:
/app/node_modules/wide-align/align.js:2
var stringWidth = require('string-width')
                  ^
Error [ERR_REQUIRE_ESM]: require() of ES Module /app/node_modules/string-width/index.js from /app/node_modules/wide-align/align.js not supported.
Instead change the require of index.js in /app/node_modules/wide-align/align.js to a dynamic import() which is available in all CommonJS modules.
    at Object.<anonymous> (/app/node_modules/wide-align/align.js:2:19) {
  code: 'ERR_REQUIRE_ESM'
```

This error usually happens when you install a new package for the api from your host machine. To fix it you need to exec into the api container:
`docker exec -it portal-api bash`

Remove the yarn.lock file:
`rm -f yarn.lock`

And install again:
`yarn install`

This will align your versions and also update your yarn.lock file. Commit it!
