mirror of
https://github.com/hexastack/hexabot
synced 2025-06-26 18:27:28 +00:00
Merge pull request #1135 from Hexastack/1134-issue---api-make-sure-hookentityprepostupdate-is-used-across-the-board
fix(api): resolve predefined update hooks bug
This commit is contained in:
commit
c5abe12971
@ -228,4 +228,33 @@ describe('NlpEntityRepository', () => {
|
|||||||
expect(nlpEntity).toEqualPayload(result);
|
expect(nlpEntity).toEqualPayload(result);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('postUpdate', () => {
|
||||||
|
it('should update an NlpEntity and trigger a postUpdate event', async () => {
|
||||||
|
jest.spyOn(nlpService, 'handleEntityPostUpdate');
|
||||||
|
jest.spyOn(llmNluHelper, 'updateEntity');
|
||||||
|
|
||||||
|
nlpEntityRepository.eventEmitter.once(
|
||||||
|
'hook:nlpEntity:postUpdate',
|
||||||
|
async (...[query, updated]) => {
|
||||||
|
await nlpService.handleEntityPostUpdate(query, updated);
|
||||||
|
expect(llmNluHelper.updateEntity).toHaveBeenCalledWith(updated);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const updatedNlpEntity = await nlpEntityRepository.updateOne(
|
||||||
|
{
|
||||||
|
name: 'test2',
|
||||||
|
},
|
||||||
|
{ value: 'test3' },
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(nlpService.handleEntityPostUpdate).toHaveBeenCalledTimes(1);
|
||||||
|
expect(llmNluHelper.updateEntity).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
|
const result = await nlpEntityRepository.findOne(updatedNlpEntity.id);
|
||||||
|
|
||||||
|
expect(result).toEqualPayload(updatedNlpEntity);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { InjectModel } from '@nestjs/mongoose';
|
import { InjectModel } from '@nestjs/mongoose';
|
||||||
import { Document, Model, Query } from 'mongoose';
|
import { Model } from 'mongoose';
|
||||||
|
|
||||||
import { BaseRepository } from '@/utils/generics/base-repository';
|
import { BaseRepository } from '@/utils/generics/base-repository';
|
||||||
|
|
||||||
@ -30,28 +30,4 @@ export class NlpEntityRepository extends BaseRepository<
|
|||||||
constructor(@InjectModel(NlpEntity.name) readonly model: Model<NlpEntity>) {
|
constructor(@InjectModel(NlpEntity.name) readonly model: Model<NlpEntity>) {
|
||||||
super(model, NlpEntity, NLP_ENTITY_POPULATE, NlpEntityFull);
|
super(model, NlpEntity, NLP_ENTITY_POPULATE, NlpEntityFull);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Post-update hook that triggers after an NLP entity is updated.
|
|
||||||
* Emits an event to notify other parts of the system about the update.
|
|
||||||
* Bypasses built-in entities.
|
|
||||||
*
|
|
||||||
* @param query - The query used to find and update the entity.
|
|
||||||
* @param updated - The updated NLP entity document.
|
|
||||||
*/
|
|
||||||
async postUpdate(
|
|
||||||
_query: Query<
|
|
||||||
Document<NlpEntity, any, any>,
|
|
||||||
Document<NlpEntity, any, any>,
|
|
||||||
unknown,
|
|
||||||
NlpEntity,
|
|
||||||
'findOneAndUpdate'
|
|
||||||
>,
|
|
||||||
updated: NlpEntity,
|
|
||||||
): Promise<void> {
|
|
||||||
if (!updated?.builtin) {
|
|
||||||
// Bypass builtin entities (probably fixtures)
|
|
||||||
this.eventEmitter.emit('hook:nlpEntity:update', updated);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -250,4 +250,34 @@ describe('NlpValueRepository', () => {
|
|||||||
expect(nlpValue).toEqualPayload(result);
|
expect(nlpValue).toEqualPayload(result);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('postUpdate', () => {
|
||||||
|
it('should update an NlpValue and trigger a postUpdate event', async () => {
|
||||||
|
jest.spyOn(nlpService, 'handleValuePostUpdate');
|
||||||
|
jest.spyOn(llmNluHelper, 'updateValue');
|
||||||
|
|
||||||
|
nlpValueRepository.eventEmitter.once(
|
||||||
|
'hook:nlpValue:postUpdate',
|
||||||
|
async (...[query, updated]) => {
|
||||||
|
await nlpService.handleValuePostUpdate(query, updated);
|
||||||
|
|
||||||
|
expect(llmNluHelper.updateValue).toHaveBeenCalledWith(updated);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const updatedNlpValue = await nlpValueRepository.updateOne(
|
||||||
|
{
|
||||||
|
value: 'test',
|
||||||
|
},
|
||||||
|
{ value: 'test2' },
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(nlpService.handleValuePostUpdate).toHaveBeenCalledTimes(1);
|
||||||
|
expect(llmNluHelper.updateValue).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
|
const result = await nlpValueRepository.findOne(updatedNlpValue.id);
|
||||||
|
|
||||||
|
expect(result).toEqualPayload(updatedNlpValue);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -9,14 +9,7 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { InjectModel } from '@nestjs/mongoose';
|
import { InjectModel } from '@nestjs/mongoose';
|
||||||
import { plainToInstance } from 'class-transformer';
|
import { plainToInstance } from 'class-transformer';
|
||||||
import {
|
import { Model, PipelineStage, SortOrder, Types } from 'mongoose';
|
||||||
Document,
|
|
||||||
Model,
|
|
||||||
PipelineStage,
|
|
||||||
Query,
|
|
||||||
SortOrder,
|
|
||||||
Types,
|
|
||||||
} from 'mongoose';
|
|
||||||
|
|
||||||
import { BaseRepository } from '@/utils/generics/base-repository';
|
import { BaseRepository } from '@/utils/generics/base-repository';
|
||||||
import { PageQueryDto } from '@/utils/pagination/pagination-query.dto';
|
import { PageQueryDto } from '@/utils/pagination/pagination-query.dto';
|
||||||
@ -45,28 +38,6 @@ export class NlpValueRepository extends BaseRepository<
|
|||||||
super(model, NlpValue, NLP_VALUE_POPULATE, NlpValueFull);
|
super(model, NlpValue, NLP_VALUE_POPULATE, NlpValueFull);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Emits an event after an NLP value is updated, bypassing built-in values.
|
|
||||||
*
|
|
||||||
* @param query - The query that was used to update the NLP value.
|
|
||||||
* @param updated - The updated NLP value document.
|
|
||||||
*/
|
|
||||||
async postUpdate(
|
|
||||||
_query: Query<
|
|
||||||
Document<NlpValue, any, any>,
|
|
||||||
Document<NlpValue, any, any>,
|
|
||||||
unknown,
|
|
||||||
NlpValue,
|
|
||||||
'findOneAndUpdate'
|
|
||||||
>,
|
|
||||||
updated: NlpValue,
|
|
||||||
): Promise<void> {
|
|
||||||
if (!updated?.builtin) {
|
|
||||||
// Bypass builtin entities (probably fixtures)
|
|
||||||
this.eventEmitter.emit('hook:nlpValue:update', updated);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private getSortDirection(sortOrder: SortOrder) {
|
private getSortDirection(sortOrder: SortOrder) {
|
||||||
return typeof sortOrder === 'number'
|
return typeof sortOrder === 'number'
|
||||||
? sortOrder
|
? sortOrder
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
import { Injectable, NotFoundException } from '@nestjs/common';
|
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||||
import { OnEvent } from '@nestjs/event-emitter';
|
import { OnEvent } from '@nestjs/event-emitter';
|
||||||
|
import { Document, Query } from 'mongoose';
|
||||||
|
|
||||||
import { HelperService } from '@/helper/helper.service';
|
import { HelperService } from '@/helper/helper.service';
|
||||||
import { HelperType, NLU } from '@/helper/types';
|
import { HelperType, NLU } from '@/helper/types';
|
||||||
@ -96,15 +97,28 @@ export class NlpService {
|
|||||||
*
|
*
|
||||||
* @param entity - The NLP entity to be updated.
|
* @param entity - The NLP entity to be updated.
|
||||||
*/
|
*/
|
||||||
@OnEvent('hook:nlpEntity:update')
|
@OnEvent('hook:nlpEntity:postUpdate')
|
||||||
async handleEntityUpdate(entity: NlpEntity) {
|
async handleEntityPostUpdate(
|
||||||
// Synchonize new entity with NLP provider
|
_query: Query<
|
||||||
try {
|
Document<NlpEntity>,
|
||||||
const helper = await this.helperService.getDefaultNluHelper();
|
Document<NlpEntity>,
|
||||||
await helper.updateEntity(entity);
|
unknown,
|
||||||
this.logger.debug('Updated entity successfully synced!', entity);
|
NlpEntity,
|
||||||
} catch (err) {
|
'findOneAndUpdate'
|
||||||
this.logger.error('Unable to sync updated entity', err);
|
>,
|
||||||
|
updated: NlpEntity,
|
||||||
|
) {
|
||||||
|
if (!updated?.builtin) {
|
||||||
|
// Synchonize new entity with NLP provider
|
||||||
|
try {
|
||||||
|
const helper = await this.helperService.getDefaultHelper(
|
||||||
|
HelperType.NLU,
|
||||||
|
);
|
||||||
|
await helper.updateEntity(updated);
|
||||||
|
this.logger.debug('Updated entity successfully synced!', updated);
|
||||||
|
} catch (err) {
|
||||||
|
this.logger.error('Unable to sync updated entity', err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,15 +194,28 @@ export class NlpService {
|
|||||||
*
|
*
|
||||||
* @param value - The NLP value to be updated.
|
* @param value - The NLP value to be updated.
|
||||||
*/
|
*/
|
||||||
@OnEvent('hook:nlpValue:update')
|
@OnEvent('hook:nlpValue:postUpdate')
|
||||||
async handleValueUpdate(value: NlpValue) {
|
async handleValuePostUpdate(
|
||||||
// Synchonize new value with NLP provider
|
_query: Query<
|
||||||
try {
|
Document<NlpValue, any, any>,
|
||||||
const helper = await this.helperService.getDefaultNluHelper();
|
Document<NlpValue, any, any>,
|
||||||
await helper.updateValue(value);
|
unknown,
|
||||||
this.logger.debug('Updated value successfully synced!', value);
|
NlpValue,
|
||||||
} catch (err) {
|
'findOneAndUpdate'
|
||||||
this.logger.error('Unable to sync updated value', err);
|
>,
|
||||||
|
updated: NlpValue,
|
||||||
|
) {
|
||||||
|
if (!updated?.builtin) {
|
||||||
|
// Synchonize new value with NLP provider
|
||||||
|
try {
|
||||||
|
const helper = await this.helperService.getDefaultHelper(
|
||||||
|
HelperType.NLU,
|
||||||
|
);
|
||||||
|
await helper.updateValue(updated);
|
||||||
|
this.logger.debug('Updated value successfully synced!', updated);
|
||||||
|
} catch (err) {
|
||||||
|
this.logger.error('Unable to sync updated value', err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
7
api/types/event-emitter.d.ts
vendored
7
api/types/event-emitter.d.ts
vendored
@ -132,10 +132,10 @@ declare module '@nestjs/event-emitter' {
|
|||||||
menu: TDefinition<Menu>;
|
menu: TDefinition<Menu>;
|
||||||
language: TDefinition<Language>;
|
language: TDefinition<Language>;
|
||||||
translation: TDefinition<Translation>;
|
translation: TDefinition<Translation>;
|
||||||
nlpEntity: TDefinition<NlpEntity, { update: NlpEntity }>;
|
nlpEntity: TDefinition<NlpEntity>;
|
||||||
nlpSampleEntity: TDefinition<NlpSampleEntity>;
|
nlpSampleEntity: TDefinition<NlpSampleEntity>;
|
||||||
nlpSample: TDefinition<NlpSample>;
|
nlpSample: TDefinition<NlpSample>;
|
||||||
nlpValue: TDefinition<NlpValue, { update: NlpValue }>;
|
nlpValue: TDefinition<NlpValue>;
|
||||||
setting: TDefinition<Setting>;
|
setting: TDefinition<Setting>;
|
||||||
invitation: TDefinition<Invitation>;
|
invitation: TDefinition<Invitation>;
|
||||||
model: TDefinition<Model>;
|
model: TDefinition<Model>;
|
||||||
@ -189,7 +189,8 @@ declare module '@nestjs/event-emitter' {
|
|||||||
|
|
||||||
type TPostUpdateValidate<T> = FilterQuery<T>;
|
type TPostUpdateValidate<T> = FilterQuery<T>;
|
||||||
|
|
||||||
type TPostUpdate<T> = THydratedDocument<T>;
|
// TODO this type will be optimized soon in a separated PR
|
||||||
|
type TPostUpdate<T> = T & any;
|
||||||
|
|
||||||
type TPostDelete = DeleteResult;
|
type TPostDelete = DeleteResult;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user