@solidxai/core 0.1.13-beta.11 → 0.1.13-beta.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +16 -0
- package/CHANGELOG.md +1128 -0
- package/CLAUDE.md +26 -0
- package/dist/commands/run-tests.command.d.ts +2 -0
- package/dist/commands/run-tests.command.d.ts.map +1 -1
- package/dist/commands/run-tests.command.js +20 -3
- package/dist/commands/run-tests.command.js.map +1 -1
- package/dist/seeders/seed-data/solid-core-metadata.json +1 -1
- package/dist/services/chatter-message.service.d.ts +4 -1
- package/dist/services/chatter-message.service.d.ts.map +1 -1
- package/dist/services/chatter-message.service.js +4 -1
- package/dist/services/chatter-message.service.js.map +1 -1
- package/dist/services/crud-helper.service.d.ts +1 -2
- package/dist/services/crud-helper.service.d.ts.map +1 -1
- package/dist/services/crud-helper.service.js +2 -16
- package/dist/services/crud-helper.service.js.map +1 -1
- package/dist/services/crud.service.d.ts.map +1 -1
- package/dist/services/crud.service.js +1 -1
- package/dist/services/crud.service.js.map +1 -1
- package/dist/services/draft-publish-helper.service.d.ts +1 -0
- package/dist/services/draft-publish-helper.service.d.ts.map +1 -1
- package/dist/services/draft-publish-helper.service.js +38 -4
- package/dist/services/draft-publish-helper.service.js.map +1 -1
- package/dist/services/settings/default-settings-provider.service.d.ts +62 -6
- package/dist/services/settings/default-settings-provider.service.d.ts.map +1 -1
- package/dist/services/settings/default-settings-provider.service.js +34 -3
- package/dist/services/settings/default-settings-provider.service.js.map +1 -1
- package/dist/testing/reporter/console-reporter.d.ts +3 -0
- package/dist/testing/reporter/console-reporter.d.ts.map +1 -1
- package/dist/testing/reporter/console-reporter.js +2 -0
- package/dist/testing/reporter/console-reporter.js.map +1 -1
- package/dist/testing/reporter/progress-reporter.d.ts +64 -0
- package/dist/testing/reporter/progress-reporter.d.ts.map +1 -0
- package/dist/testing/reporter/progress-reporter.js +224 -0
- package/dist/testing/reporter/progress-reporter.js.map +1 -0
- package/dist/testing/reporter/reporter.types.d.ts +3 -0
- package/dist/testing/reporter/reporter.types.d.ts.map +1 -1
- package/dist/testing/reporter/reporter.types.js.map +1 -1
- package/dist/testing/runner/run-from-metadata.d.ts.map +1 -1
- package/dist/testing/runner/run-from-metadata.js +1 -0
- package/dist/testing/runner/run-from-metadata.js.map +1 -1
- package/dist/theme/theme-registry.d.ts +14 -0
- package/dist/theme/theme-registry.d.ts.map +1 -0
- package/dist/theme/theme-registry.js +147 -0
- package/dist/theme/theme-registry.js.map +1 -0
- package/package.json +1 -1
- package/src/commands/run-tests.command.ts +17 -3
- package/src/seeders/seed-data/solid-core-metadata.json +1 -1
- package/src/services/1.js +6 -0
- package/src/services/chatter-message.service.ts +22 -1
- package/src/services/crud-helper.service.ts +19 -16
- package/src/services/crud.service.ts +2 -1
- package/src/services/draft-publish-helper.service.ts +56 -4
- package/src/services/settings/default-settings-provider.service.ts +34 -3
- package/src/testing/README.md +2 -1
- package/src/testing/reporter/console-reporter.ts +4 -0
- package/src/testing/reporter/progress-reporter.ts +251 -0
- package/src/testing/reporter/reporter.types.ts +3 -0
- package/src/testing/runner/run-from-metadata.ts +1 -0
- package/src/theme/theme-registry.ts +181 -0
- package/dist-tests/api/authenticate.spec.js +0 -119
- package/dist-tests/api/authenticate.spec.js.map +0 -1
- package/dist-tests/api/crud-service.findOne.cityMaster.spec.js +0 -97
- package/dist-tests/api/crud-service.findOne.cityMaster.spec.js.map +0 -1
- package/dist-tests/api/ping.spec.js +0 -21
- package/dist-tests/api/ping.spec.js.map +0 -1
- package/dist-tests/helpers/auth.js +0 -41
- package/dist-tests/helpers/auth.js.map +0 -1
- package/dist-tests/helpers/env.js +0 -11
- package/dist-tests/helpers/env.js.map +0 -1
- package/docs/agent-builder/notebook-lm-prompt-for-agent-builder.md +0 -136
- package/docs/agent-builder/team-ready-note-agent-builder.md +0 -305
- package/docs/agent-hub-grooming.md +0 -301
- package/docs/dashboards/AGENTIC_DASHBOARD_IMPLEMENTATION_PLAN.md +0 -438
- package/docs/dashboards/dashboard-curl-smoke-tests.txt +0 -146
- package/docs/dashboards/delete-legacy-dashboard-metadata.sql +0 -172
- package/docs/datasource-introspection-ddl-analysis.md +0 -326
- package/docs/datasource-introspection-implementation-plan.md +0 -306
- package/docs/grouping-enhancements.md +0 -89
- package/docs/java-spring/README.md +0 -3
- package/docs/java-spring/solid-core-module-deep-dive-report.md +0 -1317
- package/docs/module-package-import-handoff.md +0 -691
- package/docs/seed-changes.md +0 -65
- package/docs/test-data-workflow.md +0 -200
- package/docs/type-declaration-import-issue.md +0 -24
- package/docs/workflow/business-automation-example-notes.md +0 -309
- package/docs/workflow/control-flow-node-addition-sop.md +0 -324
- package/docs/workflow/data-engineering-pipeline-example-notes.md +0 -330
- package/docs/workflow/foreach-example-notes.md +0 -187
- package/docs/workflow/hello-world-example-notes.md +0 -271
- package/docs/workflow/kestra-concepts-plugins-blueprints.md +0 -315
- package/docs/workflow/loop-until-example-notes.md +0 -198
- package/docs/workflow/microservices-and-apis-example-notes.md +0 -264
- package/docs/workflow/samples.md +0 -25
- package/docs/workflow/what-is-kestra.md +0 -79
- package/docs/workflow/workflow-core-module-handoff-summary.md +0 -191
- package/docs/workflow/workflow-module-brd.md +0 -185
- package/docs/workflow/workflow-module-domain-model.md +0 -252
- package/docs/workflow/workflow-module-metadata-dsl.md +0 -302
- package/docs/workflow/workflow-module-technical-spec.md +0 -293
- package/docs/workflow/workflow-node-type-contracts.md +0 -635
- package/docs/workflow/workflow-node-ui-metadata-contract.md +0 -1262
- package/docs/workflow/workflow-solidx-model-field-spec.md +0 -284
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chatter-message.service.js","sourceRoot":"","sources":["../../src/services/chatter-message.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { LocalDateTimeTransformer, serializeDate } from 'src/transformers/typeorm/local-date-time-transformer';\nimport { BadRequestException, ForbiddenException, forwardRef, Inject, Injectable, NotFoundException } from '@nestjs/common';\nimport { ModuleRef } from \"@nestjs/core\";\nimport { InjectEntityManager } from '@nestjs/typeorm';\nimport { Brackets, EntityManager, EntityMetadata, In } from 'typeorm';\n\nimport { classify } from '@angular-devkit/core/src/utils/strings';\nimport { CHATTER_MESSAGE_STATUS, CHATTER_MESSAGE_SUBTYPE, CHATTER_MESSAGE_TYPE, CHATTER_MESSAGE_USER_FIELDS } from 'src/constants/chatter-message.constants';\nimport { isDangerousMediaFile } from 'src/constants/media-file-types';\nimport { ERROR_MESSAGES } from 'src/constants/error-messages';\nimport { PostChatterMessageDto } from 'src/dtos/post-chatter-message.dto';\nimport { UpdateChatterNoteMessageDto } from 'src/dtos/update-chatter-note-message.dto';\nimport { ModelMetadataHelperService } from 'src/helpers/model-metadata-helper.service';\nimport { lowerFirst } from 'src/helpers/string.helper';\nimport { ChatterMentionNotificationPayload } from 'src/interfaces/chatter-mention-notification.interface';\nimport { ChatterMessageDetailsRepository } from 'src/repository/chatter-message-details.repository';\nimport { ChatterMessageRepository } from 'src/repository/chatter-message.repository';\nimport { FieldMetadataRepository } from 'src/repository/field-metadata.repository';\nimport { MediaRepository } from 'src/repository/media.repository';\nimport { ModelMetadataRepository } from 'src/repository/model-metadata.repository';\nimport { CRUDService } from 'src/services/crud.service';\nimport { BasicFilterDto } from '../dtos/basic-filters.dto';\nimport { MediaStorageProviderType } from '../dtos/create-media-storage-provider-metadata.dto';\nimport { ChatterMessageDetails } from '../entities/chatter-message-details.entity';\nimport { ChatterMessage } from '../entities/chatter-message.entity';\nimport { User } from '../entities/user.entity';\nimport { getMediaStorageProvider } from './mediaStorageProviders';\nimport { RequestContextService } from './request-context.service';\nimport { Logger } from '@nestjs/common';\nimport { SolidIntrospectService } from './solid-introspect.service';\nimport { PublisherFactory } from './queues/publisher-factory.service';\n\ninterface ChatterMention {\n username: string;\n display_name?: string;\n displayName?: string;\n id?: string | number;\n}\n\n@Injectable()\nexport class ChatterMessageService extends CRUDService<ChatterMessage> {\n private readonly _logger = new Logger(ChatterMessageService.name);\n\n constructor(\n @InjectEntityManager()\n readonly entityManager: EntityManager,\n // @InjectRepository(ChatterMessage, 'default')\n readonly repo: ChatterMessageRepository,\n // @InjectRepository(ChatterMessageDetailsRepository, 'default')\n readonly chatterMessageDetailsRepo: ChatterMessageDetailsRepository,\n readonly mediaRepository: MediaRepository,\n // @InjectRepository(FieldMetadata, 'default')\n // readonly fieldMetadataRepo: Repository<FieldMetadata>,\n readonly fieldMetadataRepo: FieldMetadataRepository,\n readonly moduleRef: ModuleRef,\n // @InjectRepository(ModelMetadata)\n // private readonly modelMetadataRepo: Repository<ModelMetadata>,\n @Inject(forwardRef(() => ModelMetadataRepository))\n private readonly modelMetadataRepo: ModelMetadataRepository,\n readonly requestContextService: RequestContextService,\n private readonly modelMetadataHelperService: ModelMetadataHelperService,\n private readonly publisherFactory: PublisherFactory<ChatterMentionNotificationPayload>,\n ) {\n super(entityManager, repo, 'chatterMessage', 'solid-core', moduleRef);\n }\n\n private getCoModelService(coModelName: string): CRUDService<any> {\n const introspectService = this.moduleRef.get(SolidIntrospectService, { strict: false });\n const modelSingularName = lowerFirst(coModelName);\n const coModelService = introspectService?.getCRUDService(modelSingularName);\n if (!coModelService) {\n throw new BadRequestException(ERROR_MESSAGES.MODEL_SERVICE_NOT_FOUND(modelSingularName));\n }\n return coModelService;\n }\n\n private async assertRecordAccess(coModelName: string, coModelEntityId: number) {\n const activeUser = this.requestContextService.getActiveUser();\n if (!activeUser) {\n throw new ForbiddenException(ERROR_MESSAGES.FORBIDDEN);\n }\n\n const coModelService = this.getCoModelService(coModelName);\n await coModelService.findOne(coModelEntityId, {}, { activeUser });\n }\n\n private resolveMessageUserId(userId?: number | null): number | null {\n if (userId) {\n return userId;\n }\n\n return this.requestContextService.getActiveUser()?.sub ?? null;\n }\n\n private resolveMessageUser(userId?: number | null) {\n const resolvedUserId = this.resolveMessageUserId(userId);\n return resolvedUserId ? ({ id: resolvedUserId } as any) : null;\n }\n\n private stampMessageAuditFields(chatterMessage: ChatterMessage, userId?: number | null) {\n const resolvedUserId = this.resolveMessageUserId(userId);\n chatterMessage.user = resolvedUserId ? ({ id: resolvedUserId } as any) : null;\n chatterMessage.createdBy = resolvedUserId;\n chatterMessage.updatedBy = resolvedUserId;\n }\n\n /**\n * Reduce a message's hydrated `user` relation to CHATTER_MESSAGE_USER_FIELDS.\n *\n * `getChatterMessages` restricts the columns in the query itself, which is preferable.\n * The generic CRUD paths below build their query from find-options and hand `populate`\n * straight to TypeORM, so they are trimmed after the fact instead. (`createdBy` /\n * `updatedBy` need nothing here - CRUDService.handlePopulateUserIdFields already selects\n * only USER_SUMMARY_FIELDS when a caller populates them.)\n */\n private trimMessageUser<M extends ChatterMessage>(message: M): M {\n if (message?.user) {\n message.user = this.toUserSummary(message.user) as User;\n }\n return message;\n }\n\n private trimMessageUsers(messages: ChatterMessage[] | undefined) {\n messages?.forEach(message => this.trimMessageUser(message));\n }\n\n /**\n * `GET /chatter-message?populate[]=user` would otherwise be a way around the column\n * allowlist applied by getChatterMessages.\n */\n async find(basicFilterDto: BasicFilterDto, solidRequestContext: any = {}): Promise<any> {\n const result = await super.find(basicFilterDto, solidRequestContext);\n this.trimMessageUsers(result?.records);\n // A grouped find (populateGroup) nests its entities one level deeper.\n for (const groupRecord of result?.groupRecords ?? []) {\n this.trimMessageUsers(groupRecord?.groupData?.records);\n }\n return result;\n }\n\n async findOne(id: number, query: any = {}, solidRequestContext: any = {}) {\n return this.trimMessageUser(await super.findOne(id, query, solidRequestContext));\n }\n\n private isEditableCustomNoteMessage(message: ChatterMessage): boolean {\n if (message.messageType !== CHATTER_MESSAGE_TYPE.CUSTOM) {\n return false;\n }\n return [CHATTER_MESSAGE_SUBTYPE.CUSTOM, CHATTER_MESSAGE_SUBTYPE.NOTE].includes(message.messageSubType as any);\n }\n\n private parseAttachmentIds(value?: string): number[] {\n if (!value || typeof value !== 'string') return [];\n return value\n .split(',')\n .map(v => Number(v.trim()))\n .filter(v => Number.isInteger(v) && v > 0);\n }\n\n private parseMessageBodyMentions(value?: string): ChatterMention[] {\n if (!value || typeof value !== 'string') return [];\n try {\n const parsed = JSON.parse(value);\n return Array.isArray(parsed) ? parsed : [];\n } catch {\n return [];\n }\n }\n\n private renderMentionTokens(messageBody: string, mentions: ChatterMention[]) {\n return mentions.reduce((nextMessage, mention, index) => {\n const username = mention.username;\n if (!username) return nextMessage;\n return nextMessage.replace(new RegExp(`\\\\{\\\\{\\\\s*${index}\\\\s*\\\\}\\\\}`, 'g'), `@${username}`);\n }, messageBody || '');\n }\n\n /**\n * Chatter attachments bypass MediaFieldCrudManager - they go straight to\n * storageProvider.store() - so the shared predicate is applied here directly. The rules\n * themselves live in media-file-types so upload paths can't drift apart.\n */\n private validateChatterMediaFiles(files: Express.Multer.File[] = []) {\n if (Array.isArray(files) && files.some(file => isDangerousMediaFile(file))) {\n throw new BadRequestException('Dangerous file types are not allowed in chatter attachments.');\n }\n }\n\n private async publishChatterMentionNotifications(message: ChatterMessage, model: any) {\n if (message.messageType !== CHATTER_MESSAGE_TYPE.CUSTOM || message.messageSubType !== CHATTER_MESSAGE_SUBTYPE.NOTE) {\n return;\n }\n\n const mentions = this.parseMessageBodyMentions(message.messageBodyMentions);\n const mentionUserIds = mentions\n .map(mention => Number(mention.id))\n .filter(id => Number.isInteger(id) && id > 0);\n const uniqueMentionUserIds = Array.from(new Set(mentionUserIds));\n if (uniqueMentionUserIds.length === 0) return;\n\n const activeUser = this.requestContextService.getActiveUser();\n\n const payload: ChatterMentionNotificationPayload = {\n templateName: 'chatter-mention-notification',\n mentions: mentions.map(mention => ({\n id: Number(mention.id) || undefined,\n username: mention.username,\n displayName: mention.display_name || mention.displayName || mention.username,\n })),\n actor: {\n id: activeUser?.sub,\n username: activeUser?.username,\n email: activeUser?.email,\n },\n noteBody: this.renderMentionTokens(message.messageBody, mentions),\n entity: {\n id: message.coModelEntityId,\n modelName: model?.singularName || message.coModelName,\n moduleName: model?.module?.name,\n displayName: model?.displayName || message.coModelName,\n userKey: message.modelUserKey,\n },\n parentEntity: 'chatterMessage',\n parentEntityId: message.id,\n };\n\n try {\n await this.publisherFactory.publish(\n {\n payload,\n parentEntity: 'chatterMessage',\n parentEntityId: message.id,\n retryCount: 3,\n retryInterval: 5000,\n },\n 'ChatterMentionNotificationEmailQueuePublisher',\n );\n } catch (error: any) {\n this._logger.error(`Failed to publish chatter mention notification email job: ${error.message}`, error.stack);\n }\n }\n\n // Deliberately bypasses UserRepository's security-rule filtering: the mention picker\n // needs id/username/fullName for any active user regardless of the caller's row-level\n // access to the User model, same as the getChatterMessages one-to-many lookup below.\n async getMentionableUsers(search?: string, limit: number = 8): Promise<Array<{ id: number; username: string; fullName: string }>> {\n const normalizedLimit = Number.isInteger(limit) && limit > 0 && limit <= 50 ? limit : 8;\n const userRepository = this.entityManager.getRepository(User);\n\n const qb = userRepository\n .createQueryBuilder('user')\n .select(['user.id', 'user.username', 'user.fullName'])\n .where('user.active = :active', { active: true });\n\n const trimmedSearch = (search ?? '').trim();\n if (trimmedSearch) {\n qb.andWhere('(LOWER(user.username) LIKE :search OR LOWER(user.fullName) LIKE :search)', {\n search: `%${trimmedSearch.toLowerCase()}%`,\n });\n }\n\n qb.orderBy('user.username', 'ASC').take(normalizedLimit);\n\n const users = await qb.getMany();\n return users.map(user => ({ id: user.id, username: user.username, fullName: user.fullName }));\n }\n\n async markCompleted(id: number) {\n const activeUser = this.requestContextService.getActiveUser();\n if (!activeUser) {\n throw new BadRequestException(ERROR_MESSAGES.FORBIDDEN);\n }\n\n const message = await this.repo.findOne({ where: { id } });\n if (!message) {\n throw new NotFoundException(`Entity [solid-core.chatterMessage] with id ${id} not found`);\n }\n\n await this.assertRecordAccess(message.coModelName, message.coModelEntityId);\n\n message.status = CHATTER_MESSAGE_STATUS.COMPLETED;\n return this.repo.save(message);\n }\n\n async updateCustomNoteMessage(id: number, updateDto: UpdateChatterNoteMessageDto, files: Express.Multer.File[] = []) {\n const activeUser = this.requestContextService.getActiveUser();\n if (!activeUser) {\n throw new ForbiddenException(ERROR_MESSAGES.FORBIDDEN);\n }\n\n const message = await this.repo.findOne({ where: { id }, relations: { user: true } });\n if (!message) {\n throw new NotFoundException(`Entity [solid-core.chatterMessage] with id ${id} not found`);\n }\n\n await this.assertRecordAccess(message.coModelName, message.coModelEntityId);\n\n if (!this.isEditableCustomNoteMessage(message)) {\n throw new BadRequestException('Only custom note messages can be edited.');\n }\n\n if (!message.user?.id || message.user.id !== activeUser.sub) {\n throw new ForbiddenException('You can only edit your own custom note messages.');\n }\n\n const removeAttachmentIds = this.parseAttachmentIds(updateDto?.removeAttachmentIds);\n const hasMessageBody = typeof updateDto?.messageBody === 'string';\n const hasMessageBodyMentions = typeof updateDto?.messageBodyMentions === 'string';\n const trimmedMessageBody = (updateDto?.messageBody ?? '').trim();\n const hasNewFiles = Array.isArray(files) && files.length > 0;\n\n if (!hasMessageBody && !hasMessageBodyMentions && removeAttachmentIds.length === 0 && !hasNewFiles) {\n throw new BadRequestException('No note changes submitted.');\n }\n\n if (hasMessageBody && trimmedMessageBody.length === 0) {\n throw new BadRequestException('Message body cannot be empty.');\n }\n\n this.validateChatterMediaFiles(files);\n\n if (hasMessageBody) {\n message.messageBody = trimmedMessageBody;\n }\n if (hasMessageBodyMentions) {\n message.messageBodyMentions = updateDto.messageBodyMentions;\n }\n const model = await this.modelMetadataRepo.findOne({\n where: { singularName: message.coModelName },\n relations: { module: true }\n });\n message.updatedBy = activeUser.sub;\n // Ensure updatedAt changes even for attachment-only edits.\n message.updatedAt = new Date();\n const savedMessage = await this.repo.save(message);\n\n if (removeAttachmentIds.length > 0 || hasNewFiles) {\n const model = await this.modelMetadataService.findOneBySingularName('chatterMessage', {\n fields: {\n model: true,\n mediaStorageProvider: true,\n },\n module: true,\n });\n\n const mediaFields = model.fields.filter(field => field.type === 'mediaSingle' || field.type === 'mediaMultiple');\n const attachmentFieldIds = mediaFields.map(field => field.id);\n\n if (removeAttachmentIds.length > 0 && attachmentFieldIds.length > 0) {\n const mediaToRemove = await this.mediaRepository.find({\n where: {\n id: In(removeAttachmentIds),\n entityId: savedMessage.id,\n modelMetadata: { id: model.id },\n fieldMetadata: { id: In(attachmentFieldIds) },\n },\n relations: {\n mediaStorageProviderMetadata: true,\n fieldMetadata: true,\n },\n });\n\n for (const media of mediaToRemove) {\n const storageType = media.mediaStorageProviderMetadata?.type as MediaStorageProviderType;\n const storageProvider = await getMediaStorageProvider(this.moduleRef, storageType);\n await storageProvider.deleteByMediaRecord(media);\n }\n\n if (mediaToRemove.length > 0) {\n await this.mediaRepository.remove(mediaToRemove);\n }\n }\n\n for (const mediaField of mediaFields) {\n const storageProviderMetadata = mediaField.mediaStorageProvider;\n const storageProviderType = storageProviderMetadata.type as MediaStorageProviderType;\n const storageProvider = await getMediaStorageProvider(this.moduleRef, storageProviderType);\n\n const media = files.filter(multerFile => multerFile.fieldname === mediaField.name);\n if (media.length > 0) {\n await storageProvider.store(media, savedMessage, mediaField);\n }\n }\n }\n\n await this.publishChatterMentionNotifications(savedMessage, model);\n\n // The `user` relation was loaded for the ownership check above; don't return all of it.\n return this.trimMessageUser(savedMessage);\n }\n\n async postMessage(postDto: PostChatterMessageDto, files: Express.Multer.File[] = []) {\n const coModelName = lowerFirst(postDto.coModelName);\n await this.assertRecordAccess(coModelName, postDto.coModelEntityId);\n\n this.validateChatterMediaFiles(files);\n\n const chatterMessage = new ChatterMessage();\n chatterMessage.messageType = CHATTER_MESSAGE_TYPE.CUSTOM;\n chatterMessage.messageSubType = postDto.messageSubType || CHATTER_MESSAGE_SUBTYPE.CUSTOM;\n chatterMessage.status = postDto.status ?? CHATTER_MESSAGE_STATUS.PENDING;\n chatterMessage.messageBody = postDto.messageBody;\n chatterMessage.messageBodyMentions = postDto.messageBodyMentions;\n chatterMessage.coModelEntityId = postDto.coModelEntityId;\n chatterMessage.coModelName = coModelName;\n chatterMessage.modelUserKey = postDto.modelUserKey ?? null;\n\n const model = await this.modelMetadataRepo.findOne({\n where: { singularName: coModelName },\n relations: { userKeyField: true, module: true }\n });\n chatterMessage.modelDisplayName = model?.displayName ?? null;\n\n this.stampMessageAuditFields(chatterMessage);\n\n const savedMessage = await this.repo.save(chatterMessage);\n\n if (files && files.length > 0) {\n const model = await this.modelMetadataService.findOneBySingularName('chatterMessage', {\n fields: {\n model: true,\n mediaStorageProvider: true,\n },\n module: true,\n });\n\n const mediaFields = model.fields.filter(field => field.type === 'mediaSingle' || field.type === 'mediaMultiple');\n\n for (const mediaField of mediaFields) {\n const media = files.filter(multerFile => multerFile.fieldname === mediaField.name);\n if (media.length > 0) {\n const storageProviderMetadata = mediaField.mediaStorageProvider;\n const storageProviderType = storageProviderMetadata.type as MediaStorageProviderType;\n const storageProvider = await getMediaStorageProvider(this.moduleRef, storageProviderType);\n await storageProvider.store(media, savedMessage, mediaField);\n }\n }\n }\n\n await this.publishChatterMentionNotifications(savedMessage, model);\n\n return savedMessage;\n }\n\n async postAuditMessageOnInsert(entity: any, modelName: string, messageQueue: boolean = false, userId?: number | null) {\n if (!entity) {\n return;\n }\n const model = await this.modelMetadataRepo.findOne({\n where: {\n singularName: lowerFirst(modelName)\n },\n relations: {\n fields: true,\n module: true,\n userKeyField: true\n }\n });\n\n if (!model || !model.enableAuditTracking) {\n return;\n }\n\n const auditFields = model.fields.filter(field =>\n field.enableAuditTracking &&\n !['mediaSingle', 'mediaMultiple', 'richText', 'json'].includes(field.type) &&\n !(field.type === 'relation' && field.relationType === 'one-to-many')\n );\n\n const chatterMessage = new ChatterMessage();\n chatterMessage.messageType = CHATTER_MESSAGE_TYPE.AUDIT;\n chatterMessage.messageSubType = CHATTER_MESSAGE_SUBTYPE.AUDIT_INSERT;\n chatterMessage.status = CHATTER_MESSAGE_STATUS.PENDING;\n chatterMessage.coModelEntityId = entity.id;\n chatterMessage.coModelName = model?.singularName;\n chatterMessage.modelDisplayName = model?.displayName;\n chatterMessage.modelUserKey = entity[model?.userKeyField?.name];\n chatterMessage.messageBody = `New ${model?.displayName} created`;\n this.stampMessageAuditFields(chatterMessage, userId);\n\n const savedMessage = await this.repo.save(chatterMessage);\n\n for (const field of auditFields) {\n const fieldValue = entity[field.name];\n if (fieldValue !== undefined && fieldValue !== null && fieldValue !== '') {\n const messageDetail = new ChatterMessageDetails();\n messageDetail.chatterMessage = savedMessage;\n messageDetail.fieldName = field.name;\n messageDetail.fieldDisplayName = field.displayName;\n messageDetail.fieldType = field.type;\n messageDetail.oldValue = null;\n messageDetail.oldValueDisplay = null;\n messageDetail.newValue = this.formatFieldValue(field, fieldValue);\n messageDetail.newValueDisplay = await this.formatFieldValueDisplay(field, fieldValue);\n await this.chatterMessageDetailsRepo.save(messageDetail);\n }\n }\n }\n\n async postAuditMessageOnUpdate(entity: any, modelName: string, databaseEntity: any, updatedColumns: any[] = [], messageQueue: boolean = false, userId?: number | null) {\n if (!databaseEntity || !entity) {\n return;\n }\n const model = await this.modelMetadataRepo.findOne({\n where: {\n singularName: lowerFirst(modelName)\n },\n relations: {\n fields: true,\n module: true,\n userKeyField: true\n }\n });\n\n if (!model || !model.enableAuditTracking) {\n return;\n }\n\n const modelFields = await this.modelMetadataHelperService.loadFieldHierarchy(model.singularName)\n\n const auditFields = modelFields.filter(field =>\n field.enableAuditTracking &&\n !['mediaSingle', 'mediaMultiple', 'richText', 'json'].includes(field.type) &&\n !(field.type === 'relation' && field.relationType === 'one-to-many')\n );\n\n const updatedFieldNames = new Set(updatedColumns.map(col => col.propertyName));\n\n const allNonRelationFields = auditFields.filter(field => field.type !== 'relation');\n const allRelationFields = auditFields.filter(field => field.type === 'relation');\n\n let potentialNonRelationFields = [];\n\n if (updatedColumns.length > 0) {\n potentialNonRelationFields = allNonRelationFields.filter(field =>\n updatedFieldNames.has(field.name)\n );\n } else {\n potentialNonRelationFields = allNonRelationFields;\n }\n\n const potentialRelationFields = allRelationFields;\n\n const changedNonRelationFields = potentialNonRelationFields.filter(field => {\n const newValue = entity[field.name];\n const oldValue = databaseEntity[field.name];\n return this.hasValueChanged(newValue, oldValue);\n });\n\n const changedRelationFields = [];\n if (potentialRelationFields.length > 0) {\n const metadata = this.entityManager.connection.entityMetadatas.find(m => m.name === modelName);\n const populatedOldEntity = await this.populateRelationFields(databaseEntity, potentialRelationFields, metadata);\n\n for (const field of potentialRelationFields) {\n const newValue = entity[field.name];\n const oldValue = populatedOldEntity[field.name];\n\n if (this.hasRelationValueChanged(field, newValue, oldValue)) {\n changedRelationFields.push({\n field,\n newValue,\n oldValue\n });\n }\n }\n }\n\n const allChangedFields = [\n ...changedNonRelationFields.map(field => ({\n field,\n newValue: entity[field.name],\n oldValue: databaseEntity[field.name]\n })),\n ...changedRelationFields\n ];\n\n if (allChangedFields.length === 0) {\n return;\n }\n\n const chatterMessage = new ChatterMessage();\n chatterMessage.messageType = CHATTER_MESSAGE_TYPE.AUDIT;\n chatterMessage.messageSubType = CHATTER_MESSAGE_SUBTYPE.AUDIT_UPDATE;\n chatterMessage.status = CHATTER_MESSAGE_STATUS.PENDING;\n chatterMessage.coModelEntityId = entity?.id;\n chatterMessage.coModelName = model?.singularName;\n chatterMessage.modelDisplayName = model.displayName;\n chatterMessage.modelUserKey = entity[model?.userKeyField?.name];\n chatterMessage.messageBody = `${model?.displayName} updated`;\n this.stampMessageAuditFields(chatterMessage, userId);\n\n const savedMessage = await this.repo.save(chatterMessage);\n\n for (const { field, newValue, oldValue } of allChangedFields) {\n const messageDetail = new ChatterMessageDetails();\n messageDetail.chatterMessage = savedMessage;\n messageDetail.fieldName = field.name;\n messageDetail.fieldDisplayName = field.displayName;\n messageDetail.fieldType = field.type;\n messageDetail.oldValue = this.formatFieldValue(field, oldValue);\n messageDetail.newValue = this.formatFieldValue(field, newValue);\n messageDetail.oldValueDisplay = await this.formatFieldValueDisplay(field, oldValue);\n messageDetail.newValueDisplay = await this.formatFieldValueDisplay(field, newValue);\n await this.chatterMessageDetailsRepo.save(messageDetail);\n }\n }\n\n async postAuditMessageOnDelete(modelName: string, databaseEntity: any, messageQueue: boolean = false, userId?: number | null) {\n const model = await this.modelMetadataRepo.findOne({\n where: {\n singularName: lowerFirst(modelName)\n },\n relations: {\n module: true,\n userKeyField: true\n }\n });\n\n if (!model || !model.enableAuditTracking) {\n return;\n }\n\n const modelFields = await this.modelMetadataHelperService.loadFieldHierarchy(model.singularName);\n\n const auditFields = modelFields.filter(field =>\n field.enableAuditTracking &&\n !['mediaSingle', 'mediaMultiple', 'richText', 'json'].includes(field.type) &&\n !(field.type === 'relation' && field.relationType === 'one-to-many')\n );\n\n // Populate relation fields so display values (e.g. names) are resolvable.\n // The related entities themselves still exist in the DB after a delete.\n const relationFields = auditFields.filter(field => field.type === 'relation');\n const entityMetadata = this.entityManager.connection.entityMetadatas.find(m => m.name === modelName);\n const populatedEntity = relationFields.length > 0 && entityMetadata\n ? await this.populateRelationFields(databaseEntity, relationFields, entityMetadata)\n : { ...databaseEntity };\n\n const chatterMessage = new ChatterMessage();\n chatterMessage.messageType = CHATTER_MESSAGE_TYPE.AUDIT;\n chatterMessage.messageSubType = CHATTER_MESSAGE_SUBTYPE.AUDIT_DELETE;\n chatterMessage.status = CHATTER_MESSAGE_STATUS.PENDING;\n chatterMessage.coModelEntityId = databaseEntity?.id;\n chatterMessage.coModelName = model?.singularName;\n chatterMessage.modelDisplayName = model?.displayName;\n chatterMessage.modelUserKey = databaseEntity[model?.userKeyField?.name];\n chatterMessage.messageBody = `${model?.displayName} deleted`;\n\n this.stampMessageAuditFields(chatterMessage, userId);\n\n const savedMessage = await this.repo.save(chatterMessage);\n\n for (const field of auditFields) {\n const fieldValue = populatedEntity[field.name];\n if (fieldValue !== undefined && fieldValue !== null && fieldValue !== '') {\n const messageDetail = new ChatterMessageDetails();\n messageDetail.chatterMessage = savedMessage;\n messageDetail.fieldName = field.name;\n messageDetail.fieldDisplayName = field.displayName;\n messageDetail.fieldType = field.type;\n messageDetail.oldValue = this.formatFieldValue(field, fieldValue);\n messageDetail.oldValueDisplay = await this.formatFieldValueDisplay(field, fieldValue);\n messageDetail.newValue = null;\n messageDetail.newValueDisplay = null;\n await this.chatterMessageDetailsRepo.save(messageDetail);\n }\n }\n }\n\n private formatFieldValue(field: any, value: any): string {\n if (value === null || value === undefined) {\n return '';\n }\n\n if (field.type === 'selectionStatic' || field.type === 'selectionDynamic') {\n return `${value}`;\n }\n\n if (field.type === 'relation') {\n if (field.relationType === \"many-to-one\") {\n return value.id;\n }\n if (field.relationType === 'many-to-many') {\n return value.map(item => item.id).join(', ');\n }\n }\n\n if (value instanceof Date) {\n return serializeDate(value);\n }\n\n return value.toString();\n }\n\n private async formatFieldValueDisplay(field: any, value: any): Promise<string> {\n if (value === null || value === undefined) {\n return '';\n }\n\n if (field.type === 'selectionStatic' || field.type === 'selectionDynamic') {\n return `${value}`;\n }\n\n if (['date', 'datetime', 'time'].includes(field.type)) {\n return null;\n }\n\n if (field.type === 'relation') {\n if (field.relationType === \"many-to-one\") {\n if (value.name) {\n return value.name;\n }\n\n try {\n const relatedModel = await this.modelMetadataRepo.findOne({\n where: { singularName: field.relationCoModelSingularName || field.relation },\n relations: { userKeyField: true }\n });\n\n if (relatedModel && relatedModel.userKeyField) {\n const userKeyFieldName = relatedModel.userKeyField.name;\n return value[userKeyFieldName] ? value[userKeyFieldName].toString() : '';\n }\n\n if (value.id) {\n return value.id.toString();\n }\n } catch (error: any) {\n console.error('Error fetching related model metadata:', error);\n return value.id ? value.id.toString() : '';\n }\n }\n\n if (field.relationType === 'many-to-many') {\n return value.map(item => item.name).join(', ');\n }\n }\n\n return value.toString();\n }\n\n private hasValueChanged(newValue: any, oldValue: any): boolean {\n if (newValue === oldValue) {\n return false;\n }\n\n if (newValue === null && oldValue === null) {\n return false;\n }\n\n if (newValue === undefined && oldValue === undefined) {\n return false;\n }\n\n if (newValue && oldValue && typeof newValue === 'object' && typeof oldValue === 'object') {\n if (newValue.id !== undefined && oldValue.id !== undefined) {\n return newValue.id !== oldValue.id;\n }\n\n if (Array.isArray(newValue) && Array.isArray(oldValue)) {\n if (newValue.length !== oldValue.length) {\n return true;\n }\n const newIds = newValue.map(item => item.id || item).sort();\n const oldIds = oldValue.map(item => item.id || item).sort();\n return JSON.stringify(newIds) !== JSON.stringify(oldIds);\n }\n }\n\n if (Array.isArray(newValue) && Array.isArray(oldValue)) {\n return JSON.stringify(newValue) !== JSON.stringify(oldValue);\n }\n\n return true;\n }\n\n private hasRelationValueChanged(field: any, newValue: any, oldValue: any): boolean {\n if (newValue === oldValue) {\n return false;\n }\n\n if ((newValue === null || newValue === undefined) && (oldValue === null || oldValue === undefined)) {\n return false;\n }\n\n if (field.relationType === 'many-to-one') {\n const newId = this.extractRelationId(newValue);\n const oldId = this.extractRelationId(oldValue);\n return newId !== oldId;\n }\n\n if (field.relationType === 'many-to-many') {\n const newIds = this.extractRelationIds(newValue);\n const oldIds = this.extractRelationIds(oldValue);\n\n if (newIds.length !== oldIds.length) {\n return true;\n }\n\n newIds.sort();\n oldIds.sort();\n\n return JSON.stringify(newIds) !== JSON.stringify(oldIds);\n }\n\n return this.hasValueChanged(newValue, oldValue);\n }\n\n private extractRelationId(value: any): any {\n if (value === null || value === undefined) {\n return null;\n }\n\n if (typeof value === 'string' || typeof value === 'number') {\n return value;\n }\n\n if (typeof value === 'object' && value.id !== undefined) {\n return value.id;\n }\n\n return null;\n }\n\n private extractRelationIds(value: any): any[] {\n if (!Array.isArray(value)) {\n const id = this.extractRelationId(value);\n return id !== null ? [id] : [];\n }\n\n return value.map(item => this.extractRelationId(item)).filter(id => id !== null);\n }\n\n private async populateRelationFields(databaseEntity: any, relationFields: any[], metadata: EntityMetadata): Promise<any> {\n const populatedEntity = { ...databaseEntity };\n\n for (const field of relationFields) {\n const relationValue = databaseEntity[field.name];\n\n if (relationValue === null || relationValue === undefined) {\n populatedEntity[field.name] = relationValue;\n continue;\n }\n\n const relationMetadata = metadata.relations.find(rel => rel.propertyName === field.name);\n if (!relationMetadata) {\n populatedEntity[field.name] = relationValue;\n continue;\n }\n\n const targetEntity = relationMetadata.inverseEntityMetadata || relationMetadata.type;\n\n if (field.relationType === 'many-to-one') {\n const relationId = this.extractRelationId(relationValue);\n if (relationId) {\n const relatedEntity = await this.entityManager.findOne(targetEntity as any, {\n where: { id: relationId }\n });\n populatedEntity[field.name] = relatedEntity;\n } else {\n populatedEntity[field.name] = relationValue;\n }\n } else if (field.relationType === 'many-to-many' || field.relationType === 'manyToMany') {\n const relationIds = this.extractRelationIds(relationValue);\n if (relationIds.length > 0) {\n const relatedEntities = await this.entityManager.findByIds(targetEntity as any, relationIds);\n populatedEntity[field.name] = relatedEntities;\n } else {\n populatedEntity[field.name] = relationValue;\n }\n } else {\n populatedEntity[field.name] = relationValue;\n }\n }\n\n return populatedEntity;\n }\n\n private logHeapUsed(label: string) {\n const mb = () => Math.round(process.memoryUsage().heapUsed / 1024 / 1024);\n this._logger.log(`heapUsedMB(${label}): ${mb()}`);\n }\n\n // [2026-02-05T23:31:21.025Z] INFO: [200 OK] \n // GET /api/chatter-message/getChatterMessages/216/mswipeBoomboxBulkUpload?populateMedia[0]=messageAttachments&populate[0]=user&populate[1]=chatterMessageDetails&limit=25 22747ms\n async getChatterMessages(entityId: number, entityName: string, query: any) {\n const { limit = 25, offset = 0, populate = [], populateMedia = [], filters } = query;\n this.logHeapUsed('getChatterMessages-start');\n\n await this.assertRecordAccess(lowerFirst(entityName), entityId);\n\n const model = await this.modelMetadataRepo.findOne({\n where: {\n singularName: entityName\n },\n });\n this.logHeapUsed('getChatterMessages-modelLoaded');\n const oneToManyFields = await this.fieldMetadataRepo.find({\n where: {\n model: { id: model.id },\n type: 'relation',\n relationType: 'one-to-many'\n }\n });\n this.logHeapUsed('getChatterMessages-oneToManyFieldsLoaded');\n\n const relatedEntitiesMap = new Map<string, number[]>();\n\n for (const field of oneToManyFields) {\n if (field.enableAuditTracking === false) {\n this._logger.log(`Skipping field ${field.name} for chatter message retrieval because audit tracking is disabled`);\n continue\n }\n const coModelName = field.relationCoModelSingularName;\n const coModelFieldName = field.relationCoModelFieldName;\n\n const coModel = await this.modelMetadataRepo.findOne({\n where: { singularName: coModelName }\n });\n\n if (coModel) {\n //const relatedEntityRepository = this.entityManager.getRepository(classify(coModelName));\n const dsName = coModel.dataSource || 'default';\n const em = dsName === 'default' ? this.entityManager : this.moduleRef.get(`${dsName}EntityManager`, { strict: false });\n\n const relatedEntityRepository = em.getRepository(classify(coModelName));\n\n const relatedEntities = await relatedEntityRepository.find({\n select: {\n id: true,\n },\n where: { [coModelFieldName]: { id: entityId } },\n take: 5,\n });\n\n const relatedIds = relatedEntities.map((entity: any) => entity.id);\n relatedEntitiesMap.set(field.name, relatedIds);\n }\n }\n this.logHeapUsed('getChatterMessages-relatedEntitiesLoaded');\n\n const qb = await this.repo.createSecurityRuleAwareQueryBuilder('entity');\n this.logHeapUsed('getChatterMessages-queryBuilderReady');\n\n const orConditions: string[] = [];\n const parameters: any = {};\n\n orConditions.push('(entity.coModelName = :entityName AND entity.coModelEntityId = :entityId)');\n parameters.entityName = entityName;\n parameters.entityId = entityId;\n\n let paramIndex = 0;\n for (const [fieldName, relatedIds] of relatedEntitiesMap.entries()) {\n if (relatedIds.length > 0) {\n const field = oneToManyFields.find(f => f.name === fieldName);\n if (field) {\n const coModelName = field.relationCoModelSingularName;\n const idsParamName = `relatedIds${paramIndex}`;\n orConditions.push(`(entity.coModelName = :coModelName${paramIndex} AND entity.coModelEntityId IN (:...${idsParamName}))`);\n parameters[`coModelName${paramIndex}`] = coModelName;\n parameters[idsParamName] = relatedIds;\n paramIndex++;\n }\n }\n }\n\n // SECURITY: must be andWhere. `where()` REPLACES every previously registered condition,\n // which would discard the row-level security rules applied by\n // createSecurityRuleAwareQueryBuilder above. (The inner `where` is safe: it is the first\n // condition on a fresh Brackets sub-builder.)\n qb.andWhere(new Brackets(qb => {\n qb.where(orConditions.join(' OR '), parameters);\n }));\n\n const relations = ['chatterMessageDetails'];\n if (populate && populate.length > 0) {\n const normalizedPopulate = this.crudHelperService.normalize(populate);\n // SECURITY: 'user' is joined below with an explicit column allowlist. A client-supplied\n // populate[]=user must not be able to turn it back into a full-entity join (the chatter\n // panel does send exactly that).\n relations.push(...normalizedPopulate.filter(rel => rel !== 'user' && !relations.includes(rel)));\n }\n\n relations.forEach(relation => {\n qb.leftJoinAndSelect(`entity.${relation}`, relation);\n });\n\n // Only the author's id and display name leave this endpoint - see CHATTER_MESSAGE_USER_FIELDS.\n // This join must stay before applyFilters below: it lets filters[user][fullName] reuse this\n // alias instead of adding a second join of its own.\n qb.leftJoin('entity.user', 'user');\n qb.addSelect(CHATTER_MESSAGE_USER_FIELDS.map(field => `user.${field}`));\n\n if (filters) {\n qb.andWhere(new Brackets(whereQb => {\n this.crudHelperService.applyFilters(whereQb, filters, 'entity', qb);\n }));\n }\n\n qb.orderBy('entity.createdAt', 'DESC');\n\n qb.skip(offset).take(limit);\n\n const [entities, count] = await qb.getManyAndCount();\n this.logHeapUsed('getChatterMessages-entitiesLoaded');\n\n // The join above only selects the allowlisted columns, but TypeORM still hydrates the\n // author with `new User()`, which leaves every initialiser-backed property (active,\n // forcePasswordChange, ...) sitting on the instance holding its default rather than a\n // value read from the database. Replace it with a plain object of exactly the\n // allowlisted keys so the response cannot report fabricated defaults as data.\n this.trimMessageUsers(entities);\n\n // Convert date strings in message details to ISO format for consistent handling on the frontend\n const DATE_FIELD_TYPES = ['date', 'datetime', 'time'];\n for (const entity of entities) {\n for (const detail of entity.chatterMessageDetails ?? []) {\n if (!detail.fieldType || !DATE_FIELD_TYPES.includes(detail.fieldType)) continue;\n if (detail.oldValue) {\n const d = LocalDateTimeTransformer.from(detail.oldValue);\n if (d) detail.oldValue = d.toISOString();\n }\n if (detail.newValue) {\n const d = LocalDateTimeTransformer.from(detail.newValue);\n if (d) detail.newValue = d.toISOString();\n }\n }\n }\n\n if (populateMedia && populateMedia.length > 0) {\n const normalizedPopulateMedia = this.crudHelperService.normalize(populateMedia);\n this.logHeapUsed('getChatterMessages-beforePopulateMedia');\n await this['handlePopulateMedia'](normalizedPopulateMedia, entities);\n this.logHeapUsed('getChatterMessages-afterPopulateMedia');\n }\n\n const currentPage = Math.floor(offset / limit) + 1;\n const totalPages = Math.ceil(count / limit);\n const nextPage = currentPage < totalPages ? currentPage + 1 : null;\n const prevPage = currentPage > 1 ? currentPage - 1 : null;\n\n return {\n meta: {\n totalRecords: count,\n currentPage: currentPage,\n nextPage: nextPage,\n prevPage: prevPage,\n totalPages: totalPages,\n perPage: +limit,\n },\n records: entities\n };\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"chatter-message.service.js","sourceRoot":"","sources":["../../src/services/chatter-message.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { LocalDateTimeTransformer, serializeDate } from 'src/transformers/typeorm/local-date-time-transformer';\nimport { BadRequestException, ForbiddenException, forwardRef, Inject, Injectable, NotFoundException } from '@nestjs/common';\nimport { ModuleRef } from \"@nestjs/core\";\nimport { InjectEntityManager } from '@nestjs/typeorm';\nimport { Brackets, EntityManager, EntityMetadata, In } from 'typeorm';\n\nimport { classify } from '@angular-devkit/core/src/utils/strings';\nimport { CHATTER_MESSAGE_STATUS, CHATTER_MESSAGE_SUBTYPE, CHATTER_MESSAGE_TYPE, CHATTER_MESSAGE_USER_FIELDS } from 'src/constants/chatter-message.constants';\nimport { isDangerousMediaFile } from 'src/constants/media-file-types';\nimport { ERROR_MESSAGES } from 'src/constants/error-messages';\nimport { PostChatterMessageDto } from 'src/dtos/post-chatter-message.dto';\nimport { UpdateChatterNoteMessageDto } from 'src/dtos/update-chatter-note-message.dto';\nimport { ModelMetadataHelperService } from 'src/helpers/model-metadata-helper.service';\nimport { lowerFirst } from 'src/helpers/string.helper';\nimport { ChatterMentionNotificationPayload } from 'src/interfaces/chatter-mention-notification.interface';\nimport { ChatterMessageDetailsRepository } from 'src/repository/chatter-message-details.repository';\nimport { ChatterMessageRepository } from 'src/repository/chatter-message.repository';\nimport { FieldMetadataRepository } from 'src/repository/field-metadata.repository';\nimport { MediaRepository } from 'src/repository/media.repository';\nimport { ModelMetadataRepository } from 'src/repository/model-metadata.repository';\nimport { CRUDService } from 'src/services/crud.service';\nimport { BasicFilterDto } from '../dtos/basic-filters.dto';\nimport { MediaStorageProviderType } from '../dtos/create-media-storage-provider-metadata.dto';\nimport { ChatterMessageDetails } from '../entities/chatter-message-details.entity';\nimport { ChatterMessage } from '../entities/chatter-message.entity';\nimport { User } from '../entities/user.entity';\nimport { getMediaStorageProvider } from './mediaStorageProviders';\nimport { RequestContextService } from './request-context.service';\nimport { Logger } from '@nestjs/common';\nimport { SolidIntrospectService } from './solid-introspect.service';\nimport { PublisherFactory } from './queues/publisher-factory.service';\n\ninterface ChatterMention {\n username: string;\n display_name?: string;\n displayName?: string;\n id?: string | number;\n}\n\n/**\n * Server-side-only overrides for `postMessage`. Not part of `PostChatterMessageDto`, so\n * nothing here is settable over HTTP - only in-process callers such as migration or\n * back-fill services can supply it.\n */\nexport interface PostChatterMessageOptions {\n /** Backdate the message instead of stamping it with the current time. */\n createdAt?: Date;\n}\n\n@Injectable()\nexport class ChatterMessageService extends CRUDService<ChatterMessage> {\n private readonly _logger = new Logger(ChatterMessageService.name);\n\n constructor(\n @InjectEntityManager()\n readonly entityManager: EntityManager,\n // @InjectRepository(ChatterMessage, 'default')\n readonly repo: ChatterMessageRepository,\n // @InjectRepository(ChatterMessageDetailsRepository, 'default')\n readonly chatterMessageDetailsRepo: ChatterMessageDetailsRepository,\n readonly mediaRepository: MediaRepository,\n // @InjectRepository(FieldMetadata, 'default')\n // readonly fieldMetadataRepo: Repository<FieldMetadata>,\n readonly fieldMetadataRepo: FieldMetadataRepository,\n readonly moduleRef: ModuleRef,\n // @InjectRepository(ModelMetadata)\n // private readonly modelMetadataRepo: Repository<ModelMetadata>,\n @Inject(forwardRef(() => ModelMetadataRepository))\n private readonly modelMetadataRepo: ModelMetadataRepository,\n readonly requestContextService: RequestContextService,\n private readonly modelMetadataHelperService: ModelMetadataHelperService,\n private readonly publisherFactory: PublisherFactory<ChatterMentionNotificationPayload>,\n ) {\n super(entityManager, repo, 'chatterMessage', 'solid-core', moduleRef);\n }\n\n private getCoModelService(coModelName: string): CRUDService<any> {\n const introspectService = this.moduleRef.get(SolidIntrospectService, { strict: false });\n const modelSingularName = lowerFirst(coModelName);\n const coModelService = introspectService?.getCRUDService(modelSingularName);\n if (!coModelService) {\n throw new BadRequestException(ERROR_MESSAGES.MODEL_SERVICE_NOT_FOUND(modelSingularName));\n }\n return coModelService;\n }\n\n private async assertRecordAccess(coModelName: string, coModelEntityId: number) {\n const activeUser = this.requestContextService.getActiveUser();\n if (!activeUser) {\n throw new ForbiddenException(ERROR_MESSAGES.FORBIDDEN);\n }\n\n const coModelService = this.getCoModelService(coModelName);\n await coModelService.findOne(coModelEntityId, {}, { activeUser });\n }\n\n private resolveMessageUserId(userId?: number | null): number | null {\n if (userId) {\n return userId;\n }\n\n return this.requestContextService.getActiveUser()?.sub ?? null;\n }\n\n private resolveMessageUser(userId?: number | null) {\n const resolvedUserId = this.resolveMessageUserId(userId);\n return resolvedUserId ? ({ id: resolvedUserId } as any) : null;\n }\n\n private stampMessageAuditFields(chatterMessage: ChatterMessage, userId?: number | null) {\n const resolvedUserId = this.resolveMessageUserId(userId);\n chatterMessage.user = resolvedUserId ? ({ id: resolvedUserId } as any) : null;\n chatterMessage.createdBy = resolvedUserId;\n chatterMessage.updatedBy = resolvedUserId;\n }\n\n /**\n * Reduce a message's hydrated `user` relation to CHATTER_MESSAGE_USER_FIELDS.\n *\n * `getChatterMessages` restricts the columns in the query itself, which is preferable.\n * The generic CRUD paths below build their query from find-options and hand `populate`\n * straight to TypeORM, so they are trimmed after the fact instead. (`createdBy` /\n * `updatedBy` need nothing here - CRUDService.handlePopulateUserIdFields already selects\n * only USER_SUMMARY_FIELDS when a caller populates them.)\n */\n private trimMessageUser<M extends ChatterMessage>(message: M): M {\n if (message?.user) {\n message.user = this.toUserSummary(message.user) as User;\n }\n return message;\n }\n\n private trimMessageUsers(messages: ChatterMessage[] | undefined) {\n messages?.forEach(message => this.trimMessageUser(message));\n }\n\n /**\n * `GET /chatter-message?populate[]=user` would otherwise be a way around the column\n * allowlist applied by getChatterMessages.\n */\n async find(basicFilterDto: BasicFilterDto, solidRequestContext: any = {}): Promise<any> {\n const result = await super.find(basicFilterDto, solidRequestContext);\n this.trimMessageUsers(result?.records);\n // A grouped find (populateGroup) nests its entities one level deeper.\n for (const groupRecord of result?.groupRecords ?? []) {\n this.trimMessageUsers(groupRecord?.groupData?.records);\n }\n return result;\n }\n\n async findOne(id: number, query: any = {}, solidRequestContext: any = {}) {\n return this.trimMessageUser(await super.findOne(id, query, solidRequestContext));\n }\n\n private isEditableCustomNoteMessage(message: ChatterMessage): boolean {\n if (message.messageType !== CHATTER_MESSAGE_TYPE.CUSTOM) {\n return false;\n }\n return [CHATTER_MESSAGE_SUBTYPE.CUSTOM, CHATTER_MESSAGE_SUBTYPE.NOTE].includes(message.messageSubType as any);\n }\n\n private parseAttachmentIds(value?: string): number[] {\n if (!value || typeof value !== 'string') return [];\n return value\n .split(',')\n .map(v => Number(v.trim()))\n .filter(v => Number.isInteger(v) && v > 0);\n }\n\n private parseMessageBodyMentions(value?: string): ChatterMention[] {\n if (!value || typeof value !== 'string') return [];\n try {\n const parsed = JSON.parse(value);\n return Array.isArray(parsed) ? parsed : [];\n } catch {\n return [];\n }\n }\n\n private renderMentionTokens(messageBody: string, mentions: ChatterMention[]) {\n return mentions.reduce((nextMessage, mention, index) => {\n const username = mention.username;\n if (!username) return nextMessage;\n return nextMessage.replace(new RegExp(`\\\\{\\\\{\\\\s*${index}\\\\s*\\\\}\\\\}`, 'g'), `@${username}`);\n }, messageBody || '');\n }\n\n /**\n * Chatter attachments bypass MediaFieldCrudManager - they go straight to\n * storageProvider.store() - so the shared predicate is applied here directly. The rules\n * themselves live in media-file-types so upload paths can't drift apart.\n */\n private validateChatterMediaFiles(files: Express.Multer.File[] = []) {\n if (Array.isArray(files) && files.some(file => isDangerousMediaFile(file))) {\n throw new BadRequestException('Dangerous file types are not allowed in chatter attachments.');\n }\n }\n\n private async publishChatterMentionNotifications(message: ChatterMessage, model: any) {\n if (message.messageType !== CHATTER_MESSAGE_TYPE.CUSTOM || message.messageSubType !== CHATTER_MESSAGE_SUBTYPE.NOTE) {\n return;\n }\n\n const mentions = this.parseMessageBodyMentions(message.messageBodyMentions);\n const mentionUserIds = mentions\n .map(mention => Number(mention.id))\n .filter(id => Number.isInteger(id) && id > 0);\n const uniqueMentionUserIds = Array.from(new Set(mentionUserIds));\n if (uniqueMentionUserIds.length === 0) return;\n\n const activeUser = this.requestContextService.getActiveUser();\n\n const payload: ChatterMentionNotificationPayload = {\n templateName: 'chatter-mention-notification',\n mentions: mentions.map(mention => ({\n id: Number(mention.id) || undefined,\n username: mention.username,\n displayName: mention.display_name || mention.displayName || mention.username,\n })),\n actor: {\n id: activeUser?.sub,\n username: activeUser?.username,\n email: activeUser?.email,\n },\n noteBody: this.renderMentionTokens(message.messageBody, mentions),\n entity: {\n id: message.coModelEntityId,\n modelName: model?.singularName || message.coModelName,\n moduleName: model?.module?.name,\n displayName: model?.displayName || message.coModelName,\n userKey: message.modelUserKey,\n },\n parentEntity: 'chatterMessage',\n parentEntityId: message.id,\n };\n\n try {\n await this.publisherFactory.publish(\n {\n payload,\n parentEntity: 'chatterMessage',\n parentEntityId: message.id,\n retryCount: 3,\n retryInterval: 5000,\n },\n 'ChatterMentionNotificationEmailQueuePublisher',\n );\n } catch (error: any) {\n this._logger.error(`Failed to publish chatter mention notification email job: ${error.message}`, error.stack);\n }\n }\n\n // Deliberately bypasses UserRepository's security-rule filtering: the mention picker\n // needs id/username/fullName for any active user regardless of the caller's row-level\n // access to the User model, same as the getChatterMessages one-to-many lookup below.\n async getMentionableUsers(search?: string, limit: number = 8): Promise<Array<{ id: number; username: string; fullName: string }>> {\n const normalizedLimit = Number.isInteger(limit) && limit > 0 && limit <= 50 ? limit : 8;\n const userRepository = this.entityManager.getRepository(User);\n\n const qb = userRepository\n .createQueryBuilder('user')\n .select(['user.id', 'user.username', 'user.fullName'])\n .where('user.active = :active', { active: true });\n\n const trimmedSearch = (search ?? '').trim();\n if (trimmedSearch) {\n qb.andWhere('(LOWER(user.username) LIKE :search OR LOWER(user.fullName) LIKE :search)', {\n search: `%${trimmedSearch.toLowerCase()}%`,\n });\n }\n\n qb.orderBy('user.username', 'ASC').take(normalizedLimit);\n\n const users = await qb.getMany();\n return users.map(user => ({ id: user.id, username: user.username, fullName: user.fullName }));\n }\n\n async markCompleted(id: number) {\n const activeUser = this.requestContextService.getActiveUser();\n if (!activeUser) {\n throw new BadRequestException(ERROR_MESSAGES.FORBIDDEN);\n }\n\n const message = await this.repo.findOne({ where: { id } });\n if (!message) {\n throw new NotFoundException(`Entity [solid-core.chatterMessage] with id ${id} not found`);\n }\n\n await this.assertRecordAccess(message.coModelName, message.coModelEntityId);\n\n message.status = CHATTER_MESSAGE_STATUS.COMPLETED;\n return this.repo.save(message);\n }\n\n async updateCustomNoteMessage(id: number, updateDto: UpdateChatterNoteMessageDto, files: Express.Multer.File[] = []) {\n const activeUser = this.requestContextService.getActiveUser();\n if (!activeUser) {\n throw new ForbiddenException(ERROR_MESSAGES.FORBIDDEN);\n }\n\n const message = await this.repo.findOne({ where: { id }, relations: { user: true } });\n if (!message) {\n throw new NotFoundException(`Entity [solid-core.chatterMessage] with id ${id} not found`);\n }\n\n await this.assertRecordAccess(message.coModelName, message.coModelEntityId);\n\n if (!this.isEditableCustomNoteMessage(message)) {\n throw new BadRequestException('Only custom note messages can be edited.');\n }\n\n if (!message.user?.id || message.user.id !== activeUser.sub) {\n throw new ForbiddenException('You can only edit your own custom note messages.');\n }\n\n const removeAttachmentIds = this.parseAttachmentIds(updateDto?.removeAttachmentIds);\n const hasMessageBody = typeof updateDto?.messageBody === 'string';\n const hasMessageBodyMentions = typeof updateDto?.messageBodyMentions === 'string';\n const trimmedMessageBody = (updateDto?.messageBody ?? '').trim();\n const hasNewFiles = Array.isArray(files) && files.length > 0;\n\n if (!hasMessageBody && !hasMessageBodyMentions && removeAttachmentIds.length === 0 && !hasNewFiles) {\n throw new BadRequestException('No note changes submitted.');\n }\n\n if (hasMessageBody && trimmedMessageBody.length === 0) {\n throw new BadRequestException('Message body cannot be empty.');\n }\n\n this.validateChatterMediaFiles(files);\n\n if (hasMessageBody) {\n message.messageBody = trimmedMessageBody;\n }\n if (hasMessageBodyMentions) {\n message.messageBodyMentions = updateDto.messageBodyMentions;\n }\n const model = await this.modelMetadataRepo.findOne({\n where: { singularName: message.coModelName },\n relations: { module: true }\n });\n message.updatedBy = activeUser.sub;\n // Ensure updatedAt changes even for attachment-only edits.\n message.updatedAt = new Date();\n const savedMessage = await this.repo.save(message);\n\n if (removeAttachmentIds.length > 0 || hasNewFiles) {\n const model = await this.modelMetadataService.findOneBySingularName('chatterMessage', {\n fields: {\n model: true,\n mediaStorageProvider: true,\n },\n module: true,\n });\n\n const mediaFields = model.fields.filter(field => field.type === 'mediaSingle' || field.type === 'mediaMultiple');\n const attachmentFieldIds = mediaFields.map(field => field.id);\n\n if (removeAttachmentIds.length > 0 && attachmentFieldIds.length > 0) {\n const mediaToRemove = await this.mediaRepository.find({\n where: {\n id: In(removeAttachmentIds),\n entityId: savedMessage.id,\n modelMetadata: { id: model.id },\n fieldMetadata: { id: In(attachmentFieldIds) },\n },\n relations: {\n mediaStorageProviderMetadata: true,\n fieldMetadata: true,\n },\n });\n\n for (const media of mediaToRemove) {\n const storageType = media.mediaStorageProviderMetadata?.type as MediaStorageProviderType;\n const storageProvider = await getMediaStorageProvider(this.moduleRef, storageType);\n await storageProvider.deleteByMediaRecord(media);\n }\n\n if (mediaToRemove.length > 0) {\n await this.mediaRepository.remove(mediaToRemove);\n }\n }\n\n for (const mediaField of mediaFields) {\n const storageProviderMetadata = mediaField.mediaStorageProvider;\n const storageProviderType = storageProviderMetadata.type as MediaStorageProviderType;\n const storageProvider = await getMediaStorageProvider(this.moduleRef, storageProviderType);\n\n const media = files.filter(multerFile => multerFile.fieldname === mediaField.name);\n if (media.length > 0) {\n await storageProvider.store(media, savedMessage, mediaField);\n }\n }\n }\n\n await this.publishChatterMentionNotifications(savedMessage, model);\n\n // The `user` relation was loaded for the ownership check above; don't return all of it.\n return this.trimMessageUser(savedMessage);\n }\n\n /**\n * Post a chatter message.\n *\n * `options` is deliberately kept out of `PostChatterMessageDto` so it can only be supplied\n * by server-side callers (migrations, back-fills). The controller binds the DTO alone, so\n * an API client has no way to backdate a message.\n */\n async postMessage(postDto: PostChatterMessageDto, files: Express.Multer.File[] = [], options: PostChatterMessageOptions = {}) {\n const coModelName = lowerFirst(postDto.coModelName);\n await this.assertRecordAccess(coModelName, postDto.coModelEntityId);\n\n this.validateChatterMediaFiles(files);\n\n const chatterMessage = new ChatterMessage();\n chatterMessage.messageType = CHATTER_MESSAGE_TYPE.CUSTOM;\n chatterMessage.messageSubType = postDto.messageSubType || CHATTER_MESSAGE_SUBTYPE.CUSTOM;\n chatterMessage.status = postDto.status ?? CHATTER_MESSAGE_STATUS.PENDING;\n chatterMessage.messageBody = postDto.messageBody;\n chatterMessage.messageBodyMentions = postDto.messageBodyMentions;\n chatterMessage.coModelEntityId = postDto.coModelEntityId;\n chatterMessage.coModelName = coModelName;\n chatterMessage.modelUserKey = postDto.modelUserKey ?? null;\n // Left unset otherwise, so the @CreateDateColumn default still applies.\n if (options.createdAt) {\n chatterMessage.createdAt = options.createdAt;\n }\n\n const model = await this.modelMetadataRepo.findOne({\n where: { singularName: coModelName },\n relations: { userKeyField: true, module: true }\n });\n chatterMessage.modelDisplayName = model?.displayName ?? null;\n\n this.stampMessageAuditFields(chatterMessage);\n\n const savedMessage = await this.repo.save(chatterMessage);\n\n if (files && files.length > 0) {\n const model = await this.modelMetadataService.findOneBySingularName('chatterMessage', {\n fields: {\n model: true,\n mediaStorageProvider: true,\n },\n module: true,\n });\n\n const mediaFields = model.fields.filter(field => field.type === 'mediaSingle' || field.type === 'mediaMultiple');\n\n for (const mediaField of mediaFields) {\n const media = files.filter(multerFile => multerFile.fieldname === mediaField.name);\n if (media.length > 0) {\n const storageProviderMetadata = mediaField.mediaStorageProvider;\n const storageProviderType = storageProviderMetadata.type as MediaStorageProviderType;\n const storageProvider = await getMediaStorageProvider(this.moduleRef, storageProviderType);\n await storageProvider.store(media, savedMessage, mediaField);\n }\n }\n }\n\n await this.publishChatterMentionNotifications(savedMessage, model);\n\n return savedMessage;\n }\n\n async postAuditMessageOnInsert(entity: any, modelName: string, messageQueue: boolean = false, userId?: number | null) {\n if (!entity) {\n return;\n }\n const model = await this.modelMetadataRepo.findOne({\n where: {\n singularName: lowerFirst(modelName)\n },\n relations: {\n fields: true,\n module: true,\n userKeyField: true\n }\n });\n\n if (!model || !model.enableAuditTracking) {\n return;\n }\n\n const auditFields = model.fields.filter(field =>\n field.enableAuditTracking &&\n !['mediaSingle', 'mediaMultiple', 'richText', 'json'].includes(field.type) &&\n !(field.type === 'relation' && field.relationType === 'one-to-many')\n );\n\n const chatterMessage = new ChatterMessage();\n chatterMessage.messageType = CHATTER_MESSAGE_TYPE.AUDIT;\n chatterMessage.messageSubType = CHATTER_MESSAGE_SUBTYPE.AUDIT_INSERT;\n chatterMessage.status = CHATTER_MESSAGE_STATUS.PENDING;\n chatterMessage.coModelEntityId = entity.id;\n chatterMessage.coModelName = model?.singularName;\n chatterMessage.modelDisplayName = model?.displayName;\n chatterMessage.modelUserKey = entity[model?.userKeyField?.name];\n chatterMessage.messageBody = `New ${model?.displayName} created`;\n this.stampMessageAuditFields(chatterMessage, userId);\n\n const savedMessage = await this.repo.save(chatterMessage);\n\n for (const field of auditFields) {\n const fieldValue = entity[field.name];\n if (fieldValue !== undefined && fieldValue !== null && fieldValue !== '') {\n const messageDetail = new ChatterMessageDetails();\n messageDetail.chatterMessage = savedMessage;\n messageDetail.fieldName = field.name;\n messageDetail.fieldDisplayName = field.displayName;\n messageDetail.fieldType = field.type;\n messageDetail.oldValue = null;\n messageDetail.oldValueDisplay = null;\n messageDetail.newValue = this.formatFieldValue(field, fieldValue);\n messageDetail.newValueDisplay = await this.formatFieldValueDisplay(field, fieldValue);\n await this.chatterMessageDetailsRepo.save(messageDetail);\n }\n }\n }\n\n async postAuditMessageOnUpdate(entity: any, modelName: string, databaseEntity: any, updatedColumns: any[] = [], messageQueue: boolean = false, userId?: number | null) {\n if (!databaseEntity || !entity) {\n return;\n }\n const model = await this.modelMetadataRepo.findOne({\n where: {\n singularName: lowerFirst(modelName)\n },\n relations: {\n fields: true,\n module: true,\n userKeyField: true\n }\n });\n\n if (!model || !model.enableAuditTracking) {\n return;\n }\n\n const modelFields = await this.modelMetadataHelperService.loadFieldHierarchy(model.singularName)\n\n const auditFields = modelFields.filter(field =>\n field.enableAuditTracking &&\n !['mediaSingle', 'mediaMultiple', 'richText', 'json'].includes(field.type) &&\n !(field.type === 'relation' && field.relationType === 'one-to-many')\n );\n\n const updatedFieldNames = new Set(updatedColumns.map(col => col.propertyName));\n\n const allNonRelationFields = auditFields.filter(field => field.type !== 'relation');\n const allRelationFields = auditFields.filter(field => field.type === 'relation');\n\n let potentialNonRelationFields = [];\n\n if (updatedColumns.length > 0) {\n potentialNonRelationFields = allNonRelationFields.filter(field =>\n updatedFieldNames.has(field.name)\n );\n } else {\n potentialNonRelationFields = allNonRelationFields;\n }\n\n const potentialRelationFields = allRelationFields;\n\n const changedNonRelationFields = potentialNonRelationFields.filter(field => {\n const newValue = entity[field.name];\n const oldValue = databaseEntity[field.name];\n return this.hasValueChanged(newValue, oldValue);\n });\n\n const changedRelationFields = [];\n if (potentialRelationFields.length > 0) {\n const metadata = this.entityManager.connection.entityMetadatas.find(m => m.name === modelName);\n const populatedOldEntity = await this.populateRelationFields(databaseEntity, potentialRelationFields, metadata);\n\n for (const field of potentialRelationFields) {\n const newValue = entity[field.name];\n const oldValue = populatedOldEntity[field.name];\n\n if (this.hasRelationValueChanged(field, newValue, oldValue)) {\n changedRelationFields.push({\n field,\n newValue,\n oldValue\n });\n }\n }\n }\n\n const allChangedFields = [\n ...changedNonRelationFields.map(field => ({\n field,\n newValue: entity[field.name],\n oldValue: databaseEntity[field.name]\n })),\n ...changedRelationFields\n ];\n\n if (allChangedFields.length === 0) {\n return;\n }\n\n const chatterMessage = new ChatterMessage();\n chatterMessage.messageType = CHATTER_MESSAGE_TYPE.AUDIT;\n chatterMessage.messageSubType = CHATTER_MESSAGE_SUBTYPE.AUDIT_UPDATE;\n chatterMessage.status = CHATTER_MESSAGE_STATUS.PENDING;\n chatterMessage.coModelEntityId = entity?.id;\n chatterMessage.coModelName = model?.singularName;\n chatterMessage.modelDisplayName = model.displayName;\n chatterMessage.modelUserKey = entity[model?.userKeyField?.name];\n chatterMessage.messageBody = `${model?.displayName} updated`;\n this.stampMessageAuditFields(chatterMessage, userId);\n\n const savedMessage = await this.repo.save(chatterMessage);\n\n for (const { field, newValue, oldValue } of allChangedFields) {\n const messageDetail = new ChatterMessageDetails();\n messageDetail.chatterMessage = savedMessage;\n messageDetail.fieldName = field.name;\n messageDetail.fieldDisplayName = field.displayName;\n messageDetail.fieldType = field.type;\n messageDetail.oldValue = this.formatFieldValue(field, oldValue);\n messageDetail.newValue = this.formatFieldValue(field, newValue);\n messageDetail.oldValueDisplay = await this.formatFieldValueDisplay(field, oldValue);\n messageDetail.newValueDisplay = await this.formatFieldValueDisplay(field, newValue);\n await this.chatterMessageDetailsRepo.save(messageDetail);\n }\n }\n\n async postAuditMessageOnDelete(modelName: string, databaseEntity: any, messageQueue: boolean = false, userId?: number | null) {\n const model = await this.modelMetadataRepo.findOne({\n where: {\n singularName: lowerFirst(modelName)\n },\n relations: {\n module: true,\n userKeyField: true\n }\n });\n\n if (!model || !model.enableAuditTracking) {\n return;\n }\n\n const modelFields = await this.modelMetadataHelperService.loadFieldHierarchy(model.singularName);\n\n const auditFields = modelFields.filter(field =>\n field.enableAuditTracking &&\n !['mediaSingle', 'mediaMultiple', 'richText', 'json'].includes(field.type) &&\n !(field.type === 'relation' && field.relationType === 'one-to-many')\n );\n\n // Populate relation fields so display values (e.g. names) are resolvable.\n // The related entities themselves still exist in the DB after a delete.\n const relationFields = auditFields.filter(field => field.type === 'relation');\n const entityMetadata = this.entityManager.connection.entityMetadatas.find(m => m.name === modelName);\n const populatedEntity = relationFields.length > 0 && entityMetadata\n ? await this.populateRelationFields(databaseEntity, relationFields, entityMetadata)\n : { ...databaseEntity };\n\n const chatterMessage = new ChatterMessage();\n chatterMessage.messageType = CHATTER_MESSAGE_TYPE.AUDIT;\n chatterMessage.messageSubType = CHATTER_MESSAGE_SUBTYPE.AUDIT_DELETE;\n chatterMessage.status = CHATTER_MESSAGE_STATUS.PENDING;\n chatterMessage.coModelEntityId = databaseEntity?.id;\n chatterMessage.coModelName = model?.singularName;\n chatterMessage.modelDisplayName = model?.displayName;\n chatterMessage.modelUserKey = databaseEntity[model?.userKeyField?.name];\n chatterMessage.messageBody = `${model?.displayName} deleted`;\n\n this.stampMessageAuditFields(chatterMessage, userId);\n\n const savedMessage = await this.repo.save(chatterMessage);\n\n for (const field of auditFields) {\n const fieldValue = populatedEntity[field.name];\n if (fieldValue !== undefined && fieldValue !== null && fieldValue !== '') {\n const messageDetail = new ChatterMessageDetails();\n messageDetail.chatterMessage = savedMessage;\n messageDetail.fieldName = field.name;\n messageDetail.fieldDisplayName = field.displayName;\n messageDetail.fieldType = field.type;\n messageDetail.oldValue = this.formatFieldValue(field, fieldValue);\n messageDetail.oldValueDisplay = await this.formatFieldValueDisplay(field, fieldValue);\n messageDetail.newValue = null;\n messageDetail.newValueDisplay = null;\n await this.chatterMessageDetailsRepo.save(messageDetail);\n }\n }\n }\n\n private formatFieldValue(field: any, value: any): string {\n if (value === null || value === undefined) {\n return '';\n }\n\n if (field.type === 'selectionStatic' || field.type === 'selectionDynamic') {\n return `${value}`;\n }\n\n if (field.type === 'relation') {\n if (field.relationType === \"many-to-one\") {\n return value.id;\n }\n if (field.relationType === 'many-to-many') {\n return value.map(item => item.id).join(', ');\n }\n }\n\n if (value instanceof Date) {\n return serializeDate(value);\n }\n\n return value.toString();\n }\n\n private async formatFieldValueDisplay(field: any, value: any): Promise<string> {\n if (value === null || value === undefined) {\n return '';\n }\n\n if (field.type === 'selectionStatic' || field.type === 'selectionDynamic') {\n return `${value}`;\n }\n\n if (['date', 'datetime', 'time'].includes(field.type)) {\n return null;\n }\n\n if (field.type === 'relation') {\n if (field.relationType === \"many-to-one\") {\n if (value.name) {\n return value.name;\n }\n\n try {\n const relatedModel = await this.modelMetadataRepo.findOne({\n where: { singularName: field.relationCoModelSingularName || field.relation },\n relations: { userKeyField: true }\n });\n\n if (relatedModel && relatedModel.userKeyField) {\n const userKeyFieldName = relatedModel.userKeyField.name;\n return value[userKeyFieldName] ? value[userKeyFieldName].toString() : '';\n }\n\n if (value.id) {\n return value.id.toString();\n }\n } catch (error: any) {\n console.error('Error fetching related model metadata:', error);\n return value.id ? value.id.toString() : '';\n }\n }\n\n if (field.relationType === 'many-to-many') {\n return value.map(item => item.name).join(', ');\n }\n }\n\n return value.toString();\n }\n\n private hasValueChanged(newValue: any, oldValue: any): boolean {\n if (newValue === oldValue) {\n return false;\n }\n\n if (newValue === null && oldValue === null) {\n return false;\n }\n\n if (newValue === undefined && oldValue === undefined) {\n return false;\n }\n\n if (newValue && oldValue && typeof newValue === 'object' && typeof oldValue === 'object') {\n if (newValue.id !== undefined && oldValue.id !== undefined) {\n return newValue.id !== oldValue.id;\n }\n\n if (Array.isArray(newValue) && Array.isArray(oldValue)) {\n if (newValue.length !== oldValue.length) {\n return true;\n }\n const newIds = newValue.map(item => item.id || item).sort();\n const oldIds = oldValue.map(item => item.id || item).sort();\n return JSON.stringify(newIds) !== JSON.stringify(oldIds);\n }\n }\n\n if (Array.isArray(newValue) && Array.isArray(oldValue)) {\n return JSON.stringify(newValue) !== JSON.stringify(oldValue);\n }\n\n return true;\n }\n\n private hasRelationValueChanged(field: any, newValue: any, oldValue: any): boolean {\n if (newValue === oldValue) {\n return false;\n }\n\n if ((newValue === null || newValue === undefined) && (oldValue === null || oldValue === undefined)) {\n return false;\n }\n\n if (field.relationType === 'many-to-one') {\n const newId = this.extractRelationId(newValue);\n const oldId = this.extractRelationId(oldValue);\n return newId !== oldId;\n }\n\n if (field.relationType === 'many-to-many') {\n const newIds = this.extractRelationIds(newValue);\n const oldIds = this.extractRelationIds(oldValue);\n\n if (newIds.length !== oldIds.length) {\n return true;\n }\n\n newIds.sort();\n oldIds.sort();\n\n return JSON.stringify(newIds) !== JSON.stringify(oldIds);\n }\n\n return this.hasValueChanged(newValue, oldValue);\n }\n\n private extractRelationId(value: any): any {\n if (value === null || value === undefined) {\n return null;\n }\n\n if (typeof value === 'string' || typeof value === 'number') {\n return value;\n }\n\n if (typeof value === 'object' && value.id !== undefined) {\n return value.id;\n }\n\n return null;\n }\n\n private extractRelationIds(value: any): any[] {\n if (!Array.isArray(value)) {\n const id = this.extractRelationId(value);\n return id !== null ? [id] : [];\n }\n\n return value.map(item => this.extractRelationId(item)).filter(id => id !== null);\n }\n\n private async populateRelationFields(databaseEntity: any, relationFields: any[], metadata: EntityMetadata): Promise<any> {\n const populatedEntity = { ...databaseEntity };\n\n for (const field of relationFields) {\n const relationValue = databaseEntity[field.name];\n\n if (relationValue === null || relationValue === undefined) {\n populatedEntity[field.name] = relationValue;\n continue;\n }\n\n const relationMetadata = metadata.relations.find(rel => rel.propertyName === field.name);\n if (!relationMetadata) {\n populatedEntity[field.name] = relationValue;\n continue;\n }\n\n const targetEntity = relationMetadata.inverseEntityMetadata || relationMetadata.type;\n\n if (field.relationType === 'many-to-one') {\n const relationId = this.extractRelationId(relationValue);\n if (relationId) {\n const relatedEntity = await this.entityManager.findOne(targetEntity as any, {\n where: { id: relationId }\n });\n populatedEntity[field.name] = relatedEntity;\n } else {\n populatedEntity[field.name] = relationValue;\n }\n } else if (field.relationType === 'many-to-many' || field.relationType === 'manyToMany') {\n const relationIds = this.extractRelationIds(relationValue);\n if (relationIds.length > 0) {\n const relatedEntities = await this.entityManager.findByIds(targetEntity as any, relationIds);\n populatedEntity[field.name] = relatedEntities;\n } else {\n populatedEntity[field.name] = relationValue;\n }\n } else {\n populatedEntity[field.name] = relationValue;\n }\n }\n\n return populatedEntity;\n }\n\n private logHeapUsed(label: string) {\n const mb = () => Math.round(process.memoryUsage().heapUsed / 1024 / 1024);\n this._logger.log(`heapUsedMB(${label}): ${mb()}`);\n }\n\n // [2026-02-05T23:31:21.025Z] INFO: [200 OK] \n // GET /api/chatter-message/getChatterMessages/216/mswipeBoomboxBulkUpload?populateMedia[0]=messageAttachments&populate[0]=user&populate[1]=chatterMessageDetails&limit=25 22747ms\n async getChatterMessages(entityId: number, entityName: string, query: any) {\n const { limit = 25, offset = 0, populate = [], populateMedia = [], filters } = query;\n this.logHeapUsed('getChatterMessages-start');\n\n await this.assertRecordAccess(lowerFirst(entityName), entityId);\n\n const model = await this.modelMetadataRepo.findOne({\n where: {\n singularName: entityName\n },\n });\n this.logHeapUsed('getChatterMessages-modelLoaded');\n const oneToManyFields = await this.fieldMetadataRepo.find({\n where: {\n model: { id: model.id },\n type: 'relation',\n relationType: 'one-to-many'\n }\n });\n this.logHeapUsed('getChatterMessages-oneToManyFieldsLoaded');\n\n const relatedEntitiesMap = new Map<string, number[]>();\n\n for (const field of oneToManyFields) {\n if (field.enableAuditTracking === false) {\n this._logger.log(`Skipping field ${field.name} for chatter message retrieval because audit tracking is disabled`);\n continue\n }\n const coModelName = field.relationCoModelSingularName;\n const coModelFieldName = field.relationCoModelFieldName;\n\n const coModel = await this.modelMetadataRepo.findOne({\n where: { singularName: coModelName }\n });\n\n if (coModel) {\n //const relatedEntityRepository = this.entityManager.getRepository(classify(coModelName));\n const dsName = coModel.dataSource || 'default';\n const em = dsName === 'default' ? this.entityManager : this.moduleRef.get(`${dsName}EntityManager`, { strict: false });\n\n const relatedEntityRepository = em.getRepository(classify(coModelName));\n\n const relatedEntities = await relatedEntityRepository.find({\n select: {\n id: true,\n },\n where: { [coModelFieldName]: { id: entityId } },\n take: 5,\n });\n\n const relatedIds = relatedEntities.map((entity: any) => entity.id);\n relatedEntitiesMap.set(field.name, relatedIds);\n }\n }\n this.logHeapUsed('getChatterMessages-relatedEntitiesLoaded');\n\n const qb = await this.repo.createSecurityRuleAwareQueryBuilder('entity');\n this.logHeapUsed('getChatterMessages-queryBuilderReady');\n\n const orConditions: string[] = [];\n const parameters: any = {};\n\n orConditions.push('(entity.coModelName = :entityName AND entity.coModelEntityId = :entityId)');\n parameters.entityName = entityName;\n parameters.entityId = entityId;\n\n let paramIndex = 0;\n for (const [fieldName, relatedIds] of relatedEntitiesMap.entries()) {\n if (relatedIds.length > 0) {\n const field = oneToManyFields.find(f => f.name === fieldName);\n if (field) {\n const coModelName = field.relationCoModelSingularName;\n const idsParamName = `relatedIds${paramIndex}`;\n orConditions.push(`(entity.coModelName = :coModelName${paramIndex} AND entity.coModelEntityId IN (:...${idsParamName}))`);\n parameters[`coModelName${paramIndex}`] = coModelName;\n parameters[idsParamName] = relatedIds;\n paramIndex++;\n }\n }\n }\n\n // SECURITY: must be andWhere. `where()` REPLACES every previously registered condition,\n // which would discard the row-level security rules applied by\n // createSecurityRuleAwareQueryBuilder above. (The inner `where` is safe: it is the first\n // condition on a fresh Brackets sub-builder.)\n qb.andWhere(new Brackets(qb => {\n qb.where(orConditions.join(' OR '), parameters);\n }));\n\n const relations = ['chatterMessageDetails'];\n if (populate && populate.length > 0) {\n const normalizedPopulate = this.crudHelperService.normalize(populate);\n // SECURITY: 'user' is joined below with an explicit column allowlist. A client-supplied\n // populate[]=user must not be able to turn it back into a full-entity join (the chatter\n // panel does send exactly that).\n relations.push(...normalizedPopulate.filter(rel => rel !== 'user' && !relations.includes(rel)));\n }\n\n relations.forEach(relation => {\n qb.leftJoinAndSelect(`entity.${relation}`, relation);\n });\n\n // Only the author's id and display name leave this endpoint - see CHATTER_MESSAGE_USER_FIELDS.\n // This join must stay before applyFilters below: it lets filters[user][fullName] reuse this\n // alias instead of adding a second join of its own.\n qb.leftJoin('entity.user', 'user');\n qb.addSelect(CHATTER_MESSAGE_USER_FIELDS.map(field => `user.${field}`));\n\n if (filters) {\n qb.andWhere(new Brackets(whereQb => {\n this.crudHelperService.applyFilters(whereQb, filters, 'entity', qb);\n }));\n }\n\n qb.orderBy('entity.createdAt', 'DESC');\n\n qb.skip(offset).take(limit);\n\n const [entities, count] = await qb.getManyAndCount();\n this.logHeapUsed('getChatterMessages-entitiesLoaded');\n\n // The join above only selects the allowlisted columns, but TypeORM still hydrates the\n // author with `new User()`, which leaves every initialiser-backed property (active,\n // forcePasswordChange, ...) sitting on the instance holding its default rather than a\n // value read from the database. Replace it with a plain object of exactly the\n // allowlisted keys so the response cannot report fabricated defaults as data.\n this.trimMessageUsers(entities);\n\n // Convert date strings in message details to ISO format for consistent handling on the frontend\n const DATE_FIELD_TYPES = ['date', 'datetime', 'time'];\n for (const entity of entities) {\n for (const detail of entity.chatterMessageDetails ?? []) {\n if (!detail.fieldType || !DATE_FIELD_TYPES.includes(detail.fieldType)) continue;\n if (detail.oldValue) {\n const d = LocalDateTimeTransformer.from(detail.oldValue);\n if (d) detail.oldValue = d.toISOString();\n }\n if (detail.newValue) {\n const d = LocalDateTimeTransformer.from(detail.newValue);\n if (d) detail.newValue = d.toISOString();\n }\n }\n }\n\n if (populateMedia && populateMedia.length > 0) {\n const normalizedPopulateMedia = this.crudHelperService.normalize(populateMedia);\n this.logHeapUsed('getChatterMessages-beforePopulateMedia');\n await this['handlePopulateMedia'](normalizedPopulateMedia, entities);\n this.logHeapUsed('getChatterMessages-afterPopulateMedia');\n }\n\n const currentPage = Math.floor(offset / limit) + 1;\n const totalPages = Math.ceil(count / limit);\n const nextPage = currentPage < totalPages ? currentPage + 1 : null;\n const prevPage = currentPage > 1 ? currentPage - 1 : null;\n\n return {\n meta: {\n totalRecords: count,\n currentPage: currentPage,\n nextPage: nextPage,\n prevPage: prevPage,\n totalPages: totalPages,\n perPage: +limit,\n },\n records: entities\n };\n }\n}\n"]}
|
|
@@ -77,7 +77,6 @@ export declare class CrudHelperService {
|
|
|
77
77
|
groupName: string;
|
|
78
78
|
groupValue: any;
|
|
79
79
|
};
|
|
80
|
-
countGroupedRecords(qb: SelectQueryBuilder<any>, basicFilterDto: BasicFilterDto, entityAlias: string): Promise<number>;
|
|
81
80
|
hasReadPermissionOnModel: (activeUser: ActiveUserData, modelName: string) => boolean;
|
|
82
81
|
hasWritePermissionOnModel: (activeUser: ActiveUserData, modelName: string) => boolean;
|
|
83
82
|
hasUpdatePermissionOnModel: (activeUser: ActiveUserData, modelName: string) => boolean;
|
|
@@ -97,7 +96,7 @@ export declare class CrudHelperService {
|
|
|
97
96
|
};
|
|
98
97
|
records: T[];
|
|
99
98
|
};
|
|
100
|
-
executeGroupPipeline<T>(filterQb: SelectQueryBuilder<T>, basicFilterDto: BasicFilterDto, alias: string, createQbFn: () => Promise<SelectQueryBuilder<T>>, postProcessEntities?: (entities: T[]) => Promise<void
|
|
99
|
+
executeGroupPipeline<T>(filterQb: SelectQueryBuilder<T>, basicFilterDto: BasicFilterDto, alias: string, createQbFn: () => Promise<SelectQueryBuilder<T>>, postProcessEntities?: (entities: T[]) => Promise<void>, internationalisation?: boolean, draftPublishWorkflow?: boolean, moduleRef?: any): Promise<{
|
|
101
100
|
meta: {
|
|
102
101
|
totalRecords: number;
|
|
103
102
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"crud-helper.service.d.ts","sourceRoot":"","sources":["../../src/services/crud-helper.service.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"crud-helper.service.d.ts","sourceRoot":"","sources":["../../src/services/crud-helper.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -728,20 +728,6 @@ let CrudHelperService = CrudHelperService_1 = class CrudHelperService {
|
|
|
728
728
|
...groupAggregateValues
|
|
729
729
|
};
|
|
730
730
|
}
|
|
731
|
-
async countGroupedRecords(qb, basicFilterDto, entityAlias) {
|
|
732
|
-
const { limit, offset, ...rest } = basicFilterDto;
|
|
733
|
-
const filteredDto = { ...rest, limit: undefined, offset: undefined };
|
|
734
|
-
const filteredQB = this.buildFilterQuery(qb, filteredDto, entityAlias, undefined, undefined, undefined, FilterCombinator.AND, false, false);
|
|
735
|
-
const groupByFields = this.normalize(filteredDto.groupBy);
|
|
736
|
-
if (!groupByFields || groupByFields.length === 0) {
|
|
737
|
-
throw new Error(error_messages_1.ERROR_MESSAGES.INVALID_GROUP_BY_COUNT);
|
|
738
|
-
}
|
|
739
|
-
this.applyGroupBySelections(filteredQB, groupByFields, entityAlias);
|
|
740
|
-
this.applyAggregates(filteredQB, ['count'], entityAlias);
|
|
741
|
-
filteredQB.limit(undefined).offset(undefined).take(undefined).skip(undefined);
|
|
742
|
-
const rawResults = await filteredQB.getRawMany();
|
|
743
|
-
return rawResults.length;
|
|
744
|
-
}
|
|
745
731
|
pagedResponse(offset, limit, count, entities) {
|
|
746
732
|
const safeLimit = limit ?? count ?? 0;
|
|
747
733
|
const safeOffset = offset ?? 0;
|
|
@@ -761,7 +747,7 @@ let CrudHelperService = CrudHelperService_1 = class CrudHelperService {
|
|
|
761
747
|
records: entities,
|
|
762
748
|
};
|
|
763
749
|
}
|
|
764
|
-
async executeGroupPipeline(filterQb, basicFilterDto, alias, createQbFn, postProcessEntities) {
|
|
750
|
+
async executeGroupPipeline(filterQb, basicFilterDto, alias, createQbFn, postProcessEntities, internationalisation, draftPublishWorkflow, moduleRef) {
|
|
765
751
|
const groupByFields = this.normalize(basicFilterDto.groupBy);
|
|
766
752
|
if (!groupByFields.length)
|
|
767
753
|
throw new common_1.BadRequestException(error_messages_1.ERROR_MESSAGES.INVALID_GROUP_BY_COUNT);
|
|
@@ -790,7 +776,7 @@ let CrudHelperService = CrudHelperService_1 = class CrudHelperService {
|
|
|
790
776
|
aggregates: undefined,
|
|
791
777
|
sort: basicFilterDto.groupFilter?.sort,
|
|
792
778
|
};
|
|
793
|
-
groupQb = this.buildFilterQuery(groupQb, groupFilterDto, alias);
|
|
779
|
+
groupQb = this.buildFilterQuery(groupQb, groupFilterDto, alias, internationalisation, draftPublishWorkflow, moduleRef);
|
|
794
780
|
groupQb = this.buildGroupByRecordsQuery(groupQb, group, alias, groupAliasMap, aggregateAliasMap, groupExpressionMap);
|
|
795
781
|
const [entities, count] = await groupQb.getManyAndCount();
|
|
796
782
|
if (postProcessEntities)
|