npm package: @rocicorp/licensing
Description: Replicache licensing client and server
Latest version: 7.1.0

# licensing

Replicache license server and client

# API Versioning

[api-versioning](api-versioning.md)

# Development Instructions

## Set up

- `brew install node` (or brew equivalent)
- `brew install heroku/brew/heroku`
- `heroku login`
- optional but helpful: `heroku autocomplete` (and follow instructions)
- setup staging and production remote, run these commands in this order
  1.  `heroku git:remote -a replicache-license-staging`
  2.  `git remote rename heroku staging`
  3.  `heroku git:remote -a replicache-license`
- verify your remotes are correct

  `git remote -v`

  output should look like this:

  ```
  heroku  https://git.heroku.com/replicache-license.git (fetch)
  heroku  https://git.heroku.com/replicache-license.git (push)
  origin  git@github.com:rocicorp/licensing.git (fetch)
  origin  git@github.com:rocicorp/licensing.git (push)
  staging https://git.heroku.com/replicache-license-staging.git (fetch)
  staging https://git.heroku.com/replicache-license-staging.git (push)
  ```

- install [Docker](https://docs.docker.com/desktop/), run it, and configure
  Settings to start when you log in (if you'd like)
- install postgres (for the `psql` cli, we use docker to actually
  run postgres) eg `brew install postgresql`
- create a `.env` file in the root directory of the project with contents:
  ```
  DATABASE_URL="postgresql://testuser:testpw@localhost:5433/test"
  ```
  Note: currently the same db is used by tests and when you run the server
  locally. It's wiped each start/test but still, that's lame. See note in
  docker-compose.yml and feel free to fix this.

## Common tasks

- **IMPORTANT**: `npm run start` is for **production**. The prod db is persistently
  running so doesn't need to be started. When running locally we need to start a local,
  dockerized db; use `npm run start_local` to start up locally.

### Database

- connect to local db:
  - `npm run start_test_db`
  - `npx prisma migrate dev`
  - `source ./.env && psql $DATABASE_URL`
- generate a migration:
  - `npx prisma migrate dev --name foo` generates the new migration
  - `npx prisma generate` generates the new client
- dev migration compaction: to compact several new, locally applied migrations (do not do this in production, or if they have been applied in prod, unless you are resetting the prod db, which you probably should not be)
  1. bring up the local db eg `npm run start_test_db && npm run migrate_test_db`
  2. remove the migration rows in the db from the `_prisma_migrations` table
  3. remove the migration dirs from `primsa/migrations`
  4. run `npx prisma migrate dev` which will generate a new migration AND RESET THE LOCAL DB
- BACKUPS
  - automatic physical backups happen continuously and are saved for a week and can be restored using [rollbacks](https://devcenter.heroku.com/articles/heroku-postgres-rollback)
  - logical backups happen every 24h at 2am pacific time and are kept for ~30 days (`heroku pg:backups:schedule --at '02:00 America/Los_Angeles' --app replicache-license`)
  - capture a manual logical backup:
    - `heroku pg:backups:capture --app replicache-license`
  - list logical backups:
    - `heroku pg:backups --app replicache-license`
  - restore from a logical backup:
    - `heroku pg:backups:restore <backupid eg b001> --app replicache-license`

### Environments

We have two environments:

1. staging: app [replicache-license-staging](https://dashboard.heroku.com/apps/replicache-license-staging) remote name 'staging'
2. production: app [replicache-license](https://dashboard.heroku.com/apps/replicache-license) remote name 'heroku'

Env vars, resources, etc. are NOT automatically reflected from prod to staging, you need to remember to add them both places eg:

```
heroku config:set --a replicache-license-staging FOO=bar
heroku config:set --a replicache-license FOO=bar
```

### Pushing code

- to push from main: `git push heroku main` or `git push staging main`
- to push from someother branch: `git push <heroku|staging> someother:main`

To deploy to staging:

```
# Copy prod db to the staging db:
heroku pg:copy replicache-license::DATABASE_URL DATABASE_URL -a replicache-license-staging --verbose

# TODO: should probably be pushing from a release branch

# Push the code, assuming you want to push from main. This should
# happen *after* copying the prod db because it will run migrations.
git push staging main

# Create a license on staging (using the licensing package get-license)
rm $(which get-license-cmd)
npm run build && npm link
npx get-license-cmd -s
```

To deploy to production:

```
heroku maintenance:on -a replicache-license
git push heroku main
# <verify it's all good>
heroku maintenance:off -a replicache-license
```

### Rolling back

It's often more convenient to just roll forward, but here are the useful commands:

```
heroku releases -a <replicache-license|replicache-license-staging>
heroku releases:info vXX -a <replicache-license|replicache-license-staging>
heroku rollback vXX -a <replicache-license|replicache-license-staging>
```

[More info](https://devcenter.heroku.com/articles/releases).

### Logs

- to tail logs: `heroku logs --tail -a <replicache-license|replicache-license-staging>`
- view logs in Datadog: [https://app.datadoghq.com/logs?query=service%3Alicensing](https://app.datadoghq.com/logs?query=service%3Alicensing)
- view logs in heroku: [https://dashboard.heroku.com/apps/replicache-license/logs](https://dashboard.heroku.com/apps/replicache-license/logs)
- how it works:
  - heroku works out of the box with an [https log drain to datadog](https://docs.datadoghq.com/logs/guide/collect-heroku-logs/) which we enabled for prod
  - added a custom datadog attribute for our log levels (INF, DBG, etc) and added a status remapper to a new pipeline. [instructions](https://docs.datadoghq.com/logs/faq/how-to-remap-custom-severity-values-to-the-official-log-status/)