Maintain a central history of changes to tables ( models ) in sequelize.
npm install sequelize-central-logsh
npm install sequelize-central-log
`
Usage
$3
Sequelize Central log needs your initated sequelize connection for example:
`typescript
import { Sequelize } from 'sequelize';
const sequelize = new Sequelize('database', 'username', 'password');
`
Import Sequelize Central Log, create a new instance by passing in your sequelize instance and options ( see below ) as
well as defineModels() to setup the revision model, which should be done after initalizing them in sequelize.
`typescript
import { SequelizeCentralLog } from 'sequelize-central-log';
const options = {...}; // define options from list below
const centralLog = new SequelizeCentralLog(sequelize, options);
const Revision = centralLog.defineModels(); // returns your revision model instance for querying
`
This sets up your central log (revision table) and returns the table instance to be used for querying.
Lastly for each model you want to track history on call the addHistory function passing in the model.
`typescript
centralLog.addHistory(sequelize.model('ModelName'));
// For those that define their models as a class, you can simply pass that class in.
import SequelizeModelClass from '../sequelize_model_class';
centralLog.addHistory(SequelizeModelClass);
`
The hasHistory function will add a hasMany association from the model to the revision model so you can include and have
revisions returned with your results.
$3
There are two ways to exclude columns from being tracked in the revision history table.
You can pass them in as a string array your options when instantiating the Sequelize Central Log ( this will override the defaults).
See options below for the defaults. You can override the defaults by passing an empty array.
`typescript
const centralLog = new SequelizeCentralLog(sequelizeDB, { exclude: ['column1', 'column2']});
`
or you can pass them in per model as a string array when adding the history to the sequelize model:
`typescript
centralLog.addHistory(ModelA, {exclude: ['columnModelA']});
centralLog.addHistory(ModelB);
`
General exclude and model level exclude are added together on the model level. So a globally excluded id column will apply to every
model while a column excluded when adding history to the model will be excluded only for that table.
Example based on the setup above:
1. Table A will have the columns id and columnModelA excluded.
2. Table B will only have the id column excluded.
$3
You can use composite keys while tracking history. Current limitations are limited to 2 keys currently.
The second key is tracked in a column added to the revision table modelId2, (which you can override the column name). A
Third Composite key works the same with a default of modelId3.
This is configured by passing the option when creating the log and then per model.
`typescript
const centralLog = new SequelizeCentralLog(sequelizeDB, {useCompositeKeys: true});
centralLog.addHistory(Model, { hasCompositeKey: true });
/**
* For a Third Composite Key
*/
centralLog.addHistory(Model, { hasCompositeKey: true, thirdCompositeKey: true });
`
This will still create the hasMany association on the model and will pull back the revisions. YAY!
$3
You can track the author of the revision by passing the user model as an option when creating the SequelizeCentralLog
instance( model must be initialized in sequelize first).
`typescript
const centralLog = SequelizeCentralLog(sequelizeDB, {userModel: User});
`
This will create a foreign key ( allowed null ) column on the revision table pointing to the id column in the user model.
There are two ways to set the userid when tracking the author. You can use a namespace (cls-hooked) or pass a userId as an option on the
sequelize query. The option passed on the query will override the namespace if you want to for some reason.
`typescript
import { createNamespace } from 'cls-hooked';
const nameSpace = createNamespace('amespaceName');
// don't forget to call run on the namespace.
nameSpace.run(() => {
nameSpace.set('keyName', userID);
// somehwere in your async chain..
Model.update(...{});
Model.create(...{});
});
/**
* OR
*/
Model.update({...values}, {userId: userID});
`
For when you need to create an entry that is an anonymous user even though the data doesn't gets saved in the table
the revision history will have it. In order to prevent the user from being logged, used the propery skipLoggingUser
on the query as a model configuration option.
ex:
`typescript
Model.update({...values}, {skipLoggingUser: true});
`
$3
By default Sequelize Central Log will track bulk actions. You can disable this on a per model basis.
`typescript
CentralLog.hasHistory(Model, {disableHistoryAutoHook: true});
``