@eherve/mongoose-track-plugin
v1.9.2
Published
A Mongoose plugin to **track, historize and audit changes** on specific schema fields. It generates an `.Info` field with metadata on the latest update, and optionally stores change history either inline or in a separate collection.
Readme
mongoose-track-plugin
A Mongoose plugin to track, historize and audit changes on specific schema fields. It generates an .Info field with metadata on the latest update, and optionally stores change history either inline or in a separate collection.
✨ Features
- ✅ Track updates on selected fields (
track: true | { ... }) - 📎 Generates a
.Infofield per tracked field (e.g.,statusInfo) - 🕒 Supports field-level history:
- In-document (e.g.,
statusHistory: [[timestamp, value, origin]]) - In external collections with rich metadata
- In-document (e.g.,
- 🧠 Track update origins using:
- A custom function per field
- The
originoption in.save()/.updateOne()/.updateMany()
- 🪝 Optional
onUpdatehook per field
📦 Installation
npm install mongoose-track-plugin🧩 Usage
1. Basic Setup
import mongoose from 'mongoose';
import trackPlugin from 'mongoose-track-plugin';
const schema = new mongoose.Schema({
status: {
type: String,
track: true, // Enable tracking
},
});
schema.plugin(trackPlugin);After update:
{
status: 'shipped',
statusInfo: {
updatedAt: Date,
value: 'shipped',
previousValue: 'pending',
origin: 'adminPanel'
}
}2. Advanced Field Tracking
const schema = new mongoose.Schema({
status: {
type: String,
track: {
origin: () => 'system-script',
historizeField: 'statusHistory', // inline history
onUpdate: (doc, field, info) => {
console.log(`${field} changed`, info);
},
},
},
});3. History in External Collection
const schema = new mongoose.Schema({
phase: {
type: String,
track: {
historizeCol: 'phase_histories', // use external collection
},
},
});Each history document will follow:
interface IHistorize<T> {
entityId: Types.ObjectId;
itemId?: Types.ObjectId;
path: string;
start: Date;
end: Date | null;
value?: T;
previousValue?: T;
nextValue?: T;
origin?: any;
metadata?: any;
}🧠 Providing origin
You can provide an origin for the update via:
A. Schema field config
track: {
origin: () => 'batch-script',
}B. Per-operation metadata
model.updateOne(filter, update, { origin: '[email protected]' });
document.save({ origin: 'cli' });🧪 Output Types
.Info Field
interface FieldUpdateInfo<T> {
updatedAt: Date;
value?: T;
previousValue?: T;
origin?: any;
}Inline History
[[timestamp, value, origin], ...]Collection History
See IHistorize<T> above.
✅ License
MIT
📬 Contributions
Issues and PRs welcome! Please write tests for any new logic.
🧱 Author
Made by @eherve
