WEBSOCKETvaliation.label

Validar 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

AuthorizationOBRIGATÓRIO
Tipo:string
Token de autenticação no formato Bearer {accessToken}. O token deve ser enviado durante o handshake de conexão WebSocket.

Parâmetros

orderIdOBRIGATÓRIO
Tipo:number
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.

tokenOBRIGATÓRIO
Tipo:string
Token JWT do usuário para validação e autenticação

Fluxo passo a passo: valiation.label

1

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}
          />
        );
      }
    }
  );
}
Quem emite: frontend (FinishOrder.tsx)
Quando: ao clicar no botão 'Etiqueta' quando pedido está em IN_PROGRESS
Payload: { orderId: number, token: string }
Callback: processa resposta e abre modal de validação
Ação em sucesso: abre modal interativo para validação de dados
2

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',
    );
  }
}
O que faz: intercepta requisição antes do handler
Validação 1: valida e decodifica token JWT
Validação 2: valida se orderId é válido e numérico
Busca dados: busca pedido completo e integrações dos procedimentos
Transformação: adiciona integrations aos dados recebidos
Tratamento de erro: lança WsException se houver erro (retorna status: 'refused')
3

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
  }
}
Quem recebe: servidor (Gateway WS)
Dados recebidos: já transformados pelo Pipe (contém integrations)
Processamento: handler simples - apenas retorna dados já processados pelo Pipe
Campos retornados: todas as integrações completas (sem filtro de campos)
Resposta: retorna via callback do socket.emit
4

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(),
  };
}
Tratamento: captura erros do Pipe ou do handler
Conversão automática: NestJS converte WsException em resposta de erro
Erros possíveis: token inválido, orderId inválido, pedido não encontrado, erro ao buscar integrações
Resposta: retorna { status: 'refused', message: '...', timestamp: '...' }
5

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}
      />
    );
  }
}
Validação: verifica se response.status === 'receive'
Ação: abre modal interativo para validação de dados
Dados passados: order e integrations (procedureId, volume, height, weight, region)
Funcionalidade: usuário pode validar e ajustar dados antes de criar etiquetas

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"
}