server/routes.js (275 lines of code) (raw):

'use strict' const apm = require('elastic-apm-node') const express = require('express') const afterAll = require('after-all-results') const db = require('./db') const redis = require('./redis') const accounting = require('./accounting') const app = module.exports = new express.Router() app.get('/stats', function (req, res) { const next = afterAll(function (err, results) { if (err) return error(err, res) res.json({ products: results[0].rows[0].count, customers: results[1].rows[0].count, orders: results[2].rows[0].count, numbers: results[3] }) }) db.pool.query('SELECT COUNT(*) FROM products', next()) db.pool.query('SELECT COUNT(*) FROM customers', next()) db.pool.query('SELECT COUNT(*) FROM orders', next()) const done = next() const sql = 'SELECT product_id, COUNT(product_id) AS amount ' + 'FROM order_lines ' + 'GROUP BY product_id' db.pool.query(sql, function (err, result) { if (err) return done(err) const orderedProducts = result.rows const next = afterAll(function (err, results) { if (err) return done(err) const result = { revenue: 0, cost: 0, profit: 0 } results.forEach(function (r, index) { const product = r.rows[0] const amount = orderedProducts[index].amount const cost = product.cost * amount const revenue = product.selling_price * amount result.revenue += revenue result.cost += cost result.profit += revenue - cost }) done(null, result) }) orderedProducts.forEach(function (row) { const sql = 'SELECT cost, selling_price FROM products WHERE id=$1' db.pool.query(sql, [row.product_id], next()) }) }) }) app.get('/products', function (req, res) { redis.get('products', function (err, obj) { if (err) apm.captureError(err) else if (obj) return res.json(obj) const sql = 'SELECT p.id, p.sku, p.name, p.stock, t.name AS type_name FROM products p ' + 'LEFT JOIN product_types t ON p.type_id=t.id' db.pool.query(sql, function (err, result) { if (err) return error(err, res) res.json(result.rows) }) }) }) app.get('/products/top', function (req, res) { const sql = 'SELECT product_id, COUNT(product_id) AS amount ' + 'FROM order_lines ' + 'GROUP BY product_id ' + 'LIMIT 3' db.pool.query(sql, function (err, result) { if (err) return error(err, res) const next = afterAll(function (err, results) { if (err) return error(err, res) const top = result.rows.map(function (row, index) { const product = results[index].rows[0] product.sold = row.amount return product }) res.json(top) }) result.rows.forEach(function (row) { const sql = 'SELECT id, sku, name, stock FROM products WHERE id=$1' db.pool.query(sql, [row.product_id], next()) }) }) }) app.get('/products/:id', function (req, res) { const sql = 'SELECT p.*, t.name AS type_name FROM products p ' + 'LEFT JOIN product_types t ON p.type_id=t.id ' + 'WHERE p.id=$1' db.pool.query(sql, [req.params.id], function (err, result) { if (err) return error(err, res) if (result.rowCount === 0) return res.status(404).end() res.json(result.rows[0]) }) }) app.get('/products/:id/customers', function (req, res) { const limit = req.query.limit || 1000 const sql = 'SELECT c.* FROM customers c ' + 'LEFT JOIN orders o ON c.id=o.customer_id ' + 'LEFT JOIN order_lines l ON o.id=l.order_id ' + 'LEFT JOIN products p ON l.product_id=p.id ' + 'WHERE p.id=$1 ' + 'LIMIT $2' db.pool.query(sql, [req.params.id, limit], function (err, result) { if (err) return error(err, res) if (!req.query.count) return res.json(result.rows) const next = afterAll(function (err, results) { if (err) return error(err, res) result.rows.forEach(function (row, index) { row.orderCount = results[index].rows.length }) res.json(result.rows) }) result.rows.forEach(function (row) { const sql = 'SELECT * FROM orders WHERE customer_id=$1' db.pool.query(sql, [row.id], next()) }) }) }) app.get('/types', function (req, res) { redis.get('types', function (err, obj) { if (err) apm.captureError(err) else if (obj) return res.json(obj) db.pool.query('SELECT * FROM product_types', function (err, result) { if (err) return error(err, res) res.json(result.rows) }) }) }) app.get('/types/:id', function (req, res) { db.pool.query('SELECT * FROM product_types WHERE id=$1', [req.params.id], function (err, result) { if (err) return error(err, res) const type = result.rows[0] if (!type) return res.status(404).end() db.pool.query('SELECT id, name FROM products WHERE type_id=$1', [req.params.id], function (err, result) { if (err) return error(err, res) type.products = result.rows res.json(type) }) }) }) app.get('/customers', function (req, res) { redis.get('customers', function (err, obj) { if (err) apm.captureError(err) else if (obj) return res.json(obj) const limit = req.query.limit || 1000 const sql = 'SELECT * FROM customers LIMIT $1' db.pool.query(sql, [limit], function (err, result) { if (err) return error(err, res) res.json(result.rows) }) }) }) app.post('/customers', function (req, res) { const customer = req.body const isEmail = /^([a-zA-Z0-9])(([-.]|[_]+)?([a-zA-Z0-9]+))*(@){1}[a-z0-9]+[.]{1}(([a-z]{2,3})|([a-z]{2,3}[.]{1}[a-z]{2,3}))$/ if (!customer.full_name || !customer.company_name || !isEmail.test(customer.email)) { res.status(400).end() return } const sql = 'INSERT INTO customers (full_name, company_name, email, address, postal_code, city, country) VALUES ($1, $2, $3, $4, $5, $6, $7)' const values = [ customer.full_name, customer.company_name, customer.email, customer.address, customer.postal_code, customer.city, customer.country ] db.pool.query(sql, values, function (err) { if (err) return error(err, res) res.end() }) }) app.get('/customers/:id', function (req, res) { db.pool.query('SELECT * FROM customers WHERE id=$1', [req.params.id], function (err, result) { if (err) return error(err, res) if (result.rowCount === 0) return res.status(404).end() res.json(result.rows[0]) }) }) app.get('/orders', function (req, res) { redis.get('orders', function (err, obj) { if (err) apm.captureError(err) else if (obj) return res.json(obj) const limit = req.query.limit || 1000 const sql = 'SELECT o.*, c.full_name AS customer_name FROM orders o ' + 'LEFT JOIN customers c ON c.id=o.customer_id ' + 'LIMIT $1' db.pool.query(sql, [limit], function (err, result) { if (err) return error(err, res) res.json(result.rows) }) }) }) /** * Example body: * { * customer_id: 1, * lines: [ * {id: 1, amount: 1} * ] * } */ app.post('/orders', function (req, res) { if (!req.body.customer_id || !req.body.lines) { res.status(400).end() return } db.client(function (err, client, done) { if (err) return error(err, res) const next = afterAll(function (err, results) { if (err) { done() error(err, res) return } if (results.some(function (result) { return result.rowCount === 0 })) { done() res.status(400).end() return } client.query('BEGIN', function (err) { if (err) return rollback(err) const sql = 'INSERT INTO orders (customer_id) VALUES ($1) RETURNING id' client.query(sql, [req.body.customer_id], function (err, result) { if (err) return rollback(err) const id = result.rows[0].id const next = afterAll(function (err) { if (err) return rollback(err) accounting.placeOrder({ id: id }, function (err) { if (err) return rollback(err) client.query('COMMIT', function (err) { if (err) return rollback(err) done() redis.set('newest-order', id, function (err) { if (err) return error(err, res) res.json({ id: id }) }) }) }) }) req.body.lines.forEach(function (line) { const sql = 'INSERT INTO order_lines (order_id, product_id, amount) ' + 'VALUES ($1, $2, $3)' client.query(sql, [id, line.id, line.amount], next()) }) }) function rollback (err) { apm.captureError(err) client.query('ROLLBACK', function (err) { if (err) apm.captureError(err) done(err) res.status(500).end() }) } }) }) client.query('SELECT id FROM customers WHERE id=$1', [req.body.customer_id], next()) req.body.lines.forEach(function (line) { client.query('SELECT id FROM products WHERE id=$1', [line.id], next()) }) }) }) app.get('/orders/:id', function (req, res) { db.pool.query('SELECT * FROM orders WHERE id=$1', [req.params.id], function (err, result) { if (err) return error(err, res) const order = result.rows[0] if (!order) return res.status(404).end() const sql = 'SELECT l.amount, p.* FROM order_lines l ' + 'LEFT JOIN products p ON l.product_id=p.id ' + 'WHERE l.order_id=$1' db.pool.query(sql, [req.params.id], function (err, result) { if (err) return error(err, res) order.lines = result.rows apm.setCustomContext({ orderLines: result.rows.length }) res.json(order) }) }) }) function error (err, res) { apm.captureError(err) res.status(500).end() }