-
Notifications
You must be signed in to change notification settings - Fork 34
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: log activity for team create and edit
- Loading branch information
1 parent
5f7ffb0
commit 4978f75
Showing
17 changed files
with
311 additions
and
6 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import Hapi from '@hapi/hapi'; | ||
import * as Resource from './resource'; | ||
|
||
// groups/{groupId}/activities | ||
|
||
// activities?{} | ||
|
||
export const get = { | ||
description: 'get all activities or team activities', | ||
tags: ['api'], | ||
handler: async (request: Hapi.Request) => { | ||
const { team } = request.query; | ||
return Resource.get(team); | ||
} | ||
}; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import Hapi from '@hapi/hapi'; | ||
import * as Handler from './handler'; | ||
|
||
export const plugin = { | ||
name: 'activity', | ||
dependencies: 'postgres', | ||
register(server: Hapi.Server) { | ||
server.route([ | ||
{ | ||
method: 'GET', | ||
path: '/api/activities', | ||
options: Handler.get | ||
} | ||
]); | ||
} | ||
}; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { Activity } from '../../model/activity'; | ||
|
||
export const get = async (team = '') => { | ||
let criteria: any = { | ||
order: { | ||
createdAt: 'DESC' | ||
} | ||
}; | ||
|
||
if (team.length !== 0) { | ||
// fetch activities based on team | ||
criteria = Object.assign(criteria, { | ||
where: { | ||
team | ||
} | ||
}); | ||
} | ||
|
||
return Activity.find(criteria); | ||
}; | ||
|
||
export const create = async (payload: any) => { | ||
return await Activity.save({ ...payload }); | ||
}; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import Joi from 'joi'; | ||
import Config from '../../config/config'; | ||
|
||
const validationOptions = Config.get('/validationOptions'); | ||
|
||
export const ActivityPayload = Joi.object() | ||
.label('ActivityPayload') | ||
.keys({ | ||
id: Joi.string().required(), | ||
title: Joi.string().required(), | ||
team: Joi.string().required(), | ||
details: Joi.array().items(Joi.object().optional()), | ||
createdAt: Joi.date().iso().required(), | ||
createdBy: Joi.string().required() | ||
}) | ||
.options(validationOptions); |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import Faker from 'faker'; | ||
import { define } from 'typeorm-seeding'; | ||
import { Activity } from '../model/activity'; | ||
// import { User } from '../model/user'; | ||
|
||
define(Activity, (faker: typeof Faker) => { | ||
const activity = new Activity(); | ||
activity.id = faker.random.uuid(); | ||
activity.title = faker.random.words(3).toString(); | ||
activity.model = 'User'; | ||
activity.document = {}; | ||
activity.documentId = faker.random.uuid(); | ||
activity.diffs = [{}]; | ||
// const user = new User(); | ||
// user.id = faker.random.uuid(); | ||
// user.displayname = faker.random.word(); | ||
// activity.createdBy = user; | ||
return activity; | ||
}); |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { | ||
Entity, | ||
Column, | ||
CreateDateColumn, | ||
BaseEntity, | ||
PrimaryGeneratedColumn | ||
} from 'typeorm'; | ||
|
||
import Constants from '../utils/constant'; | ||
|
||
// eslint-disable-next-line import/no-cycle | ||
// import { User } from './user'; | ||
|
||
@Entity(Constants.MODEL.Activity) | ||
export class Activity extends BaseEntity { | ||
@PrimaryGeneratedColumn('uuid') | ||
id: string; | ||
|
||
@Column({ | ||
type: 'varchar', | ||
nullable: false | ||
}) | ||
title: string; | ||
|
||
@Column({ | ||
type: 'varchar', | ||
nullable: false | ||
}) | ||
model: string; | ||
|
||
@Column({ | ||
type: 'varchar', | ||
nullable: false | ||
}) | ||
documentId: string; | ||
|
||
@Column({ | ||
type: 'jsonb', | ||
nullable: false | ||
}) | ||
document: Record<string, string>; | ||
|
||
@Column({ | ||
type: 'jsonb', | ||
nullable: true | ||
}) | ||
diffs: Record<string, string>[]; | ||
|
||
@CreateDateColumn() | ||
createdAt: string; | ||
|
||
// @Column({ | ||
// type: 'varchar', | ||
// nullable: false | ||
// }) | ||
// @ManyToOne(() => User, (user) => user.activities) | ||
// createdBy: User; | ||
} |
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
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
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
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
import { | ||
EntitySubscriberInterface, | ||
EventSubscriber, | ||
InsertEvent, | ||
UpdateEvent | ||
} from 'typeorm'; | ||
import { delta } from '../utils/deep-diff'; | ||
import Constants from '../utils/constant'; | ||
import { create } from '../app/activity/resource'; | ||
|
||
const excludeFields = ['id', 'createdAt', 'updatedAt']; | ||
const actions = { | ||
CREATE: 'create', | ||
EDIT: 'edit' | ||
}; | ||
|
||
const getTitle = (event: any, type: string) => { | ||
let title = ''; | ||
switch (type) { | ||
case actions.CREATE: | ||
if (event.metadata.tableName === Constants.MODEL.Group) { | ||
title = `Created ${event.entity?.displayname} Team `; | ||
} else if (event.metadata.tableName === Constants.MODEL.CasbinRule) { | ||
title = `Created ${event.entity?.ptype} Casbin Rule `; | ||
} | ||
break; | ||
case actions.EDIT: | ||
if (event.metadata.tableName === Constants.MODEL.Group) { | ||
title = `Edited ${event.entity?.displayname}`; | ||
} else if (event.metadata.tableName === Constants.MODEL.CasbinRule) { | ||
title = `Edited ${event.entity?.ptype} Casbin Rule `; | ||
} | ||
break; | ||
default: | ||
title = ''; | ||
} | ||
|
||
return title; | ||
}; | ||
|
||
const getDiff = (event: any, type: string) => { | ||
switch (type) { | ||
case actions.CREATE: | ||
return delta({}, event.entity, { | ||
exclude: excludeFields | ||
}); | ||
case actions.EDIT: | ||
return delta(event.databaseEntity, event.entity, { | ||
exclude: excludeFields | ||
}); | ||
default: | ||
return []; | ||
} | ||
}; | ||
|
||
const storeActivityPayload = async (event: any, type: string) => { | ||
// console.log( | ||
// 'storeActivityPayload event -> ', | ||
// event.entity, | ||
// event.databaseEntity, | ||
// event.metadata.tableName | ||
// ); | ||
if ( | ||
event.metadata.tableName === Constants.MODEL.Activity || | ||
event.metadata.tableName === Constants.MODEL.Role || | ||
event.metadata.tableName === Constants.MODEL.User | ||
) { | ||
return; | ||
} | ||
const title = getTitle(event, type); | ||
await create({ | ||
document: event.entity, | ||
title, | ||
documentId: event.entity.id, | ||
model: event.metadata.tableName, | ||
diffs: getDiff(event, type) | ||
}); | ||
}; | ||
|
||
@EventSubscriber() | ||
export class ModelSubscriber implements EntitySubscriberInterface { | ||
afterInsert = async (event: InsertEvent<any>) => { | ||
await storeActivityPayload(event, actions.CREATE); | ||
}; | ||
|
||
afterUpdate = async (event: UpdateEvent<any>) => { | ||
await storeActivityPayload(event, actions.EDIT); | ||
}; | ||
|
||
/** | ||
* Called before entity removal. | ||
*/ | ||
// beforeRemove = async (event: RemoveEvent<any>) => { | ||
// console.log( | ||
// `BEFORE ENTITY WITH metadata.tableName ${JSON.stringify( | ||
// event.metadata.tableName | ||
// )} REMOVED: `, | ||
// event.entity | ||
// ); | ||
// }; | ||
|
||
/** | ||
* Called after entity removal. | ||
*/ | ||
// afterRemove = async (event: RemoveEvent<any>) => { | ||
// Object.keys(event.queryRunner.data).forEach((key) => { | ||
// console.log(`key => ${key} and value => ${event.queryRunner.data[key]}`); | ||
// }); | ||
// | ||
// console.log(`AFTER ENTITY WITH queryRunner REMOVED: `, event.entity); | ||
// }; | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
export default { | ||
MODEL: { | ||
Activity: 'activities', | ||
Group: 'groups', | ||
Role: 'roles', | ||
User: 'users', | ||
CasbinRule: 'casbin_rule' | ||
} | ||
}; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
const { diff } = require('deep-diff'); | ||
|
||
export const delta = ( | ||
previous = {}, | ||
current = {}, | ||
options?: { exclude: string[] } | ||
) => { | ||
return diff(previous, current).filter((i: any) => | ||
(options?.exclude || []).every((x: any) => i.path.indexOf(x) === -1) | ||
); | ||
}; |
Oops, something went wrong.