valiation.labelValidar Etiqueta do Pedido
Evento WebSocket para validar dados de integração de um pedido antes de gerar etiquetas. O cliente emite este evento com o ID do pedido e o token JWT. Um Pipe intercepta a requisição antes do handler, valida o token, busca o pedido e as integrações relacionadas aos procedimentos. O handler retorna as integrações completas com todos os campos disponíveis. Este evento é usado quando o pedido está em status IN_PROGRESS para permitir que o usuário valide e ajuste os dados dos procedimentos antes de criar as etiquetas. O frontend abre um modal interativo com os dados de integração para validação.
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 |
|---|---|---|---|
orderId | number | Sim | ID do pedido para validar etiquetas |
ID do pedido para operações relacionadas às etiquetas. É um identificador numérico único que identifica um pedido específico no sistema. Para encontrar o ID do pedido, para acessar a página de listar todos os pedidos do laboratório. | |||
token | string | Sim | Token JWT do usuário para validação e autenticação |
orderIdOBRIGATÓRIOID do pedido para operações relacionadas às etiquetas. É um identificador numérico único que identifica um pedido específico no sistema.
Para encontrar o ID do pedido, para acessar a página de listar todos os pedidos do laboratório.
tokenOBRIGATÓRIOFluxo passo a passo: valiation.label
Cliente emite a requisição via WebSocket com callback
O frontend emite o evento 'valiation.label' com o ID do pedido e o token JWT:
// FinishOrder.tsx
async function handleValidations(order: Order) {
socket?.emit(
'valiation.label',
{ orderId: order.id, token },
(response: ValiditionsResponseWs) => {
if (response.status === 'receive') {
// Abre modal de validação com as integrações
openModal(
<Validation
order={order}
integrations={response.integrations}
/>
);
}
}
);
}Pipe intercepta e transforma os dados
O Pipe ProceduresRequiredPipe intercepta a requisição antes do handler, valida o token, busca o pedido e as integrações:
// procedures-required.pipe.ts
async transform({
orderId,
fields,
token,
}: {
orderId: number;
fields: CamposAdicionais;
token: string;
}): Promise<any> {
try {
// Valida e decodifica o token JWT
const payload = await this.jwtService.verifyAsync(token, {
secret: this.jwtConfiguration.access.secret,
audience: this.jwtConfiguration.access.audience,
issuer: this.jwtConfiguration.access.issuer,
});
// Valida orderId
if (orderId === undefined || orderId === null) {
throw new WsException('orderId is required');
}
const parsedOrderId = Number(orderId);
if (isNaN(parsedOrderId)) {
throw new WsException('orderId must be a valid number');
}
// Busca o pedido completo
const order = await this.ordersService.findById(
parsedOrderId,
payload,
);
// Extrai IDs dos procedimentos do pedido
const procedureIds = order.patientExams.procedureSupplier.map(
(ps) => ps.procedureId,
);
// Busca integrações relacionadas aos procedimentos
const integrations = await this.integrationDBService.findByProceduresIds(
procedureIds,
payload,
);
// Retorna dados transformados
return {
orderId,
integrations,
fields,
token,
};
} catch (e) {
const error = e as Error;
this.logger.debug(error, error.stack);
throw new WsException(
'Erro ao procurar os procedimentos da integração',
);
}
}Gateway recebe dados transformados e retorna
O handler recebe os dados já transformados pelo Pipe e retorna as integrações completas:
// accounts.gateways.ts
@SubscribeMessage('valiation.label')
async handleValidationLabel(
@ConnectedSocket() client: Socket,
@MessageBody(ProceduresRequiredPipe)
data: {
integrations: Array<
IntegrationDiagnosticsBrazil & {
procedure: Procedures;
}
>;
},
): Promise<ResponseWs> {
try {
// Retorna integrações completas (sem filtrar campos)
return {
status: 'receive',
integrations: data.integrations,
timestamp: new Date().toISOString(),
};
} catch (e) {
// ... tratamento de erro
}
}Gateway trata erros do Pipe
Se o Pipe lançar uma exceção, o NestJS converte automaticamente para resposta de erro:
// accounts.gateways.ts - Continuação do handleValidationLabel
} catch (e) {
const { message } = e as Error;
this.logger.debug(e);
return {
status: 'refused',
message: message,
timestamp: new Date().toISOString(),
};
}Cliente processa resposta e abre modal de validação
No frontend, o callback processa a resposta e abre o modal de validação com os dados de integração:
// FinishOrder.tsx - Callback do socket.emit
(response: ValiditionsResponseWs) => {
if (response.status === 'receive') {
// Abre modal interativo para validação
openModal(
<Validation
order={order}
integrations={response.integrations}
/>
);
}
}Request URL
ws://api-dev.imagemais.com{
"orderId": 123,
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
...{
"orderId": 123,
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}Respostas
{
"status": "receive",
"integrations": [
...{
"status": "receive",
"integrations": [
{
"procedureId": 456,
"volume": "5ml",
"height": "170cm",
"weight": "70kg",
"region": "Braço direito"
}
],
"timestamp": "2025-01-23T10:30:00.000Z"
}{
"status": "refused",
"message": "Erro ao procurar os procedimentos da integração",
...{
"status": "refused",
"message": "Erro ao procurar os procedimentos da integração",
"timestamp": "2025-01-23T10:30:00.000Z"
}