# Quick Start

## Referral Campaign App

In this example, we will try to build an API server for a new referral campaign where:

1. unregistered users will sign up with or without a referral code
2. newly signed up users will have an unique referral code to invite other users
3. if a user's referral code is used when signing up, that user gets a point.

## Prerequisites

To complete the following guide, you will need

1. Node version 8 or newer (to install Node, please go to <https://nodejs.org/en/download/>)
2. MongoDB version 3 or newer (to install MongoDB locally, please go to <https://docs.mongodb.com/manual/installation/#tutorials>)

## 1. Setup your first project

You are going to create a new folder and create a Node application within it.

```bash
$ mkdir referral_journey
$ cd referral_journey
$ npm init --yes
```

![screenshot: initializing your app](https://3515816241-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LOkfsLjd-KkAAHYh7IT%2F-LP6NaRTKcwoW7MxhgPZ%2F-LP6Ou3zuL77CuBQgC5H%2Fimage.png?alt=media\&token=452c854b-f790-40d4-aa45-827a3cd9e59f)

After running these commands, you will find a `package.json` file in your newly created `referral_journey` directory. So far so good!

## 2. Install `jerni` and `jerni-dev`

You need to install `jerni` and `jerni-dev` package from [npm](https://npm.im/jerni-dev) with the following command:

```bash
$ npm i jerni
$ npm i -D jerni-dev
```

For yarn users:

```bash
$ yarn add jerni
$ yarn add -D jerni-dev
```

> `jerni-dev` is a toolkit to improve developers' productivity and experience when developing a `jerni` app. It should never be used in production server.
>
> With `jerni-dev` developers don't have to worry about setting up and maintaining an events queue service. It also enables development only features like hot-reloading your event handlers and time-traveling your events history. Read more about `jerni-dev` at <https://github.com/tungv/jerni/blob/master/packages/jerni-dev/readme.md>

Then open `package.json` file for edit. You need to add a `subscribe-dev` script to `scripts` path.

```javascript
"scripts": {
  "subscribe-dev": "jerni-dev index.js"
}
```

![screenshot: package.json file with subscribe-dev scripts](https://3515816241-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LOkfsLjd-KkAAHYh7IT%2F-LP6RuFNYzMaXuMg5uDL%2F-LP6VPKQyvVCP7HbOQW3%2Fimage.png?alt=media\&token=64ea4670-d8a9-4c19-a22d-ca7f0dbf5c82)

## 3. Define Event Handlers

In this step, we're going to tell `jerni` what it should do when an event arrives. Base on the requirements, we need to react to event `"USER_REGISTERED"`. And the reaction is to insert a new document to mongodb describing the new user.

> in `jerni` an event describes something happened in the past. Events always have a unique and incremental `id`, a `type` and an optional `payload`. It's designed very similarly to a [Flux Standard Action](https://github.com/redux-utilities/flux-standard-action)
>
> Since it's about something that happened, the type should be in a past participle form, eg. `USER_REGISTERED` or `USER_DEACTIVATED`. Note that ALL\_CAPS convention is not a requirement but more a personal reference.

To be able to work with mongodb in the opinionated way of `jerni` we need to install `@jerni/store-mongo` using [npm](https://www.npmjs.com/package/@jerni/store-mongo):

```bash
$ npm i @jerni/store-mongo
```

Create a JavaScript file at `models/users.js` from the current working directory with the following content:

{% code title="models/users.js" %}

```javascript
const { Model } = require("@jerni/store-mongo");
const mapEvents = require("jerni/lib/mapEvents");

module.exports = new Model({
  name: "users",
  version: "1",
  transform: mapEvents({
    USER_REGISTERED: event => ({
      insertOne: {
        id: event.payload.user_id,
        name: event.payload.user_name,
        password: event.payload.hashed_password,
        referred_users: [],
        referral_point: 0
      }
    })
  })
});
```

{% endcode %}

Model is where you handle your events as they arrive. `transform` property accepts a pure function to transform an event into one or many mongodb operations such as `insertOne`/`insertMany` , `updateOne`/`updateMany` , `deleteOne`/`deleteMany`, for more details please read <https://github.com/tungv/jerni/tree/master/packages/store-mongo>

> `mapEvents` is a utility function to make it more readable. It's entirely optional but recommended.

## 4. Connect the journey

We are going to use `createJourney` function from `jerni` package to complete a journey. Please create `index.js` file from the current working directory with the following content:

{% code title="index.js" %}

```javascript
const createJourney = require("jerni");
const { Store } = require("@jerni/store-mongo");
const createJourney = require("jerni");

const { EVENT_STORE_URL } = process.env;

const mongoStore = new Store({
  name: "referral-app",
  url: "mongodb://localhost:27017",
  dbName: "referral-app",
  models: [require("./models/users")]
});

module.exports = createJourney({
  writeTo: EVENT_STORE_URL,
  stores: [mongoStore]
});
```

{% endcode %}

This code will create a journey by connecting an events queue service to your mongodb store. You can have more than one stores but only one events queue is allowed.

## 5. Start sending events


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.jerni.dev/master.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
