This example demonstrates v4.0.0 features of @cleancode-id/nestjs-sequelize-auditor with a complete NestJS application.
- π― Zero Setup - Just one decorator and module config
- π€ Built-in Creator -
include: ["creator"]works automatically - π‘οΈ Global Creator Fields - Secure creator data filtering
- π JWT Authentication - Automatic user tracking from Passport
- π¦ Bulk Operations - Individual audit records for bulk operations
- π Multi-Actor Support - Different user types (User, Admin)
- Node.js 16+
- MySQL database
- Basic NestJS knowledge
# 1. Clone and install
git clone <this-repo>
cd nest-sequelize-auditor-example
npm install
# 2. Database setup
cp .env.example .env
# Edit .env with your MySQL credentials
# Create database
mysql -u root -p -e "CREATE DATABASE IF NOT EXISTS \`nest-sequelize-auditor-example\`"
# 3. Seed test users
npx sequelize-cli db:seed:all
# 4. Start application
npm run start:devTest Users Created:
- admin@cleancode.id / password:
password - user@cleancode.id / password:
password
# 1. Login to get JWT
curl -X POST http://localhost:8001/auth/login \
-H "Content-Type: application/json" \
-d '{"email": "admin@cleancode.id", "password": "password"}'
# Response: {"access_token": "eyJ...", "user": {...}}# 2. Create post with authentication
curl -X POST http://localhost:8001/posts \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-d '{
"title": "Test Post",
"content": "Testing creator functionality",
"published": true
}'
# 3. Get posts with creator info
curl -H "Authorization: Bearer YOUR_TOKEN_HERE" \
http://localhost:8001/posts/paginatedResponse shows filtered creator data:
{
"count": 1,
"rows": [{
"id": 1,
"title": "Test Post",
"content": "Testing creator functionality",
"creator": {
"id": 1,
"name": "CleanCode Admin"
}
}]
}# Test bulk operations with individual audit tracking
curl -X POST http://localhost:8001/users/bulk \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-d '[
{"name": "User 1", "email": "user1@test.com", "password": "pass1"},
{"name": "User 2", "email": "user2@test.com", "password": "pass2"}
]'# Get all user audits
curl -H "Authorization: Bearer YOUR_TOKEN_HERE" \
http://localhost:8001/users/audits
# Get specific user with audit history
curl -H "Authorization: Bearer YOUR_TOKEN_HERE" \
http://localhost:8001/users/1?include=auditsAuditModule.forRoot({
autoSync: true, // Auto-create audit table
actorTypes: ['User'], // Models that can be actors
creatorFields: ['id', 'name'], // π₯ GLOBAL: Only safe fields in creator
auth: {
type: 'passport', // Use Passport.js
userProperty: 'user', // req.user
userIdField: 'user_id', // For custom user ID field
},
})@Auditable({
exclude: ['password', 'created_at', 'updated_at'],
auditEvents: [AuditEvent.CREATED, AuditEvent.UPDATED, AuditEvent.DELETED],
})
@Table({ tableName: 'users' })
export class User extends Model {
// β¨ Automatically available (v4.0.0):
// - audits: Audit[] relationship
// - creator: User virtual field (filtered by creatorFields)
// - creationAudit: Audit relationship
}src/
βββ auth/
β βββ auth.controller.ts # JWT login endpoints
β βββ auth.service.ts # Authentication logic
βββ user/
β βββ user.model.ts # π₯ @Auditable User model
β βββ user.service.ts # User CRUD with audit
β βββ user.controller.ts # REST API endpoints
βββ post/
β βββ post.model.ts # π₯ @Auditable Post model
β βββ post.service.ts # Post CRUD with creator
β βββ post.controller.ts # Creator relationship demos
βββ app.module.ts # π₯ AuditModule.forRoot() config
βββ main.ts
# Run all tests
npm test
# Run specific test files
npm test -- src/audit-relationships.spec.ts
npm test -- src/audit-bulk-operations.spec.tsTest Coverage:
- β Creator relationships
- β Global creator fields
- β Automatic relationship setup
- β Bulk operations
- β Authentication integration
- β Field filtering
The example uses "file:../package" so changes to the main package are automatically reflected:
- Edit package files in
../package/src/ - Rebuild:
cd ../package && npm run build - Restart example: Changes active immediately
-- Connect to your database
USE `nest-sequelize-auditor-example`;
-- See all audit activity
SELECT
id, event, auditable_type, auditable_id,
actorable_type, actorable_id, created_at
FROM audits
ORDER BY created_at DESC
LIMIT 10;Visit http://localhost:8001/debug/audit-relationships to see:
- Available model associations
- Actor relationship setup
- Raw audit data queries
The example demonstrates bulk operation performance considerations:
// β οΈ Bulk operations trigger additional SELECT queries
await User.bulkCreate([...]); // β
Fast
await User.update({...}, {where: {...}}); // β οΈ Slower (fetches old values)
await User.destroy({where: {...}}); // β οΈ Slower (fetches old values)See bulk operation tests in src/audit-bulk-operations.spec.ts for batching strategies.
@Auditable({
auditEvents: process.env.NODE_ENV === 'production'
? [AuditEvent.CREATED, AuditEvent.DELETED] // Skip updates in prod
: [AuditEvent.CREATED, AuditEvent.UPDATED, AuditEvent.DELETED]
})// β
Global creator field filtering
AuditModule.forRoot({
creatorFields: ['id', 'name'], // Never expose passwords
})
// β
Sensitive field masking
@Auditable({
exclude: ['password'],
mask: ['ssn', 'creditCard']
})| Endpoint | Method | Description |
|---|---|---|
/auth/login |
POST | Get JWT token |
/users |
GET | List users with creator |
/users/:id |
GET | Get user with audit history |
/posts/paginated |
GET | Paginated posts with creator |
/posts/:id/with-creator |
GET | Post with creator info |
/users/bulk |
POST | Test bulk operations |
/debug/audit-relationships |
GET | Debug audit setup |
- Try the API - Use the endpoints above with Postman/curl
- Explore Tests - Check the comprehensive test suite
- Check Database - See audit records in MySQL
- Customize Config - Modify
AuditModule.forRoot()options
This example helps validate package features. When adding new functionality:
- Add test cases in
src/*.spec.ts - Create example endpoints demonstrating the feature
- Update this README with usage examples
- Ensure all tests pass:
npm test
Need Help? Check the main package documentation or open an issue! π