Track your KPIs at a record level

Keeping track of your user activity can be a tedious process if not setup appropriately. Forest Admin provides you with the right tool to monitor the performance indicators that matter at a record level. With the analytics per account feature, you can systematically conduct a thorough monitoring of your data, anticipate and predict your customer's needs before they're even able to formulate it for better lead nurturing, trial conversion, and up-sells!

Then in this example, we can create a Smart Chart specific to the company Deliveroo. Sometimes, charts data are complicated and closely tied to your business. Choose “Smart” as the data source when configuring your chart. Forest Admin will make the HTTP call to Smart Chart URL when retrieving the chart values.

It's now time to code the logic to compute the chart values. In this example, we're retrieving the revenue data from a Stripe demo account to compute the MRR.

Lumber
Rails
Express/Sequelize
Express/Mongoose

To help us in this task, we use the library stripe, moment and bluebird.

When serializing the data, we use the Liana.StatSerializer() serializer. This function requires only one argument formatted like this:

{ value: <number> }

You can access the record id on which you are calculating the chart values is available through the variable req.body.record_id.

/routes/companies.js
const express = require('express');
const router = express.Router();
const Liana = require('forest-express-sequelize');
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
const moment = require('moment');
const P = require('bluebird');
router.post('/charts/mrr', Liana.ensureAuthenticated, (req, res) => {
let mrr = 0;
let from = moment.utc('2018-03-01').unix();
let to = moment.utc('2018-03-31').unix();
return stripe.charges
.list({
created: { gte: from, lte: to }
})
.then((response) => {
return P.each(response.data, (charge) => {
mrr += charge.amount;
});
})
.then(() => {
let json = new Liana.StatSerializer({
value: mrr
}).perform();
res.send(json);
});
});
module.exports = router;

When serializing the data, we use the serialize_model() method. Check the value syntax below.

{ value: <number> }
/config/routes.rb
Rails.application.routes.draw do
# MUST be declared before the mount ForestLiana::Engine.
namespace :forest do
post '/stats/mrr' => 'charts#mrr'
end
mount ForestLiana::Engine => '/forest'
end
/app/controllers/forest/charts_controller.rb
class Forest::ChartsController < ForestLiana::ApplicationController
def mrr
mrr = 0
from = Date.parse('2018-03-01').to_time(:utc).to_i
to = Date.parse('2018-03-31').to_time(:utc).to_i
Stripe::Charge.list({
created: { gte: from, lte: to },
limit: 100
}).each do |charge|
mrr += charge.amount / 100
end
stat = ForestLiana::Model::Stat.new({ value: mrr })
render json: serialize_model(stat)
end
end

To help us in this task, we use the library stripe, moment and bluebird.

When serializing the data, we use the Liana.StatSerializer() serializer. This function requires only one argument formatted like this:

{ value: <number> }

You can access the record id on which you are calculating the chart values is available through the variable req.body.record_id.

/routes/companies.js
const express = require('express');
const router = express.Router();
const Liana = require('forest-express-sequelize');
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
const moment = require('moment');
const P = require('bluebird');
router.post('/charts/mrr', Liana.ensureAuthenticated, (req, res) => {
let mrr = 0;
let from = moment.utc('2018-03-01').unix();
let to = moment.utc('2018-03-31').unix();
return stripe.charges
.list({
created: { gte: from, lte: to }
})
.then((response) => {
return P.each(response.data, (charge) => {
mrr += charge.amount;
});
})
.then(() => {
let json = new Liana.StatSerializer({
value: mrr
}).perform();
res.send(json);
});
});
module.exports = router;

To help us in this task, we use the library stripe, moment and bluebird.

When serializing the data, we use the Liana.StatSerializer() serializer. This function requires only one argument formatted like this:

{ value: <number> }

You can access the record id on which you are calculating the chart values is available through the variable req.body.record_id.

/routes/companies.js
const express = require('express');
const router = express.Router();
const Liana = require('forest-express-mongoose');
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
const moment = require('moment');
const P = require('bluebird');
router.post('/charts/mrr', Liana.ensureAuthenticated, (req, res) => {
let mrr = 0;
let from = moment.utc('2018-03-01').unix();
let to = moment.utc('2018-03-31').unix();
return stripe.charges
.list({
created: { gte: from, lte: to }
})
.then((response) => {
return P.each(response.data, (charge) => {
mrr += charge.amount;
});
})
.then(() => {
let json = new Liana.StatSerializer({
value: mrr
}).perform();
res.send(json);
});
});
module.exports = router;

Then, the chart is correctly rendered after restarting your back office server and refreshing the UI.

This step is now completed. 🎉