In financial and campaign management systems like Curved Lab, tracking who changed what, when, and from where is a non-negotiable security requirement. However, typical audit implementations suffer from severe architectural rot: developers pass userId, ipAddress, and userAgent down through ten layers of business logic, polluting function signatures from HTTP controllers all the way to deep database helpers.
To establish enterprise-grade audit logging without cluttering our domain services, we leveraged Node.js's native AsyncLocalStorage combined with Mongoose post-save lifecycle hooks. Here is how we engineered an invisible, tamper-evident audit trail.
Context Propagation Without Argument Drilling
AsyncLocalStorage allows storing state throughout the lifecycle of an asynchronous execution chain—similar to thread-local storage in Java or C#. When an HTTP request reaches our Express gateway, middleware intercepts the authenticated session, IP address, and request ID, wrapping the downstream request execution inside a scoped context store.
Any deep database repository or service executed within this promise chain can query the ambient context on demand without receiving it as an argument.
