Update what is being audit logged (#11833)

No need to audit log workflow runs as it's already a form of audit log.
Add more audit log for other objects
Rename MessagingTelemetry to MessagingMonitoring
Merge Analytics and Audit in one (Audit)

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
This commit is contained in:
Félix Malfait
2025-05-04 14:35:41 +02:00
committed by GitHub
parent b1994f3707
commit 49b7f5255f
101 changed files with 948 additions and 1032 deletions

View File

@ -4,7 +4,6 @@ import { FieldMetadataType } from 'twenty-shared/types';
import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity';
import { WorkspaceEntity } from 'src/engine/twenty-orm/decorators/workspace-entity.decorator';
import { WorkspaceField } from 'src/engine/twenty-orm/decorators/workspace-field.decorator';
import { WorkspaceIsNotAuditLogged } from 'src/engine/twenty-orm/decorators/workspace-is-not-audit-logged.decorator';
import { WorkspaceIsNullable } from 'src/engine/twenty-orm/decorators/workspace-is-nullable.decorator';
import { WorkspaceIsSystem } from 'src/engine/twenty-orm/decorators/workspace-is-system.decorator';
import { API_KEY_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
@ -21,7 +20,6 @@ import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync
labelIdentifierStandardId: API_KEY_STANDARD_FIELD_IDS.name,
})
@WorkspaceIsSystem()
@WorkspaceIsNotAuditLogged()
export class ApiKeyWorkspaceEntity extends BaseWorkspaceEntity {
@WorkspaceField({
standardId: API_KEY_STANDARD_FIELD_IDS.name,

View File

@ -1,14 +1,13 @@
import { msg } from '@lingui/core/macro';
import { FieldMetadataType } from 'twenty-shared/types';
import { RelationOnDeleteAction } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-on-delete-action.interface';
import { RelationType } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-type.interface';
import { Relation } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/relation.interface';
import { RelationOnDeleteAction } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-on-delete-action.interface';
import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity';
import { WorkspaceEntity } from 'src/engine/twenty-orm/decorators/workspace-entity.decorator';
import { WorkspaceField } from 'src/engine/twenty-orm/decorators/workspace-field.decorator';
import { WorkspaceIsNotAuditLogged } from 'src/engine/twenty-orm/decorators/workspace-is-not-audit-logged.decorator';
import { WorkspaceIsSystem } from 'src/engine/twenty-orm/decorators/workspace-is-system.decorator';
import { WorkspaceJoinColumn } from 'src/engine/twenty-orm/decorators/workspace-join-column.decorator';
import { WorkspaceRelation } from 'src/engine/twenty-orm/decorators/workspace-relation.decorator';
@ -27,7 +26,6 @@ import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/sta
labelIdentifierStandardId: BLOCKLIST_STANDARD_FIELD_IDS.handle,
})
@WorkspaceIsSystem()
@WorkspaceIsNotAuditLogged()
export class BlocklistWorkspaceEntity extends BaseWorkspaceEntity {
@WorkspaceField({
standardId: BLOCKLIST_STANDARD_FIELD_IDS.handle,

View File

@ -11,7 +11,6 @@ import { Relation } from 'src/engine/workspace-manager/workspace-sync-metadata/i
import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity';
import { WorkspaceEntity } from 'src/engine/twenty-orm/decorators/workspace-entity.decorator';
import { WorkspaceField } from 'src/engine/twenty-orm/decorators/workspace-field.decorator';
import { WorkspaceIsNotAuditLogged } from 'src/engine/twenty-orm/decorators/workspace-is-not-audit-logged.decorator';
import { WorkspaceIsNullable } from 'src/engine/twenty-orm/decorators/workspace-is-nullable.decorator';
import { WorkspaceIsSystem } from 'src/engine/twenty-orm/decorators/workspace-is-system.decorator';
import { WorkspaceJoinColumn } from 'src/engine/twenty-orm/decorators/workspace-join-column.decorator';
@ -33,7 +32,6 @@ import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/sta
labelIdentifierStandardId: CONNECTED_ACCOUNT_STANDARD_FIELD_IDS.handle,
})
@WorkspaceIsSystem()
@WorkspaceIsNotAuditLogged()
export class ConnectedAccountWorkspaceEntity extends BaseWorkspaceEntity {
@WorkspaceField({
standardId: CONNECTED_ACCOUNT_STANDARD_FIELD_IDS.handle,

View File

@ -4,12 +4,12 @@ import { FieldMetadataType } from 'twenty-shared/types';
import { RelationType } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-type.interface';
import { Relation } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/relation.interface';
import { RelationOnDeleteAction } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity';
import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity';
import { CustomWorkspaceEntity } from 'src/engine/twenty-orm/custom.workspace-entity';
import { WorkspaceDynamicRelation } from 'src/engine/twenty-orm/decorators/workspace-dynamic-relation.decorator';
import { WorkspaceEntity } from 'src/engine/twenty-orm/decorators/workspace-entity.decorator';
import { WorkspaceField } from 'src/engine/twenty-orm/decorators/workspace-field.decorator';
import { WorkspaceIsNotAuditLogged } from 'src/engine/twenty-orm/decorators/workspace-is-not-audit-logged.decorator';
import { WorkspaceIsNullable } from 'src/engine/twenty-orm/decorators/workspace-is-nullable.decorator';
import { WorkspaceIsSystem } from 'src/engine/twenty-orm/decorators/workspace-is-system.decorator';
import { WorkspaceJoinColumn } from 'src/engine/twenty-orm/decorators/workspace-join-column.decorator';
@ -28,7 +28,6 @@ import { WorkflowRunWorkspaceEntity } from 'src/modules/workflow/common/standard
import { WorkflowVersionWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-version.workspace-entity';
import { WorkflowWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow.workspace-entity';
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
import { RelationOnDeleteAction } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity';
@WorkspaceEntity({
standardId: STANDARD_OBJECT_IDS.favorite,
@ -38,7 +37,6 @@ import { RelationOnDeleteAction } from 'src/engine/metadata-modules/relation-met
description: msg`A favorite that can be accessed from the left menu`,
icon: STANDARD_OBJECT_ICONS.favorite,
})
@WorkspaceIsNotAuditLogged()
@WorkspaceIsSystem()
export class FavoriteWorkspaceEntity extends BaseWorkspaceEntity {
@WorkspaceField({

View File

@ -19,7 +19,7 @@ import {
MessageImportSyncStep,
} from 'src/modules/messaging/message-import-manager/services/messaging-import-exception-handler.service';
import { MessagingPartialMessageListFetchService } from 'src/modules/messaging/message-import-manager/services/messaging-partial-message-list-fetch.service';
import { MessagingTelemetryService } from 'src/modules/messaging/monitoring/services/messaging-telemetry.service';
import { MessagingMonitoringService } from 'src/modules/messaging/monitoring/services/messaging-monitoring.service';
export type MessagingMessageListFetchJobData = {
messageChannelId: string;
@ -36,7 +36,7 @@ export class MessagingMessageListFetchJob {
constructor(
private readonly messagingFullMessageListFetchService: MessagingFullMessageListFetchService,
private readonly messagingPartialMessageListFetchService: MessagingPartialMessageListFetchService,
private readonly messagingTelemetryService: MessagingTelemetryService,
private readonly messagingMonitoringService: MessagingMonitoringService,
private readonly twentyORMManager: TwentyORMManager,
private readonly connectedAccountRefreshTokensService: ConnectedAccountRefreshTokensService,
private readonly messageImportErrorHandlerService: MessageImportExceptionHandlerService,
@ -46,7 +46,7 @@ export class MessagingMessageListFetchJob {
async handle(data: MessagingMessageListFetchJobData): Promise<void> {
const { messageChannelId, workspaceId } = data;
await this.messagingTelemetryService.track({
await this.messagingMonitoringService.track({
eventName: 'message_list_fetch_job.triggered',
messageChannelId,
workspaceId,
@ -65,7 +65,7 @@ export class MessagingMessageListFetchJob {
});
if (!messageChannel) {
await this.messagingTelemetryService.track({
await this.messagingMonitoringService.track({
eventName: 'message_list_fetch_job.error.message_channel_not_found',
messageChannelId,
workspaceId,
@ -94,7 +94,7 @@ export class MessagingMessageListFetchJob {
switch (error.code) {
case ConnectedAccountRefreshAccessTokenExceptionCode.REFRESH_ACCESS_TOKEN_FAILED:
case ConnectedAccountRefreshAccessTokenExceptionCode.REFRESH_TOKEN_NOT_FOUND:
await this.messagingTelemetryService.track({
await this.messagingMonitoringService.track({
eventName: `refresh_token.error.insufficient_permissions`,
workspaceId,
connectedAccountId: messageChannel.connectedAccountId,
@ -121,7 +121,7 @@ export class MessagingMessageListFetchJob {
`Fetching partial message list for workspace ${workspaceId} and messageChannelId ${messageChannel.id}`,
);
await this.messagingTelemetryService.track({
await this.messagingMonitoringService.track({
eventName: 'partial_message_list_fetch.started',
workspaceId,
connectedAccountId: messageChannel.connectedAccount.id,
@ -134,7 +134,7 @@ export class MessagingMessageListFetchJob {
workspaceId,
);
await this.messagingTelemetryService.track({
await this.messagingMonitoringService.track({
eventName: 'partial_message_list_fetch.completed',
workspaceId,
connectedAccountId: messageChannel.connectedAccount.id,
@ -148,7 +148,7 @@ export class MessagingMessageListFetchJob {
`Fetching full message list for workspace ${workspaceId} and account ${messageChannel.connectedAccount.id}`,
);
await this.messagingTelemetryService.track({
await this.messagingMonitoringService.track({
eventName: 'full_message_list_fetch.started',
workspaceId,
connectedAccountId: messageChannel.connectedAccount.id,
@ -160,7 +160,7 @@ export class MessagingMessageListFetchJob {
workspaceId,
);
await this.messagingTelemetryService.track({
await this.messagingMonitoringService.track({
eventName: 'full_message_list_fetch.completed',
workspaceId,
connectedAccountId: messageChannel.connectedAccount.id,

View File

@ -10,8 +10,7 @@ import {
MessageChannelWorkspaceEntity,
} from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity';
import { MessagingMessagesImportService } from 'src/modules/messaging/message-import-manager/services/messaging-messages-import.service';
import { MessagingTelemetryService } from 'src/modules/messaging/monitoring/services/messaging-telemetry.service';
import { MessagingMonitoringService } from 'src/modules/messaging/monitoring/services/messaging-monitoring.service';
export type MessagingMessagesImportJobData = {
messageChannelId: string;
workspaceId: string;
@ -24,7 +23,7 @@ export type MessagingMessagesImportJobData = {
export class MessagingMessagesImportJob {
constructor(
private readonly messagingMessagesImportService: MessagingMessagesImportService,
private readonly messagingTelemetryService: MessagingTelemetryService,
private readonly messagingMonitoringService: MessagingMonitoringService,
private readonly twentyORMManager: TwentyORMManager,
) {}
@ -32,7 +31,7 @@ export class MessagingMessagesImportJob {
async handle(data: MessagingMessagesImportJobData): Promise<void> {
const { messageChannelId, workspaceId } = data;
await this.messagingTelemetryService.track({
await this.messagingMonitoringService.track({
eventName: 'messages_import.triggered',
workspaceId,
messageChannelId,
@ -51,7 +50,7 @@ export class MessagingMessagesImportJob {
});
if (!messageChannel) {
await this.messagingTelemetryService.track({
await this.messagingMonitoringService.track({
eventName: 'messages_import.error.message_channel_not_found',
messageChannelId,
workspaceId,

View File

@ -20,8 +20,7 @@ import { MessagingGetMessagesService } from 'src/modules/messaging/message-impor
import { MessageImportExceptionHandlerService } from 'src/modules/messaging/message-import-manager/services/messaging-import-exception-handler.service';
import { MessagingMessagesImportService } from 'src/modules/messaging/message-import-manager/services/messaging-messages-import.service';
import { MessagingSaveMessagesAndEnqueueContactCreationService } from 'src/modules/messaging/message-import-manager/services/messaging-save-messages-and-enqueue-contact-creation.service';
import { MessagingTelemetryService } from 'src/modules/messaging/monitoring/services/messaging-telemetry.service';
import { MessagingMonitoringService } from 'src/modules/messaging/monitoring/services/messaging-monitoring.service';
describe('MessagingMessagesImportService', () => {
let service: MessagingMessagesImportService;
let messageChannelSyncStatusService: MessageChannelSyncStatusService;
@ -78,7 +77,7 @@ describe('MessagingMessagesImportService', () => {
},
},
{
provide: MessagingTelemetryService,
provide: MessagingMonitoringService,
useValue: {
track: jest.fn().mockResolvedValue(undefined),
},

View File

@ -26,8 +26,7 @@ import {
} from 'src/modules/messaging/message-import-manager/services/messaging-import-exception-handler.service';
import { MessagingSaveMessagesAndEnqueueContactCreationService } from 'src/modules/messaging/message-import-manager/services/messaging-save-messages-and-enqueue-contact-creation.service';
import { filterEmails } from 'src/modules/messaging/message-import-manager/utils/filter-emails.util';
import { MessagingTelemetryService } from 'src/modules/messaging/monitoring/services/messaging-telemetry.service';
import { MessagingMonitoringService } from 'src/modules/messaging/monitoring/services/messaging-monitoring.service';
@Injectable()
export class MessagingMessagesImportService {
private readonly logger = new Logger(MessagingMessagesImportService.name);
@ -38,7 +37,7 @@ export class MessagingMessagesImportService {
private readonly messageChannelSyncStatusService: MessageChannelSyncStatusService,
private readonly saveMessagesAndEnqueueContactCreationService: MessagingSaveMessagesAndEnqueueContactCreationService,
private readonly connectedAccountRefreshTokensService: ConnectedAccountRefreshTokensService,
private readonly messagingTelemetryService: MessagingTelemetryService,
private readonly messagingMonitoringService: MessagingMonitoringService,
@InjectObjectMetadataRepository(BlocklistWorkspaceEntity)
private readonly blocklistRepository: BlocklistRepository,
private readonly emailAliasManagerService: EmailAliasManagerService,
@ -62,7 +61,7 @@ export class MessagingMessagesImportService {
return;
}
await this.messagingTelemetryService.track({
await this.messagingMonitoringService.track({
eventName: 'messages_import.started',
workspaceId,
connectedAccountId: messageChannel.connectedAccountId,
@ -87,7 +86,7 @@ export class MessagingMessagesImportService {
switch (error.code) {
case ConnectedAccountRefreshAccessTokenExceptionCode.REFRESH_ACCESS_TOKEN_FAILED:
case ConnectedAccountRefreshAccessTokenExceptionCode.REFRESH_TOKEN_NOT_FOUND:
await this.messagingTelemetryService.track({
await this.messagingMonitoringService.track({
eventName: `refresh_token.error.insufficient_permissions`,
workspaceId,
connectedAccountId: messageChannel.connectedAccountId,
@ -208,7 +207,7 @@ export class MessagingMessagesImportService {
messageChannel: MessageChannelWorkspaceEntity,
workspaceId: string,
) {
await this.messagingTelemetryService.track({
await this.messagingMonitoringService.track({
eventName: 'messages_import.completed',
workspaceId,
connectedAccountId: messageChannel.connectedAccountId,

View File

@ -1,7 +1,7 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AnalyticsModule } from 'src/engine/core-modules/analytics/analytics.module';
import { AuditModule } from 'src/engine/core-modules/audit/audit.module';
import { FeatureFlag } from 'src/engine/core-modules/feature-flag/feature-flag.entity';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
@ -22,7 +22,7 @@ import { TimelineActivityWorkspaceEntity } from 'src/modules/timeline/standard-o
@Module({
imports: [
TypeOrmModule.forFeature([FeatureFlag, Workspace], 'core'),
AnalyticsModule,
AuditModule,
ContactCreationManagerModule,
WorkspaceDataSourceModule,
ObjectMetadataRepositoryModule.forFeature([

View File

@ -13,7 +13,7 @@ import { MessageQueue } from 'src/engine/core-modules/message-queue/message-queu
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
import { MessageChannelWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity';
import { MessagingTelemetryService } from 'src/modules/messaging/monitoring/services/messaging-telemetry.service';
import { MessagingMonitoringService } from 'src/modules/messaging/monitoring/services/messaging-monitoring.service';
export const MESSAGING_MESSAGE_CHANNEL_SYNC_STATUS_MONITORING_CRON_PATTERN =
'2/10 * * * *'; //Every 10 minutes, starting at 2 minutes past the hour
@ -27,7 +27,7 @@ export class MessagingMessageChannelSyncStatusMonitoringCronJob {
constructor(
@InjectRepository(Workspace, 'core')
private readonly workspaceRepository: Repository<Workspace>,
private readonly messagingTelemetryService: MessagingTelemetryService,
private readonly messagingMonitoringService: MessagingMonitoringService,
private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
private readonly exceptionHandlerService: ExceptionHandlerService,
) {}
@ -40,7 +40,7 @@ export class MessagingMessageChannelSyncStatusMonitoringCronJob {
async handle(): Promise<void> {
this.logger.log('Starting message channel sync status monitoring...');
await this.messagingTelemetryService.track({
await this.messagingMonitoringService.track({
eventName: 'message_channel.monitoring.sync_status.start',
message: 'Starting message channel sync status monitoring',
});
@ -66,7 +66,7 @@ export class MessagingMessageChannelSyncStatusMonitoringCronJob {
if (!messageChannel.syncStatus) {
continue;
}
await this.messagingTelemetryService.track({
await this.messagingMonitoringService.track({
eventName: `message_channel.monitoring.sync_status.${snakeCase(
messageChannel.syncStatus,
)}`,

View File

@ -1,18 +1,18 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AnalyticsModule } from 'src/engine/core-modules/analytics/analytics.module';
import { AuditModule } from 'src/engine/core-modules/audit/audit.module';
import { BillingModule } from 'src/engine/core-modules/billing/billing.module';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { DataSourceEntity } from 'src/engine/metadata-modules/data-source/data-source.entity';
import { MessagingCommonModule } from 'src/modules/messaging/common/messaging-common.module';
import { MessagingMessageChannelSyncStatusMonitoringCronCommand } from 'src/modules/messaging/monitoring/crons/commands/messaging-message-channel-sync-status-monitoring.cron.command';
import { MessagingMessageChannelSyncStatusMonitoringCronJob } from 'src/modules/messaging/monitoring/crons/jobs/messaging-message-channel-sync-status-monitoring.cron.job';
import { MessagingTelemetryService } from 'src/modules/messaging/monitoring/services/messaging-telemetry.service';
import { MessagingMonitoringService } from 'src/modules/messaging/monitoring/services/messaging-monitoring.service';
@Module({
imports: [
AnalyticsModule,
AuditModule,
MessagingCommonModule,
BillingModule,
TypeOrmModule.forFeature([Workspace], 'core'),
@ -21,8 +21,8 @@ import { MessagingTelemetryService } from 'src/modules/messaging/monitoring/serv
providers: [
MessagingMessageChannelSyncStatusMonitoringCronCommand,
MessagingMessageChannelSyncStatusMonitoringCronJob,
MessagingTelemetryService,
MessagingMonitoringService,
],
exports: [MessagingTelemetryService],
exports: [MessagingMonitoringService],
})
export class MessagingMonitoringModule {}

View File

@ -0,0 +1,47 @@
import { Injectable } from '@nestjs/common';
import { AuditService } from 'src/engine/core-modules/audit/services/audit.service';
type MessagingMonitoringTrackInput = {
eventName: string;
workspaceId?: string;
userId?: string;
connectedAccountId?: string;
messageChannelId?: string;
message?: string;
};
@Injectable()
export class MessagingMonitoringService {
constructor(private readonly auditService: AuditService) {}
public async track({
eventName,
workspaceId,
userId,
connectedAccountId,
messageChannelId,
message,
}: MessagingMonitoringTrackInput): Promise<void> {
const _eventName = eventName;
const _workspaceId = workspaceId;
const _userId = userId;
const _connectedAccountId = connectedAccountId;
const _messageChannelId = messageChannelId;
const _message = message;
// TODO: replace once we have Prometheus
/*
await this.auditService
.createContext({
userId,
workspaceId,
})
.track(MONITORING_EVENT, {
eventName: `messaging.${eventName}`,
connectedAccountId,
messageChannelId,
message,
}); */
}
}

View File

@ -1,39 +0,0 @@
import { Injectable } from '@nestjs/common';
import { AnalyticsService } from 'src/engine/core-modules/analytics/services/analytics.service';
import { MONITORING_EVENT } from 'src/engine/core-modules/analytics/utils/events/track/monitoring/monitoring';
type MessagingTelemetryTrackInput = {
eventName: string;
workspaceId?: string;
userId?: string;
connectedAccountId?: string;
messageChannelId?: string;
message?: string;
};
@Injectable()
export class MessagingTelemetryService {
constructor(private readonly analyticsService: AnalyticsService) {}
public async track({
eventName,
workspaceId,
userId,
connectedAccountId,
messageChannelId,
message,
}: MessagingTelemetryTrackInput): Promise<void> {
await this.analyticsService
.createAnalyticsContext({
userId,
workspaceId,
})
.track(MONITORING_EVENT, {
eventName: `messaging.${eventName}`,
connectedAccountId,
messageChannelId,
message,
});
}
}

View File

@ -1,71 +0,0 @@
import { ObjectRecordEvent } from 'src/engine/core-modules/event-emitter/types/object-record-event.event';
import { Process } from 'src/engine/core-modules/message-queue/decorators/process.decorator';
import { Processor } from 'src/engine/core-modules/message-queue/decorators/processor.decorator';
import { MessageQueue } from 'src/engine/core-modules/message-queue/message-queue.constants';
import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator';
import { WorkspaceEventBatch } from 'src/engine/workspace-event-emitter/types/workspace-event.type';
import { AuditLogRepository } from 'src/modules/timeline/repositiories/audit-log.repository';
import { AuditLogWorkspaceEntity } from 'src/modules/timeline/standard-objects/audit-log.workspace-entity';
import { WorkspaceMemberRepository } from 'src/modules/workspace-member/repositories/workspace-member.repository';
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
import { AnalyticsService } from 'src/engine/core-modules/analytics/services/analytics.service';
import { OBJECT_RECORD_UPDATED_EVENT } from 'src/engine/core-modules/analytics/utils/events/track/object-record/object-record-updated';
import { OBJECT_RECORD_CREATED_EVENT } from 'src/engine/core-modules/analytics/utils/events/track/object-record/object-record-created';
import { OBJECT_RECORD_DELETED_EVENT } from 'src/engine/core-modules/analytics/utils/events/track/object-record/object-record-delete';
@Processor(MessageQueue.entityEventsToDbQueue)
export class CreateAuditLogFromInternalEvent {
constructor(
@InjectObjectMetadataRepository(WorkspaceMemberWorkspaceEntity)
private readonly workspaceMemberService: WorkspaceMemberRepository,
@InjectObjectMetadataRepository(AuditLogWorkspaceEntity)
private readonly auditLogRepository: AuditLogRepository,
private readonly analyticsService: AnalyticsService,
) {}
@Process(CreateAuditLogFromInternalEvent.name)
async handle(
workspaceEventBatch: WorkspaceEventBatch<ObjectRecordEvent>,
): Promise<void> {
for (const eventData of workspaceEventBatch.events) {
let workspaceMemberId: string | null = null;
if (eventData.userId) {
const workspaceMember = await this.workspaceMemberService.getByIdOrFail(
eventData.userId,
workspaceEventBatch.workspaceId,
);
workspaceMemberId = workspaceMember.id;
}
await this.auditLogRepository.insert(
workspaceEventBatch.name,
'diff' in eventData.properties
? {
// we remove "before" and "after" property for a cleaner/slimmer event payload
diff: eventData.properties.diff,
}
: eventData.properties,
workspaceMemberId,
workspaceEventBatch.name.split('.')[0],
eventData.objectMetadata.id,
eventData.recordId,
workspaceEventBatch.workspaceId,
);
const analytics = this.analyticsService.createAnalyticsContext({
workspaceId: workspaceEventBatch.workspaceId,
userId: eventData.userId,
});
if (workspaceEventBatch.name.endsWith('.updated')) {
analytics.track(OBJECT_RECORD_UPDATED_EVENT, eventData.properties);
} else if (workspaceEventBatch.name.endsWith('.created')) {
analytics.track(OBJECT_RECORD_CREATED_EVENT, eventData.properties);
} else if (workspaceEventBatch.name.endsWith('.deleted')) {
analytics.track(OBJECT_RECORD_DELETED_EVENT, eventData.properties);
}
}
}
}

View File

@ -1,25 +1,17 @@
import { Module } from '@nestjs/common';
import { AuditModule } from 'src/engine/core-modules/audit/audit.module';
import { ObjectMetadataRepositoryModule } from 'src/engine/object-metadata-repository/object-metadata-repository.module';
import { CreateAuditLogFromInternalEvent } from 'src/modules/timeline/jobs/create-audit-log-from-internal-event';
import { UpsertTimelineActivityFromInternalEvent } from 'src/modules/timeline/jobs/upsert-timeline-activity-from-internal-event.job';
import { AuditLogWorkspaceEntity } from 'src/modules/timeline/standard-objects/audit-log.workspace-entity';
import { TimelineActivityModule } from 'src/modules/timeline/timeline-activity.module';
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
import { AnalyticsModule } from 'src/engine/core-modules/analytics/analytics.module';
@Module({
imports: [
ObjectMetadataRepositoryModule.forFeature([
WorkspaceMemberWorkspaceEntity,
AuditLogWorkspaceEntity,
]),
ObjectMetadataRepositoryModule.forFeature([WorkspaceMemberWorkspaceEntity]),
TimelineActivityModule,
AnalyticsModule,
],
providers: [
CreateAuditLogFromInternalEvent,
UpsertTimelineActivityFromInternalEvent,
AuditModule,
],
providers: [UpsertTimelineActivityFromInternalEvent],
})
export class TimelineJobModule {}

View File

@ -1,38 +0,0 @@
import { Injectable } from '@nestjs/common';
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service';
@Injectable()
export class AuditLogRepository {
constructor(
private readonly workspaceDataSourceService: WorkspaceDataSourceService,
) {}
public async insert(
name: string,
properties: object | null,
workspaceMemberId: string | null,
objectName: string,
objectMetadataId: string,
recordId: string,
workspaceId: string,
): Promise<void> {
const dataSourceSchema =
this.workspaceDataSourceService.getSchemaName(workspaceId);
await this.workspaceDataSourceService.executeRawQuery(
`INSERT INTO ${dataSourceSchema}."auditLog"
("name", "properties", "workspaceMemberId", "objectName", "objectMetadataId", "recordId")
VALUES ($1, $2, $3, $4, $5, $6)`,
[
name,
properties,
workspaceMemberId,
objectName,
objectMetadataId,
recordId,
],
workspaceId,
);
}
}

View File

@ -1,103 +0,0 @@
import { msg } from '@lingui/core/macro';
import { FieldMetadataType } from 'twenty-shared/types';
import { RelationType } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-type.interface';
import { Relation } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/relation.interface';
import { RelationOnDeleteAction } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-on-delete-action.interface';
import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity';
import { WorkspaceEntity } from 'src/engine/twenty-orm/decorators/workspace-entity.decorator';
import { WorkspaceField } from 'src/engine/twenty-orm/decorators/workspace-field.decorator';
import { WorkspaceIsNullable } from 'src/engine/twenty-orm/decorators/workspace-is-nullable.decorator';
import { WorkspaceIsSystem } from 'src/engine/twenty-orm/decorators/workspace-is-system.decorator';
import { WorkspaceJoinColumn } from 'src/engine/twenty-orm/decorators/workspace-join-column.decorator';
import { WorkspaceRelation } from 'src/engine/twenty-orm/decorators/workspace-relation.decorator';
import { AUDIT_LOGS_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
import { STANDARD_OBJECT_ICONS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-icons';
import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids';
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
@WorkspaceEntity({
standardId: STANDARD_OBJECT_IDS.auditLog,
namePlural: 'auditLogs',
labelSingular: msg`Audit Log`,
labelPlural: msg`Audit Logs`,
description: msg`An audit log of actions performed in the system`,
icon: STANDARD_OBJECT_ICONS.auditLog,
labelIdentifierStandardId: AUDIT_LOGS_STANDARD_FIELD_IDS.name,
})
@WorkspaceIsSystem()
export class AuditLogWorkspaceEntity extends BaseWorkspaceEntity {
@WorkspaceField({
standardId: AUDIT_LOGS_STANDARD_FIELD_IDS.name,
type: FieldMetadataType.TEXT,
label: msg`Event name`,
description: msg`Event name/type`,
icon: 'IconAbc',
})
name: string;
@WorkspaceField({
standardId: AUDIT_LOGS_STANDARD_FIELD_IDS.properties,
type: FieldMetadataType.RAW_JSON,
label: msg`Event details`,
description: msg`Json value for event details`,
icon: 'IconListDetails',
})
@WorkspaceIsNullable()
properties: JSON | null;
@WorkspaceField({
standardId: AUDIT_LOGS_STANDARD_FIELD_IDS.context,
type: FieldMetadataType.RAW_JSON,
label: msg`Event context`,
description: msg`Json object to provide context (user, device, workspace, etc.)`,
icon: 'IconListDetails',
})
@WorkspaceIsNullable()
context: JSON | null;
@WorkspaceField({
standardId: AUDIT_LOGS_STANDARD_FIELD_IDS.objectName,
type: FieldMetadataType.TEXT,
label: msg`Object name`,
description: msg`Object name`,
icon: 'IconAbc',
})
objectName: string;
@WorkspaceField({
standardId: AUDIT_LOGS_STANDARD_FIELD_IDS.objectMetadataId,
type: FieldMetadataType.TEXT,
label: msg`Object metadata id`,
description: msg`Object metadata id`,
icon: 'IconAbc',
})
objectMetadataId: string;
@WorkspaceField({
standardId: AUDIT_LOGS_STANDARD_FIELD_IDS.recordId,
type: FieldMetadataType.UUID,
label: msg`Record id`,
description: msg`Record id`,
icon: 'IconAbc',
})
@WorkspaceIsNullable()
recordId: string | null;
@WorkspaceRelation({
standardId: AUDIT_LOGS_STANDARD_FIELD_IDS.workspaceMember,
type: RelationType.MANY_TO_ONE,
label: msg`Workspace Member`,
description: msg`Event workspace member`,
icon: 'IconCircleUser',
inverseSideTarget: () => WorkspaceMemberWorkspaceEntity,
inverseSideFieldKey: 'auditLogs',
onDelete: RelationOnDeleteAction.SET_NULL,
})
@WorkspaceIsNullable()
workspaceMember: Relation<WorkspaceMemberWorkspaceEntity> | null;
@WorkspaceJoinColumn('workspaceMember')
workspaceMemberId: string | null;
}

View File

@ -1,92 +0,0 @@
import { msg } from '@lingui/core/macro';
import { FieldMetadataType } from 'twenty-shared/types';
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity';
import { WorkspaceEntity } from 'src/engine/twenty-orm/decorators/workspace-entity.decorator';
import { WorkspaceField } from 'src/engine/twenty-orm/decorators/workspace-field.decorator';
import { WorkspaceGate } from 'src/engine/twenty-orm/decorators/workspace-gate.decorator';
import { WorkspaceIsNullable } from 'src/engine/twenty-orm/decorators/workspace-is-nullable.decorator';
import { WorkspaceIsSystem } from 'src/engine/twenty-orm/decorators/workspace-is-system.decorator';
import { BEHAVIORAL_EVENT_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
import { STANDARD_OBJECT_ICONS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-icons';
import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids';
@WorkspaceEntity({
standardId: STANDARD_OBJECT_IDS.behavioralEvent,
namePlural: 'behavioralEvents',
labelSingular: msg`Behavioral Event`,
labelPlural: msg`Behavioral Events`,
description: msg`An event related to user behavior`,
icon: STANDARD_OBJECT_ICONS.behavioralEvent,
})
@WorkspaceIsSystem()
@WorkspaceGate({
featureFlag: FeatureFlagKey.IsEventObjectEnabled,
})
export class BehavioralEventWorkspaceEntity extends BaseWorkspaceEntity {
/**
*
* Common in Segment, Rudderstack, etc.
* = Track, Screen, Page...
* But doesn't feel that useful.
* Let's try living without it.
*
@WorkspaceField({
standardId: behavioralEventStandardFieldIds.type,
type: FieldMetadataType.TEXT,
label: msg`Event type`,
description: msg`Event type`,
icon: 'IconAbc',
})
type: string;
*/
@WorkspaceField({
standardId: BEHAVIORAL_EVENT_STANDARD_FIELD_IDS.name,
type: FieldMetadataType.TEXT,
label: msg`Event name`,
description: msg`Event name`,
icon: 'IconAbc',
})
name: string;
@WorkspaceField({
standardId: BEHAVIORAL_EVENT_STANDARD_FIELD_IDS.properties,
type: FieldMetadataType.RAW_JSON,
label: msg`Event details`,
description: msg`Json value for event details`,
icon: 'IconListDetails',
})
@WorkspaceIsNullable()
properties: JSON | null;
@WorkspaceField({
standardId: BEHAVIORAL_EVENT_STANDARD_FIELD_IDS.context,
type: FieldMetadataType.RAW_JSON,
label: msg`Event context`,
description: msg`Json object to provide context (user, device, workspace, etc.)`,
icon: 'IconListDetails',
})
@WorkspaceIsNullable()
context: JSON | null;
@WorkspaceField({
standardId: BEHAVIORAL_EVENT_STANDARD_FIELD_IDS.objectName,
type: FieldMetadataType.TEXT,
label: msg`Object name`,
description: msg`If the event is related to a particular object`,
icon: 'IconAbc',
})
objectName: string;
@WorkspaceField({
standardId: BEHAVIORAL_EVENT_STANDARD_FIELD_IDS.recordId,
type: FieldMetadataType.UUID,
label: msg`Object id`,
description: msg`Event name/type`,
icon: 'IconAbc',
})
@WorkspaceIsNullable()
recordId: string | null;
}

View File

@ -7,11 +7,11 @@ import { Relation } from 'typeorm';
import { RelationType } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-type.interface';
import { AGGREGATE_OPERATIONS } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { RelationOnDeleteAction } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity';
import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity';
import { WorkspaceEntity } from 'src/engine/twenty-orm/decorators/workspace-entity.decorator';
import { WorkspaceField } from 'src/engine/twenty-orm/decorators/workspace-field.decorator';
import { WorkspaceIndex } from 'src/engine/twenty-orm/decorators/workspace-index.decorator';
import { WorkspaceIsNotAuditLogged } from 'src/engine/twenty-orm/decorators/workspace-is-not-audit-logged.decorator';
import { WorkspaceIsNullable } from 'src/engine/twenty-orm/decorators/workspace-is-nullable.decorator';
import { WorkspaceIsSystem } from 'src/engine/twenty-orm/decorators/workspace-is-system.decorator';
import { WorkspaceJoinColumn } from 'src/engine/twenty-orm/decorators/workspace-join-column.decorator';
@ -20,7 +20,6 @@ import { VIEW_FIELD_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/work
import { STANDARD_OBJECT_ICONS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-icons';
import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids';
import { ViewWorkspaceEntity } from 'src/modules/view/standard-objects/view.workspace-entity';
import { RelationOnDeleteAction } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity';
registerEnumType(AGGREGATE_OPERATIONS, {
name: 'AggregateOperations',
@ -34,7 +33,6 @@ registerEnumType(AGGREGATE_OPERATIONS, {
description: msg`(System) View Fields`,
icon: STANDARD_OBJECT_ICONS.viewField,
})
@WorkspaceIsNotAuditLogged()
@WorkspaceIsSystem()
@WorkspaceIndex(['fieldMetadataId', 'viewId'], {
isUnique: true,

View File

@ -4,10 +4,10 @@ import { Relation } from 'typeorm';
import { RelationType } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-type.interface';
import { RelationOnDeleteAction } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity';
import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity';
import { WorkspaceEntity } from 'src/engine/twenty-orm/decorators/workspace-entity.decorator';
import { WorkspaceField } from 'src/engine/twenty-orm/decorators/workspace-field.decorator';
import { WorkspaceIsNotAuditLogged } from 'src/engine/twenty-orm/decorators/workspace-is-not-audit-logged.decorator';
import { WorkspaceIsNullable } from 'src/engine/twenty-orm/decorators/workspace-is-nullable.decorator';
import { WorkspaceIsSystem } from 'src/engine/twenty-orm/decorators/workspace-is-system.decorator';
import { WorkspaceJoinColumn } from 'src/engine/twenty-orm/decorators/workspace-join-column.decorator';
@ -15,7 +15,6 @@ import { WorkspaceRelation } from 'src/engine/twenty-orm/decorators/workspace-re
import { VIEW_FILTER_GROUP_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids';
import { ViewWorkspaceEntity } from 'src/modules/view/standard-objects/view.workspace-entity';
import { RelationOnDeleteAction } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity';
export enum ViewFilterGroupLogicalOperator {
AND = 'AND',
@ -31,7 +30,6 @@ export enum ViewFilterGroupLogicalOperator {
description: msg`(System) View Filter Groups`,
icon: 'IconFilterBolt',
})
@WorkspaceIsNotAuditLogged()
@WorkspaceIsSystem()
export class ViewFilterGroupWorkspaceEntity extends BaseWorkspaceEntity {
@WorkspaceRelation({

View File

@ -4,10 +4,10 @@ import { FieldMetadataType } from 'twenty-shared/types';
import { RelationType } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-type.interface';
import { Relation } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/relation.interface';
import { RelationOnDeleteAction } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity';
import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity';
import { WorkspaceEntity } from 'src/engine/twenty-orm/decorators/workspace-entity.decorator';
import { WorkspaceField } from 'src/engine/twenty-orm/decorators/workspace-field.decorator';
import { WorkspaceIsNotAuditLogged } from 'src/engine/twenty-orm/decorators/workspace-is-not-audit-logged.decorator';
import { WorkspaceIsNullable } from 'src/engine/twenty-orm/decorators/workspace-is-nullable.decorator';
import { WorkspaceIsSystem } from 'src/engine/twenty-orm/decorators/workspace-is-system.decorator';
import { WorkspaceJoinColumn } from 'src/engine/twenty-orm/decorators/workspace-join-column.decorator';
@ -16,7 +16,6 @@ import { VIEW_FILTER_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/wor
import { STANDARD_OBJECT_ICONS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-icons';
import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids';
import { ViewWorkspaceEntity } from 'src/modules/view/standard-objects/view.workspace-entity';
import { RelationOnDeleteAction } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity';
@WorkspaceEntity({
standardId: STANDARD_OBJECT_IDS.viewFilter,
@ -26,7 +25,6 @@ import { RelationOnDeleteAction } from 'src/engine/metadata-modules/relation-met
description: msg`(System) View Filters`,
icon: STANDARD_OBJECT_ICONS.viewFilter,
})
@WorkspaceIsNotAuditLogged()
@WorkspaceIsSystem()
export class ViewFilterWorkspaceEntity extends BaseWorkspaceEntity {
@WorkspaceField({

View File

@ -3,10 +3,10 @@ import { FieldMetadataType } from 'twenty-shared/types';
import { RelationType } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-type.interface';
import { RelationOnDeleteAction } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity';
import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity';
import { WorkspaceEntity } from 'src/engine/twenty-orm/decorators/workspace-entity.decorator';
import { WorkspaceField } from 'src/engine/twenty-orm/decorators/workspace-field.decorator';
import { WorkspaceIsNotAuditLogged } from 'src/engine/twenty-orm/decorators/workspace-is-not-audit-logged.decorator';
import { WorkspaceIsNullable } from 'src/engine/twenty-orm/decorators/workspace-is-nullable.decorator';
import { WorkspaceIsSystem } from 'src/engine/twenty-orm/decorators/workspace-is-system.decorator';
import { WorkspaceJoinColumn } from 'src/engine/twenty-orm/decorators/workspace-join-column.decorator';
@ -15,7 +15,6 @@ import { VIEW_GROUP_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/work
import { STANDARD_OBJECT_ICONS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-icons';
import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids';
import { ViewWorkspaceEntity } from 'src/modules/view/standard-objects/view.workspace-entity';
import { RelationOnDeleteAction } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity';
@WorkspaceEntity({
standardId: STANDARD_OBJECT_IDS.viewGroup,
@ -25,7 +24,6 @@ import { RelationOnDeleteAction } from 'src/engine/metadata-modules/relation-met
description: msg`(System) View Groups`,
icon: STANDARD_OBJECT_ICONS.viewGroup,
})
@WorkspaceIsNotAuditLogged()
@WorkspaceIsSystem()
export class ViewGroupWorkspaceEntity extends BaseWorkspaceEntity {
@WorkspaceField({

View File

@ -4,11 +4,11 @@ import { FieldMetadataType } from 'twenty-shared/types';
import { RelationType } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-type.interface';
import { Relation } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/relation.interface';
import { RelationOnDeleteAction } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity';
import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity';
import { WorkspaceEntity } from 'src/engine/twenty-orm/decorators/workspace-entity.decorator';
import { WorkspaceField } from 'src/engine/twenty-orm/decorators/workspace-field.decorator';
import { WorkspaceIndex } from 'src/engine/twenty-orm/decorators/workspace-index.decorator';
import { WorkspaceIsNotAuditLogged } from 'src/engine/twenty-orm/decorators/workspace-is-not-audit-logged.decorator';
import { WorkspaceIsNullable } from 'src/engine/twenty-orm/decorators/workspace-is-nullable.decorator';
import { WorkspaceIsSystem } from 'src/engine/twenty-orm/decorators/workspace-is-system.decorator';
import { WorkspaceJoinColumn } from 'src/engine/twenty-orm/decorators/workspace-join-column.decorator';
@ -17,7 +17,6 @@ import { VIEW_SORT_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/works
import { STANDARD_OBJECT_ICONS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-icons';
import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids';
import { ViewWorkspaceEntity } from 'src/modules/view/standard-objects/view.workspace-entity';
import { RelationOnDeleteAction } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity';
@WorkspaceEntity({
standardId: STANDARD_OBJECT_IDS.viewSort,
@ -27,7 +26,6 @@ import { RelationOnDeleteAction } from 'src/engine/metadata-modules/relation-met
description: msg`(System) View Sorts`,
icon: STANDARD_OBJECT_ICONS.viewSort,
})
@WorkspaceIsNotAuditLogged()
@WorkspaceIsSystem()
@WorkspaceIndex(['fieldMetadataId', 'viewId'], {
isUnique: true,

View File

@ -11,7 +11,6 @@ import { AGGREGATE_OPERATIONS } from 'src/engine/api/graphql/graphql-query-runne
import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity';
import { WorkspaceEntity } from 'src/engine/twenty-orm/decorators/workspace-entity.decorator';
import { WorkspaceField } from 'src/engine/twenty-orm/decorators/workspace-field.decorator';
import { WorkspaceIsNotAuditLogged } from 'src/engine/twenty-orm/decorators/workspace-is-not-audit-logged.decorator';
import { WorkspaceIsNullable } from 'src/engine/twenty-orm/decorators/workspace-is-nullable.decorator';
import { WorkspaceIsSystem } from 'src/engine/twenty-orm/decorators/workspace-is-system.decorator';
import { WorkspaceRelation } from 'src/engine/twenty-orm/decorators/workspace-relation.decorator';
@ -43,7 +42,6 @@ registerEnumType(ViewOpenRecordInType, {
icon: STANDARD_OBJECT_ICONS.view,
labelIdentifierStandardId: VIEW_STANDARD_FIELD_IDS.name,
})
@WorkspaceIsNotAuditLogged()
@WorkspaceIsSystem()
export class ViewWorkspaceEntity extends BaseWorkspaceEntity {
@WorkspaceField({

View File

@ -3,11 +3,11 @@ import { Logger } from '@nestjs/common';
import crypto from 'crypto';
import { AnalyticsService } from 'src/engine/core-modules/analytics/services/analytics.service';
import { AuditService } from 'src/engine/core-modules/audit/services/audit.service';
import { WEBHOOK_RESPONSE_EVENT } from 'src/engine/core-modules/audit/utils/events/track/webhook/webhook-response';
import { Process } from 'src/engine/core-modules/message-queue/decorators/process.decorator';
import { Processor } from 'src/engine/core-modules/message-queue/decorators/processor.decorator';
import { MessageQueue } from 'src/engine/core-modules/message-queue/message-queue.constants';
import { WEBHOOK_RESPONSE_EVENT } from 'src/engine/core-modules/analytics/utils/events/track/webhook/webhook-response';
export type CallWebhookJobData = {
targetUrl: string;
@ -26,7 +26,7 @@ export class CallWebhookJob {
private readonly logger = new Logger(CallWebhookJob.name);
constructor(
private readonly httpService: HttpService,
private readonly analyticsService: AnalyticsService,
private readonly auditService: AuditService,
) {}
private generateSignature(
@ -47,7 +47,7 @@ export class CallWebhookJob {
webhookId: data.webhookId,
eventName: data.eventName,
};
const analytics = this.analyticsService.createAnalyticsContext({
const analytics = this.auditService.createContext({
workspaceId: data.workspaceId,
});

View File

@ -1,12 +1,12 @@
import { Module } from '@nestjs/common';
import { HttpModule } from '@nestjs/axios';
import { Module } from '@nestjs/common';
import { AuditModule } from 'src/engine/core-modules/audit/audit.module';
import { CallWebhookJobsJob } from 'src/modules/webhook/jobs/call-webhook-jobs.job';
import { CallWebhookJob } from 'src/modules/webhook/jobs/call-webhook.job';
import { AnalyticsModule } from 'src/engine/core-modules/analytics/analytics.module';
@Module({
imports: [HttpModule, AnalyticsModule],
imports: [HttpModule, AuditModule],
providers: [CallWebhookJobsJob, CallWebhookJob],
})
export class WebhookJobModule {}

View File

@ -5,7 +5,6 @@ import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity
import { WorkspaceEntity } from 'src/engine/twenty-orm/decorators/workspace-entity.decorator';
import { WorkspaceField } from 'src/engine/twenty-orm/decorators/workspace-field.decorator';
import { WorkspaceIsDeprecated } from 'src/engine/twenty-orm/decorators/workspace-is-deprecated.decorator';
import { WorkspaceIsNotAuditLogged } from 'src/engine/twenty-orm/decorators/workspace-is-not-audit-logged.decorator';
import { WorkspaceIsNullable } from 'src/engine/twenty-orm/decorators/workspace-is-nullable.decorator';
import { WorkspaceIsSystem } from 'src/engine/twenty-orm/decorators/workspace-is-system.decorator';
import { WEBHOOK_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
@ -21,7 +20,6 @@ import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync
icon: STANDARD_OBJECT_ICONS.webhook,
labelIdentifierStandardId: WEBHOOK_STANDARD_FIELD_IDS.targetUrl,
})
@WorkspaceIsNotAuditLogged()
@WorkspaceIsSystem()
export class WebhookWorkspaceEntity extends BaseWorkspaceEntity {
@WorkspaceField({

View File

@ -9,6 +9,7 @@ import { ActorMetadata } from 'src/engine/metadata-modules/field-metadata/compos
import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity';
import { WorkspaceEntity } from 'src/engine/twenty-orm/decorators/workspace-entity.decorator';
import { WorkspaceField } from 'src/engine/twenty-orm/decorators/workspace-field.decorator';
import { WorkspaceIsNotAuditLogged } from 'src/engine/twenty-orm/decorators/workspace-is-not-audit-logged.decorator';
import { WorkspaceIsNullable } from 'src/engine/twenty-orm/decorators/workspace-is-nullable.decorator';
import { WorkspaceIsSystem } from 'src/engine/twenty-orm/decorators/workspace-is-system.decorator';
import { WorkspaceJoinColumn } from 'src/engine/twenty-orm/decorators/workspace-join-column.decorator';
@ -54,6 +55,7 @@ export type WorkflowRunOutput = {
labelIdentifierStandardId: WORKFLOW_RUN_STANDARD_FIELD_IDS.name,
icon: STANDARD_OBJECT_ICONS.workflowRun,
})
@WorkspaceIsNotAuditLogged()
export class WorkflowRunWorkspaceEntity extends BaseWorkspaceEntity {
@WorkspaceField({
standardId: WORKFLOW_RUN_STANDARD_FIELD_IDS.name,

View File

@ -15,7 +15,6 @@ import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity
import { WorkspaceEntity } from 'src/engine/twenty-orm/decorators/workspace-entity.decorator';
import { WorkspaceFieldIndex } from 'src/engine/twenty-orm/decorators/workspace-field-index.decorator';
import { WorkspaceField } from 'src/engine/twenty-orm/decorators/workspace-field.decorator';
import { WorkspaceIsNotAuditLogged } from 'src/engine/twenty-orm/decorators/workspace-is-not-audit-logged.decorator';
import { WorkspaceIsNullable } from 'src/engine/twenty-orm/decorators/workspace-is-nullable.decorator';
import { WorkspaceIsSearchable } from 'src/engine/twenty-orm/decorators/workspace-is-searchable.decorator';
import { WorkspaceIsSystem } from 'src/engine/twenty-orm/decorators/workspace-is-system.decorator';
@ -35,7 +34,6 @@ import { ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/s
import { FavoriteWorkspaceEntity } from 'src/modules/favorite/standard-objects/favorite.workspace-entity';
import { MessageParticipantWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-participant.workspace-entity';
import { TaskWorkspaceEntity } from 'src/modules/task/standard-objects/task.workspace-entity';
import { AuditLogWorkspaceEntity } from 'src/modules/timeline/standard-objects/audit-log.workspace-entity';
import { TimelineActivityWorkspaceEntity } from 'src/modules/timeline/standard-objects/timeline-activity.workspace-entity';
export enum WorkspaceMemberDateFormatEnum {
@ -81,7 +79,6 @@ export const SEARCH_FIELDS_FOR_WORKSPACE_MEMBER: FieldTypeAndNameMetadata[] = [
imageIdentifierStandardId: WORKSPACE_MEMBER_STANDARD_FIELD_IDS.avatarUrl,
})
@WorkspaceIsSystem()
@WorkspaceIsNotAuditLogged()
@WorkspaceIsSearchable()
export class WorkspaceMemberWorkspaceEntity extends BaseWorkspaceEntity {
@WorkspaceField({
@ -347,19 +344,6 @@ export class WorkspaceMemberWorkspaceEntity extends BaseWorkspaceEntity {
@WorkspaceIsSystem()
timelineActivities: Relation<TimelineActivityWorkspaceEntity[]>;
@WorkspaceRelation({
standardId: WORKSPACE_MEMBER_STANDARD_FIELD_IDS.auditLogs,
type: RelationType.ONE_TO_MANY,
label: msg`Audit Logs`,
description: msg`Audit Logs linked to the workspace member`,
icon: 'IconTimelineEvent',
inverseSideTarget: () => AuditLogWorkspaceEntity,
onDelete: RelationOnDeleteAction.SET_NULL,
})
@WorkspaceIsNullable()
@WorkspaceIsSystem()
auditLogs: Relation<AuditLogWorkspaceEntity[]>;
@WorkspaceField({
standardId: WORKSPACE_MEMBER_STANDARD_FIELD_IDS.searchVector,
type: FieldMetadataType.TS_VECTOR,