const NotFoundError = require('vn-loopback/util/not-found-error'); module.exports = Self => { Self.remoteMethod('pitInstance', { description: 'Gets the status of instance at specific point in time', accepts: [ { arg: 'id', type: 'integer', description: 'The log id', required: true } ], returns: { type: [Self], root: true }, http: { path: `/:id/pitInstance`, verb: 'GET' } }); Self.pitInstance = async function(id) { const log = await Self.findById(id, { fields: [ 'changedModel', 'changedModelId', 'creationDate' ] }); if (!log) throw new NotFoundError(); const where = { changedModel: log.changedModel, changedModelId: log.changedModelId }; // Fetch creation and all update logs for record up to requested log const createdWhere = { action: 'insert', creationDate: {lte: log.creationDate} }; const createdLog = await Self.findOne({ fields: ['id', 'creationDate', 'newInstance'], where: Object.assign(createdWhere, where), order: 'creationDate DESC, id DESC' }); const instance = {}; let logsWhere = { action: 'update' }; if (createdLog) { Object.assign(instance, createdLog.newInstance); Object.assign(logsWhere, { creationDate: {between: [ createdLog.creationDate, log.creationDate ]}, id: {between: [ Math.min(id, createdLog.id), Math.max(id, createdLog.id) ]} }); } else { Object.assign(logsWhere, { creationDate: {lte: log.creationDate}, id: {lte: id} }); } const logs = await Self.find({ fields: ['newInstance'], where: Object.assign(logsWhere, where), order: 'creationDate, id' }); if (!logs.length && !createdLog) throw new NotFoundError('No logs found for record'); // Merge all logs in order into one instance for (const log of logs) Object.assign(instance, log.newInstance); return instance; }; };