-
Notifications
You must be signed in to change notification settings - Fork 559
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #8201 from ever-co/798-activities-history
[Feature] Activities Logs entity and model for User / Organization / Team, etc.
- Loading branch information
Showing
9 changed files
with
424 additions
and
0 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,49 @@ | ||
import { ActorTypeEnum, IBasePerTenantAndOrganizationEntityModel, ID } from './base-entity.model'; | ||
import { IUser } from './user.model'; | ||
|
||
export interface IActivityLog extends IBasePerTenantAndOrganizationEntityModel { | ||
entity: ActivityLogEntityEnum; // Entity / Table name concerned by activity log | ||
entityId: ID; // The ID of the element we are interacting with (a task, an organization, an employee, ...) | ||
action: ActionTypeEnum; | ||
actorType?: ActorTypeEnum; | ||
description?: string; // A short sentence describing the action performed. (E.g John Doe created this on 22.09.2024) | ||
updatedFields?: string[]; // In case of update actions, which entity fields was modified simultaneously. Avoid multiple records. (E.g For task : ['name', 'members', 'projectId']) | ||
previousValues?: IActivityLogUpdatedValues[]; // Values before update (E.g For task : {title: ' First Task', members: ['Member1Name', 'Member2Name'], projectId: 'project1UUId'}) | ||
updatedValues?: IActivityLogUpdatedValues[]; // Values after update (E.g For task : {title: ' First Task Updated', members: ['Member4Name', 'Member3Name'], projectId: 'project2UUId'}) | ||
previousEntities?: IActivityLogUpdatedValues[]; // Stores previous IDs or other values for related entities. Eg : {members: ['member_1_ID', 'member_2_ID']} | ||
updatedEntities?: IActivityLogUpdatedValues[]; // Stores updated IDs, or other values for related entities. Eg : {members: ['member_1_ID', 'member_2_ID']}, | ||
creator?: IUser; | ||
creatorId?: ID; | ||
data?: Record<string, any>; | ||
} | ||
|
||
export enum ActionTypeEnum { | ||
CREATED = 'Created', | ||
UPDATED = 'Updated', | ||
DELETED = 'Deleted' | ||
} | ||
|
||
export interface IActivityLogUpdatedValues { | ||
[x: string]: any; | ||
} | ||
|
||
export enum ActivityLogEntityEnum { | ||
Candidate = 'Candidate', | ||
Contact = 'Contact', | ||
Employee = 'Employee', | ||
Expense = 'Expense', | ||
DailyPlan = 'DailyPlan', | ||
Invoice = 'Invoice', | ||
Income = 'Income', | ||
Organization = 'Organization', | ||
OrganizationContact = 'OrganizationContact', | ||
OrganizationDepartment = 'OrganizationDepartment', | ||
OrganizationDocument = 'OrganizationDocument', | ||
OrganizationProject = 'OrganizationProject', | ||
OrganizationTeam = 'OrganizationTeam', | ||
OrganizationProjectModule = 'OrganizationProjectModule', | ||
OrganizationSprint = 'OrganizationSprint', | ||
Task = 'Task', | ||
User = 'User' | ||
// Add other entities as we can to use them for activity history | ||
} |
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,121 @@ | ||
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; | ||
import { EntityRepositoryType } from '@mikro-orm/core'; | ||
import { IsArray, IsEnum, IsNotEmpty, IsOptional, IsString, IsUUID } from 'class-validator'; | ||
import { isMySQL, isPostgres } from '@gauzy/config'; | ||
import { | ||
ActivityLogEntityEnum, | ||
ActionTypeEnum, | ||
ActorTypeEnum, | ||
IActivityLog, | ||
IActivityLogUpdatedValues, | ||
ID, | ||
IUser | ||
} from '@gauzy/contracts'; | ||
import { TenantOrganizationBaseEntity, User } from '../core/entities/internal'; | ||
import { ColumnIndex, MultiORMColumn, MultiORMEntity, MultiORMManyToOne } from '../core/decorators/entity'; | ||
import { MikroOrmActivityLogRepository } from './repository/mikro-orm-activity-log.repository'; | ||
import { JoinColumn, RelationId } from 'typeorm'; | ||
|
||
@MultiORMEntity('activity_log', { mikroOrmRepository: () => MikroOrmActivityLogRepository }) | ||
export class ActivityLog extends TenantOrganizationBaseEntity implements IActivityLog { | ||
[EntityRepositoryType]?: MikroOrmActivityLogRepository; | ||
|
||
@ApiProperty({ type: () => String, enum: ActivityLogEntityEnum }) | ||
@IsNotEmpty() | ||
@IsEnum(ActivityLogEntityEnum) | ||
@ColumnIndex() | ||
@MultiORMColumn() | ||
entity: ActivityLogEntityEnum; | ||
|
||
@ApiProperty({ type: () => String }) | ||
@IsNotEmpty() | ||
@IsUUID() | ||
@ColumnIndex() | ||
@MultiORMColumn() | ||
entityId: string; | ||
|
||
@ApiProperty({ type: () => String, enum: ActionTypeEnum }) | ||
@IsNotEmpty() | ||
@IsEnum(ActionTypeEnum) | ||
@ColumnIndex() | ||
@MultiORMColumn() | ||
action: ActionTypeEnum; | ||
|
||
@ApiPropertyOptional({ type: () => String, enum: ActorTypeEnum }) | ||
@IsOptional() | ||
@IsEnum(ActorTypeEnum) | ||
@ColumnIndex() | ||
@MultiORMColumn({ nullable: true }) | ||
actorType?: ActorTypeEnum; | ||
|
||
@ApiPropertyOptional({ type: () => String }) | ||
@IsOptional() | ||
@IsString() | ||
@MultiORMColumn({ type: 'text', nullable: true }) | ||
description?: string; | ||
|
||
@ApiPropertyOptional({ type: () => Array }) | ||
@IsOptional() | ||
@IsArray() | ||
@MultiORMColumn({ type: isPostgres() ? 'jsonb' : isMySQL() ? 'json' : 'text', nullable: true }) | ||
updatedFields?: string[]; | ||
|
||
@ApiPropertyOptional({ type: () => Array }) | ||
@IsOptional() | ||
@IsArray() | ||
@MultiORMColumn({ type: isPostgres() ? 'jsonb' : isMySQL() ? 'json' : 'text', nullable: true }) | ||
previousValues?: IActivityLogUpdatedValues[]; | ||
|
||
@ApiPropertyOptional({ type: () => Array }) | ||
@IsOptional() | ||
@IsArray() | ||
@MultiORMColumn({ type: isPostgres() ? 'jsonb' : isMySQL() ? 'json' : 'text', nullable: true }) | ||
updatedValues?: IActivityLogUpdatedValues[]; | ||
|
||
@ApiPropertyOptional({ type: () => Array }) | ||
@IsOptional() | ||
@IsArray() | ||
@MultiORMColumn({ type: isPostgres() ? 'jsonb' : isMySQL() ? 'json' : 'text', nullable: true }) | ||
previousEntities?: IActivityLogUpdatedValues[]; | ||
|
||
@ApiPropertyOptional({ type: () => Array }) | ||
@IsOptional() | ||
@IsArray() | ||
@MultiORMColumn({ type: isPostgres() ? 'jsonb' : isMySQL() ? 'json' : 'text', nullable: true }) | ||
updatedEntities?: IActivityLogUpdatedValues[]; | ||
|
||
@ApiPropertyOptional({ type: () => Object }) | ||
@IsOptional() | ||
@IsArray() | ||
@MultiORMColumn({ type: isPostgres() ? 'jsonb' : isMySQL() ? 'json' : 'text', nullable: true }) | ||
data?: Record<string, any>; | ||
|
||
/* | ||
|-------------------------------------------------------------------------- | ||
| @ManyToOne | ||
|-------------------------------------------------------------------------- | ||
*/ | ||
|
||
/** | ||
* User performed action | ||
*/ | ||
@ApiPropertyOptional({ type: () => Object }) | ||
@IsOptional() | ||
@MultiORMManyToOne(() => User, { | ||
/** Indicates if relation column value can be nullable or not. */ | ||
nullable: true, | ||
|
||
/** Database cascade action on delete. */ | ||
onDelete: 'CASCADE' | ||
}) | ||
@JoinColumn() | ||
creator?: IUser; | ||
|
||
@ApiPropertyOptional({ type: () => String }) | ||
@IsOptional() | ||
@IsUUID() | ||
@RelationId((it: ActivityLog) => it.creator) | ||
@ColumnIndex() | ||
@MultiORMColumn({ nullable: true, relationId: true }) | ||
creatorId?: ID; | ||
} |
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 @@ | ||
export * from './mikro-orm-activity-log.repository'; |
4 changes: 4 additions & 0 deletions
4
packages/core/src/activity-log/repository/mikro-orm-activity-log.repository.ts
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,4 @@ | ||
import { MikroOrmBaseEntityRepository } from '../../core/repository/mikro-orm-base-entity.repository'; | ||
import { ActivityLog } from '../activity-log.entity'; | ||
|
||
export class MikroOrmActivityLogRepository extends MikroOrmBaseEntityRepository<ActivityLog> {} |
11 changes: 11 additions & 0 deletions
11
packages/core/src/activity-log/repository/type-orm-activity-log.repository.ts
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 @@ | ||
import { Injectable } from '@nestjs/common'; | ||
import { InjectRepository } from '@nestjs/typeorm'; | ||
import { Repository } from 'typeorm'; | ||
import { ActivityLog } from '../activity-log.entity'; | ||
|
||
@Injectable() | ||
export class TypeOrmActivityLogRepository extends Repository<ActivityLog> { | ||
constructor(@InjectRepository(ActivityLog) readonly repository: Repository<ActivityLog>) { | ||
super(repository.target, repository.manager, repository.queryRunner); | ||
} | ||
} |
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
Oops, something went wrong.