Hosting your own
================

The app is made of two separate parts. A (micro-)server part which is
basically just exposing an API on top of the database and a client part
(static JS scripts and assets) which is accessing this API.

## Updating the app

Whenever new versions are published, here is a quick guide to do the upgrade:

* fetch the last updated files from the repository
* ensure the client part build is up to date
    (`yarn install && yarn build`)
* check for required migrations (see below)
* ensure the server part requirements are up to date (`pip install -r
    requirements.txt`) and restart the server

From times to times, the database schema might need to be updated. Migrations
(scripts to edit the database schema for you) are provided under the
`scripts/migrations` folder. The scripts in this folder are labelled by
versions, meaning that the `0.3.py` script handles the migration of the
database from the version immediately before `0.3` to the `0.3` version of the
app.

**Always** make a backup of your database prior to running a migration on it.

If you upgrade through several versions at once, you should run all the
migrations scripts for all the intermediate versions, in the ascending order.
There are currently no automated way to handle the updates of the database
schema.

_Note :_ Versions of the app are listed in the git tags. Current version of
the code is also in the `src/constants.js` file.


## Server part

### Build setup

``` bash
# Install Python dependencies
pip install -r requirements.txt

# Start the server
python -m server
```

It is better to use a dedicated `virtualenv` if you can, to help manage Python
dependencies in a clean way.

API routes are all listed within `server/routes.py` file, with documentation
strings.

### Useful environment variables

You can pass a few environment variables to the `python -m server` command to
adapt its behavior:

* `HOST=` to specify the host to listen to (defaults to `127.0.0.1` which
    means `localhost` only).
* `PORT=` to specify the port to listen on (defaults to `8081`).
* `DATABASE=` to specify a [database URL](http://docs.peewee-orm.com/en/latest/peewee/playhouse.html#db-url) to connect to (defaults to
    `sqlite:///reports.db` which means a SQLite database named `reports.db` in
    the current working directory).
* `API_TOKEN=` to specify a token required to `POST` data to the API.

### Serving in production

You can use the `wsgi.py` script at the root of the git repository to serve
the server side part. You can find some `uwsgi` and `nginx` base config files
under the `support` folder.

You might also want to put some rate-limiting in front of the API. This can be
done easily when you use `nginx` as a reverse proxy for instance. This is
handled by the `limit_req` directive in the `nginx` base config files provided
in the `support` folder. You can then edit the
`DELAY_BETWEEN_API_BATCH_REQUESTS` configuration option in `src/constants.js`
to ensure that requests will be spaced enough when sending a batch of them so
that they will not be blocked by your rate-limiting.

### Importing OpenData

A few OpenData files can be imported in Cycl'Assist, to import roadworks for
instance. All the useful scripts to import OpenData are in the
`scripts/opendata` folder.

You can set up a daily cron task to automatically run the import of opendata
every day for instance.


## Client part

### Build setup

Here are the steps to build the client side assets and scripts.

``` bash
# Install JS dependencies
yarn install

# Serve with hot reload at localhost:8080
# (For development only)
yarn dev

# Build for production with minification
# Output assets and scripts in the `dist/` folder, ready to be used in
# production.
yarn build

# Build for production and view the bundle analyzer report
# (might be useful for debugging or development)
yarn build --report
```

To serve the app in production, you have to build the scripts and assets using
`yarn build`. It will output everything under the `dist/` folder which you can
then serve using any web server (these are just static files to be served).


### Useful environment variables

You can pass a few environment variables to the `yarn build|dev` commands to
adapt the behavior to your needs.

* `PUBLIC_PATH=https://.../foobar` to serve the app from a subdirectory.
* `API_BASE_URL=https://...` to specify the location of the server API (defaults
    to `/`). The value should end with a trailing slash.
* `THUNDERFOREST_API_KEY=` to pass an API key server to use for
    [Thunderforest](http://thunderforest.com/) tiles (OpenCycleMap, etc).
* `API_TOKEN=` to pass a token required to access the server side API (check
    below in the server part environment variables for more details).

You should also have a look at the build variables under the `config/`
subdirectory.


### Geographical extension

While the frontend could theoretically work in the entire world without much
modifications, it is currently written with mainland France in mind, mostly
because that is the territory the authors are most familiar with.
Additionnally, this limits the volume of geographical data (such as OSM
extracts) to handle and makes managing the app easier.

You could of course easily extend it to support other territories. The
French-specific parts of the code so far are:
* The [`AddressInput`](https://framagit.org/phyks/cyclassist/blob/master/src/components/AddressInput.vue) component which uses the [https://adresse.data.gouv.fr/](https://adresse.data.gouv.fr/) API to autocomplete addresses. You could easily replace it with [Algolia Places](https://community.algolia.com/places/) which covers the entire world.
