Created
January 15, 2019 07:53
-
-
Save Restuta/e00694d58fad3f3f8908b25c65bc1d4c to your computer and use it in GitHub Desktop.
With Audit Log (proto)
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
/* tl;dr of the problem | |
- We have a funtion that updates objects and produces two values [updates, auditLogRecord]. | |
Let's call it "applyChangesWithAuditLog" | |
- We need to use this function in the context of another function (let's call it "update") and that another function should not be | |
aware of the fact that that auditLogRecord's are being produced and collected. | |
- When function "update" is executed, we want to collect all auditLogRecords that originated from calls | |
to "applyChangesWithAuditLog" inside "update" function. | |
- Then we want to save all collected auditLog items to DB. | |
Code below achieves this by building a functional wrapper. | |
*/ | |
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 stepFactory() { | |
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