load.reviewCarregar Revisão de Resultado
Evento WebSocket para carregar o histórico de mensagens de uma revisão de resultado de laboratório. O cliente emite este evento com o UUID do resultado da integração e o ID da revisão. O servidor busca a revisão no banco de dados, valida permissões e status, busca o histórico de mensagens no OpenAI via threadId e propaga os dados para todos os clientes conectados da mesma conta via broadcast. Este evento retorna uma resposta imediata via callback (status: true ou false) apenas para tratamento de erros. Os dados reais (thread com histórico de mensagens) são enviados via evento separado 'load.thread' para todos os clientes da mesma conta, garantindo sincronização automática entre componentes.
Access Token
Para realizar requisições GET, POST, PUT, DELETE e PATCH nos endpoints da API você precisa de uma chave de autorização. Chamamos essa chave de accessToken.
Para ter acesso ao accessToken, é necessário que o usuário master da licença efetue a liberação deste pela interface do ImageMais Clinic. O accessToken tem validade de 1 hora.
Headers
| Nome | Tipo | Obrig. | Descrição |
|---|---|---|---|
Authorization | string | Sim | Token de autenticação no formato Bearer {accessToken}. O token deve ser enviado durante o handshake de conexão WebSocket. |
AuthorizationOBRIGATÓRIOParâmetros
| Nome | Tipo | Obrig. | Descrição |
|---|---|---|---|
resultsIntegrationUuid | string | Sim | UUID do resultado da integração de laboratório |
UUID do resultado da integração de laboratório. É um identificador único que identifica um resultado específico de integração no sistema. Para encontrar o UUID do resultado da integração, para acessar a página de listar todos os pedidos do laboratório. O UUID está disponível no campo | |||
reviewId | number | Sim | ID da revisão a ser carregada |
ID da revisão a ser carregada. É um identificador numérico único que identifica uma revisão específica de um resultado no sistema. Para encontrar o ID da revisão, primeiro você precisa do UUID do resultado da integração (obtido através da rota de listar pedidos). Com o UUID, para acessar a página de listar todos os históricos de revisão. O ID da revisão está disponível no campo | |||
resultsIntegrationUuidOBRIGATÓRIOUUID do resultado da integração de laboratório. É um identificador único que identifica um resultado específico de integração no sistema.
Para encontrar o UUID do resultado da integração, para acessar a página de listar todos os pedidos do laboratório. O UUID está disponível no campo resultsIntegration.uuid da resposta.
reviewIdOBRIGATÓRIOID da revisão a ser carregada. É um identificador numérico único que identifica uma revisão específica de um resultado no sistema.
Para encontrar o ID da revisão, primeiro você precisa do UUID do resultado da integração (obtido através da rota de listar pedidos). Com o UUID, para acessar a página de listar todos os históricos de revisão. O ID da revisão está disponível no campo id de cada item retornado pela rota.
Fluxo passo a passo: load.review
Cliente emite a requisição via WebSocket com callback
O frontend emite o evento 'load.review' com o UUID do resultado e o ID da revisão:
// page.tsx
socket.emit(
'load.review',
{
resultsIntegrationUuid: uuid,
reviewId: reviewId,
},
(response: any) => {
// Callback apenas para tratar erros
if (!response.status) {
setHistory(undefined);
setError(response.error);
}
}
);Servidor busca revisão no banco de dados
No backend (NestJS + Gateway), o servidor busca a revisão com validações de permissão e status:
// accounts.gateways.ts
@SubscribeMessage('load.review')
async handleLoadReview(
@ConnectedSocket() client: Socket,
@MessageBody() data: {
resultsIntegrationUuid: string;
reviewId: number;
},
) {
try {
const payload = client.data.payload as PayloadTokenDto;
// Busca revisão e histórico de mensagens
const thread = await this.laboratoriesService.findOneReview(
data.resultsIntegrationUuid,
data.reviewId,
payload,
);
// ... continua no próximo passo
} catch (e) {
// ... tratamento de erro
}
}Serviço valida revisão e busca histórico no OpenAI
O serviço busca a revisão no banco com validações e depois busca o histórico no OpenAI:
// laboratories.service.ts
async findOneReview(
resultsIntegrationUuid: string,
reviewId: number,
payload: PayloadTokenDto,
) {
// Busca revisão no banco com validações
const review = await this.prisma.resultsReview.findFirst({
where: {
id: reviewId,
resultsIntegration: {
uuid: resultsIntegrationUuid,
deletedAt: null, // Não deletado
order: {
accountId: payload.accountId, // Mesma conta
},
statusReview: {
name: {
in: [StatusReview.ANALYZING, StatusReview.SENT], // Status válido
},
},
},
},
select: {
id: true,
threadId: true, // ID do thread no OpenAI
createdAt: true,
updatedAt: true,
},
});
if (!review) {
throw new NotFoundException('Revisão não encontrada');
}
try {
// Busca histórico de mensagens no OpenAI via threadId
const messages = await this.openAiService.findHistory(
review.threadId,
);
// Filtra mensagens ocultas
return {
id: review.id,
messages: messages.filter(
(message) => message.metadata.hidden !== 'true',
),
createdAt: review.createdAt,
updatedAt: review.updatedAt,
};
} catch (e) {
throw new InternalServerErrorException('Erro ao buscar histórico');
}
}Servidor propaga thread via broadcast
O Gateway propaga o thread com histórico de mensagens para todos os clientes da mesma conta:
// accounts.gateways.ts - Continuação do handleLoadReview
// Propaga thread para todos os clientes da mesma conta
await this.notifyOnEvent('load.thread', thread, payload);
// Retorna sucesso via callback
return {
status: true,
};Servidor propaga evento 'load.thread' para todos da conta
O método `notifyOnEvent` envia o evento 'load.thread' para todos os sockets da mesma accountId:
async notifyOnEvent(
event: string,
data: any,
payload: PayloadTokenDto,
): Promise<any> {
if (this._events.includes(event)) {
// Envia para todos os clientes da mesma conta
this.server
.to(`${this.room}${payload.accountId}`)
.emit(event, data);
}
}
// this.room = 'orders.account.'
// Todos os clientes conectados da mesma accountId recebem o evento 'load.thread'Servidor trata erros e retorna via callback
Se houver erro durante o processamento, o servidor retorna via callback:
// accounts.gateways.ts - Continuação do handleLoadReview
} catch (e) {
const { message } = e as Error;
this.logger.debug(message);
return {
status: false,
error: message,
};
}Cliente processa resposta de erro no callback
No frontend, o callback processa apenas erros (dados reais vêm via evento separado):
// page.tsx - Callback do socket.emit
(response: any) => {
// Trata apenas erros
if (!response.status) {
setHistory(undefined);
setError(response.error);
}
// Se status === true, aguarda evento 'load.thread' para receber dados
}Cliente recebe thread via evento 'load.thread'
Todos os clientes conectados da mesma conta recebem o evento 'load.thread' e atualizam o estado:
// page.tsx
socket.on('load.thread', (data: Thread) => {
// Atualiza estado com histórico de mensagens
setHistory(data);
// Limpa erros
setError(undefined);
});
// Remove listener ao desmontar
useEffect(() => {
return () => {
socket.off('load.thread');
};
}, []);Request URL
ws://api-dev.imagemais.com{
"resultsIntegrationUuid": "550e8400-e29b-41d4-a716-446655440000",
"reviewId": 123
...{
"resultsIntegrationUuid": "550e8400-e29b-41d4-a716-446655440000",
"reviewId": 123
}Respostas
{
"status": true
}{
"status": true
}{
"status": false,
"error": "Revisão não encontrada"
...{
"status": false,
"error": "Revisão não encontrada"
}