Last active
January 15, 2019 03:25
-
-
Save Restuta/20e6352a37b59c69b0f260593fcb780b to your computer and use it in GitHub Desktop.
With Audit Log prototype
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// original version with binding to module instance | |
const { createAuditLogRecords } = require('../commands'); | |
const getStepFactory = require('./get-factory-by-type'); | |
const { createStep, updateStep } = require('./commands'); | |
const applyStepUpdates = require('./apply-step-updates'); | |
const createContainer = (items = []) => ({ | |
getAll: () => items, | |
add: x => items.push(x), | |
}); | |
// executes given function and then creates audit log records collected | |
const saveAuditLogAfterExecution = ({ | |
createAuditLogRecordsCommand, | |
getAuditLogRecords, | |
}) => updateFunc => async (...args) => { | |
const results = await updateFunc(...args); | |
await createAuditLogRecordsCommand(getAuditLogRecords()); | |
return results; | |
}; | |
const withAuditLogCollector = ({ auditLogProducingFunction, collectAuditLogRecord }) => ( | |
...args | |
) => { | |
const { updates, auditLogRecord } = auditLogProducingFunction(...args); | |
collectAuditLogRecord(auditLogRecord); | |
return updates; | |
}; | |
const stepFactory = ({ stepType, uponTransactionCommit, transaction }) => { | |
const createStepCommand = createStep(transaction); | |
const updateStepCommand = updateStep(transaction); | |
const auditLogRecordsContainer = createContainer(); | |
const applyUpdatesWithAuditLog = withAuditLogCollector({ | |
auditLogProducingFunction: applyStepUpdates, | |
collectAuditLogRecord: auditLogRecordsContainer.add, | |
}); | |
const { updateAsUser, updateAsAdmin } = getStepFactory(stepType)({ | |
createStepCommand, | |
updateStepWithAuditLogCommand, | |
uponTransactionCommit, | |
createAuditLogRecords | |
}); | |
const saveAuditLog = saveAuditLogAfterExecution({ | |
createAuditLogRecordsCommand: createAuditLogRecords(transaction), | |
getAuditLogRecords: auditLogRecordsContainer.getAll, | |
}); | |
return { | |
updateAsUser: saveAuditLog(updateAsUser), | |
updateAsAdmin: saveAuditLog(updateAsAdmin), | |
}; | |
}; | |
// ---------------- | |
const { updateAsUser, updateAsAdmin } = withAuditLog(applyStepUpdates)( | |
(applyUpdatesWithAuditLog, getCollectedAuditLogRecords) => { | |
const { updateAsUser, updateAsAdmin } = getStepFactory(stepType)({ | |
createStepCommand, | |
updateStepCommand, | |
applyUpdatesWithAuditLog, | |
uponTransactionCommit, | |
}) | |
const createAuditLogRecordsCommand = createAuditLogRecords(transaction) | |
const executeWithAuditLog = updateFunc => async (...args) => { | |
const results = await updateFunc(...args); | |
await createAuditLogRecordsCommand(getCollectedAuditLogRecords()); | |
return results; | |
}; | |
const withAuditLog = executeWithAuditLog({ | |
createAuditLogRecordsCommand: createAuditLogRecords(transaction), | |
getAuditLogRecords: auditLogRecordsContainer.getAll, | |
}); | |
} | |
/// | |
const { createAuditLogRecords } = require('../commands'); | |
const getStepFactory = require('./get-factory-by-type'); | |
const { createStep, updateStep } = require('./commands'); | |
const applyStepUpdates = require('./apply-step-updates'); | |
const createContainer = (items = []) => ({ | |
getAll: () => items, | |
add: x => items.push(x), | |
}); | |
// executes given function and then creates audit log records collected | |
const executeWithAuditLog = ({ | |
createAuditLogRecordsCommand, | |
getAuditLogRecords, | |
}) => updateFunc => async (...args) => { | |
const results = await updateFunc(...args); | |
await createAuditLogRecordsCommand(getAuditLogRecords()); | |
return results; | |
}; | |
const withAuditLogCollector = ({ auditLogProducingFunction, collectAuditLogRecord }) => ( | |
...args | |
) => { | |
const { updates, auditLogRecord } = auditLogProducingFunction(...args); | |
collectAuditLogRecord(auditLogRecord); | |
return updates; | |
}; | |
const stepFactory = ({ stepType, uponTransactionCommit, transaction }) => { | |
const createStepCommand = createStep(transaction); | |
const updateStepCommand = updateStep(transaction); | |
const auditLogRecordsContainer = createContainer(); | |
const applyUpdatesWithAuditLog = withAuditLogCollector({ | |
auditLogProducingFunction: applyStepUpdates, | |
collectAuditLogRecord: auditLogRecordsContainer.add, | |
}); | |
const { updateAsUser, updateAsAdmin } = getStepFactory(stepType)({ | |
createStepCommand, | |
updateStepCommand, | |
applyUpdatesWithAuditLog, | |
uponTransactionCommit, | |
}); | |
const withAuditLog = executeWithAuditLog({ | |
createAuditLogRecordsCommand: createAuditLogRecords(transaction), | |
getAuditLogRecords: auditLogRecordsContainer.getAll, | |
}); | |
return { | |
updateAsUser: withAuditLog(updateAsUser()), | |
updateAsAdmin: withAuditLog(updateAsAdmin), | |
}; | |
}; | |
module.exports = { | |
stepFactory, | |
}; | |
// ----------- | |
const updateFunc = ({ updateWithAuditLog }) => {}; | |
const createAuditLogCollector = ( | |
auditLogProducingFunction, | |
auditLogContainer = createContainer(), | |
) => ({ | |
func: (...args) => { | |
{ | |
const { updates, auditLogRecord } = auditLogProducingFunction(...args); | |
auditLogContainer.add(auditLogRecord); | |
return updates; | |
} | |
}, | |
getCollectedAuditRecords: auditLogContainer.getAll, | |
addRecord: auditLogContainer.add, | |
}); | |
const withAuditLog = updateFunc => auditLog => ({ | |
func: updateFunc(auditLog.func), | |
getCollectedAuditRecords: auditLog.getCollectedAuditRecords, | |
addRecord: auditLog.add, | |
} | |
const saveAuditLogAfterExecution = createAuditLogRecordsCommand => | |
({ getCollectedAuditRecords, func }) => | |
async (...args) => { | |
const results = await func(...args); | |
await createAuditLogRecordsCommand(auditLog.getCollectedAuditRecords()); | |
return results; | |
}; | |
const auditLogCollector = (createAuditLogRecordsCommand, auditLogProducingFunction) => | |
updateFunc => R.pipe( | |
createAuditLogCollector, | |
withAuditLog(updateFunc), | |
saveAuditLogAfterExecution(createAuditLogRecordsCommand) | |
)(auditLogProducingFunction) | |
// auditLog.foo() => updates (+ internal collect) | |
// auditLog.getCollectedItems() | |
function foo() { | |
const withAuditLog = auditLogCollector(createAuditLogRecordsCommand, auditLogProducingFunction); | |
return { | |
updateAsUser: withAuditLog(updateAsUser), | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment