# Infill web

## Installation

```
git clone git@github.com:getinfill/infill.git
cd infill
yarn install
yarn run vercel:init
cd firebase
yarn install
```

## Configuration

Specify `ENCRYPTION_KEY` and `ENCRYPTION_IV` in `.env.local` for local environment to work correctly. See [Secrets management](## Secrets management) for details.

## Run in production

Project is based on next.js, so easiest setup is to run it on vercel.

To build and run the server locally

```
yarn run build
yarn run start
```

## Development

- Use vscode
- Install extension chenglou92.rescript-vscode
- Install extension vdanchenkov.tailwind-class-sorter
- Install extension bradlc.vscode-tailwindcss
- Enable format on save `"editor.formatOnSave": true`
- Enable `"files.insertFinalNewline": true`
- Install prettier extension (for json, js and css files)

Periodically pull development .env:
`yarn vercel env pull`

To rebuild all ReScript:
`yarn rescript clean && yarn rescript build`

App can be run on firebase emulators or on the staging database.

To run on emulators:

```
yarn dev
```

Firestore state will be preserved among runs in `firebase/db`. You can reset state by removal of the folder.

To use firebase staging database instead of emulators use the following command instead:

```
yarn dev:no-emulators
```

### Update GraphQL JSON schema

```
get-graphql-schema https://graphql.cherre.com/graphql/ -h "Authorization=Bearer <TOKEN>" -j --output graphql_schema.json
```

### Connect to Google Cloud SQL

Install [Cloud SQL Auth Proxy](https://cloud.google.com/sql/docs/postgres/connect-instance-auth-proxy);
Look up **Connection name** of the instance to connect [here](https://console.cloud.google.com/sql/instances/), on **Overview** tab of instance page.

Run proxy:

```
cloud_sql_proxy -instances=INSTANCE_CONNECTION_NAME=tcp:5432

```

Make sure you are not running local DBMS on same port.
Then connect with SQL client to proxied local port:

```
psql "host=127.0.0.1 port=5432 sslmode=disable dbname=postgres user=postgres"
```

## Integration tests

Integration tests for API runs over network, so all tests services should be started. Tests for core api
checks server `https://infill-core-api.herokuapp.com`, tests for next.js based api checks `http://localhost:3000`.

```
yarn run test:integration
```

## Secrets management

Reason for doing this is Vercel's environment variables size limit, which is 4KB.
https://github.com/vercel/vercel/discussions/5364

Place non-public tokens, keys, etc. in `secretsPlain.js`, following example in `secretsPlain.js.example`, then run

```
node scripts/encryptSecrets.js
```

to encrypt and write them in `server/secretsEncrypted.js`.

Key and IV (initialization vector) would be prompted for entry.

Key should be 32 character long, and IV should be 16 characters long. They can be easily generated in shell:

```
tr -dc 'A-Za-z0-9!"#$%&'\''()*+,-./:;<=>?@[\]^_`{|}~' </dev/urandom | head -c 16  ; echo
```

(Source: https://unix.stackexchange.com/a/230676)

Key and IV should be available on Vercel as `ENCRYPTION_KEY` and `ENCRYPTION_IV` secret environment variables in Vercel.

If these values are changed on Vercel, ALL FOLLOWING DEPLOYMENTS should have secrets encrypted with changed keys.

For now, Key and IV are universal across all environments.

Import secrets from `server/secrets.js`, e.g.:

```
[@bs.module "../../server/secrets"] [@bs.scope ("default")] external key: string = "key";
```

to use them in code.

## Work with production repository

Add production remote, this only needs to be done once:

```
git remote add production git@github.com:getinfill/infill-production.git
```

### Upgrade production to current development version

```
git fetch --all
git checkout production
git reset --hard origin/master
```

```
git push production production
```

or

```
git push production production --force
```

in case when patches were applied to master.

### Patch a production branch

Reset to the current production branch, commit changes, switch to the new branch as usually. Then, push to the developement repository to have a preview deployment:

```
git push origin <branchName>
```

Once satisfied with changes, upgrade `production` branch and push it. Do not use production vercel/github for preview deployments, as they will work with production backend and data.

```
git checkout production
git merge <branchName>
git push production production
```

Now, when production is patched, rebase onto development branch to integrate changes to it

```
git checkout <branchName>
git rebase origin/master
git push origin <branchName> --force
```

## Firestore migrations

Generate new migration file

```
yarn dev:firegate:generate <name>
```

Run migration in development

```
yarn dev:firegate:run --force <name>
```

Note that migrations on production and staging are triggered by any commit in main branches. (production and master)

For preview deployments migrations are executed only when PR is created.

## Documentation links

https://firebase.google.com/docs/reference/node/
