WEBSOCKETget.orders.completed

Buscar Pedidos Completados

Evento WebSocket para buscar pedidos completados com filtros avançados em tempo real. O cliente emite este evento com parâmetros de busca (SearchDto) para solicitar pedidos que correspondem aos critérios especificados. O servidor processa a requisição via EventEmitter interno e busca os pedidos usando findBySearch() que permite múltiplos filtros (status, termo de busca, usuário, intervalo de datas). Diferente de get.orders.standby e get.orders.progress que usam getOrders() para buscar apenas por status, este evento usa findBySearch() que aceita filtros avançados. O frontend limpa a lista antes de buscar novos resultados e filtra os pedidos recebidos por status antes de adicionar à lista.

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

searchOPCIONAL
Tipo:string
Termo de busca para filtrar pedidos (opcional)
acceptUserIdOPCIONAL
Tipo:string
ID do usuário que coletou o pedido (opcional)
statusOBRIGATÓRIO
Tipo:string
Status do pedido (ex: COMPLETED, CANCELED, etc.)
dateInitialOBRIGATÓRIO
Tipo:string
Data inicial do intervalo de busca (formato: YYYY-MM-DD)
dateFinalOBRIGATÓRIO
Tipo:string
Data final do intervalo de busca (formato: YYYY-MM-DD)

Fluxo passo a passo: get.orders.completed

1

Cliente valida parâmetros e emite a requisição via WebSocket

O frontend valida os parâmetros de busca, limpa a lista atual e emite o evento 'get.orders.completed':

// Side.tsx
// Valida parâmetros antes de enviar
const validate = () => {
  // Validação dos parâmetros...
};

// Limpa a lista antes de buscar novos resultados
setOrders([]);

// Emite evento com parâmetros de busca
socket?.emit('get.orders.completed', {
  search: searchParams.search,
  acceptUserId: searchParams.acceptUserId,
  status: searchParams.status,
  dateInitial: searchParams.dateInitial,
  dateFinal: searchParams.dateFinal,
});
Quem emite: frontend (Side.tsx)
Quando: ao montar componente, quando parâmetros mudam ou ao submeter formulário
Payload: objeto SearchDto com parâmetros de busca
Ação prévia: limpa a lista (setOrders([])) antes de buscar
Callback: não aguarda resposta direta; recebe dados via evento 'completed'
2

Servidor recebe payload e emite evento interno

No backend (NestJS + Gateway), o servidor captura o evento com os parâmetros de busca e emite um evento interno:

@SubscribeMessage('get.orders.completed')
async handleOrdersCompled(
  @ConnectedSocket() client: Socket,
  @MessageBody() data: SearchDto,
) {
  // Cria LoadOrdersEvent com client.id, payload e data (parâmetros de busca)
  this.eventEmitter.emit(
    'load.orders.completed',
    new LoadOrdersEvent(client.id, client.data.payload, data),
  );
}

class LoadOrdersEvent {
  to: string;              // ID do socket do cliente
  payload: PayloadTokenDto; // Dados de autenticação
  data?: SearchDto;        // Parâmetros de busca (usado neste caso)
}
Quem recebe: servidor (Gateway WS)
O que faz: emite evento interno 'load.orders.completed' com LoadOrdersEvent
Diferença importante: recebe e usa data (SearchDto) no LoadOrdersEvent
Resposta direta: não retorna resposta imediata (diferente de get.orders.progress)
3

Listener busca pedidos com filtros avançados

O listener escuta o evento interno e busca os pedidos usando findBySearch() com múltiplos filtros:

@OnEvent('load.orders.completed')
async handleOnLoadOrdersCompleted({ to, payload, data }: LoadOrdersEvent) {
  try {
    // Busca pedidos com filtros avançados
    const orders = await this.ordersService.findBySearch(data, payload);
    
    // Envia cada pedido individualmente
    orders.map((order) =>
      this.gateway.notifyOnEventClient(to, 'completed', order),
    );
  } catch (e) {
    this.logger.debug(
      `Fail execunting event Orders in status: ${OrdersStatusEnum.COMPLETED}`,
      e as Error,
    );
  }
}
Método usado: findBySearch() (permite filtros avançados)
Filtros aplicados: status, search, acceptUserId, dateInitial, dateFinal, accountId
Diferença importante: usa findBySearch() ao invés de getOrders() (permite busca avançada)
Como envia: cada pedido em uma mensagem separada via 'completed'
Destino: apenas para o cliente que solicitou (to = client.id)
4

Servidor envia cada pedido via evento 'completed'

O método `notifyOnEventClient` envia cada pedido individualmente para o cliente:

async notifyOnEventClient(to: string, event: string, data: any) {
  if (this._events.includes(event)) {
    // Envia apenas para o socket específico
    this.server.to(to).emit(event, data);
  }
}

// Para cada pedido encontrado:
// this.server.to(client.id).emit('completed', order1);
// this.server.to(client.id).emit('completed', order2);
// this.server.to(client.id).emit('completed', order3);
// ...
Evento: 'completed' (está na lista de eventos permitidos)
Dados: objeto Order completo (um por mensagem)
Quantidade: múltiplos eventos completed (um para cada pedido encontrado)
Destino: apenas para o cliente que solicitou (to = client.id)
5

Cliente filtra por status e adiciona à lista

No frontend, o componente escuta o evento 'completed', filtra por status e adiciona cada pedido à lista:

// Side.tsx
useEffect(() => {
  if (!socket) return;

  const handleCompleted = (newOrder: Order) => {
    // Filtra por status antes de adicionar
    if (newOrder.status.name === searchParams.status) {
      setOrders((prev) =>
        // Previne duplicatas
        prev.some((o) => o.id === newOrder.id)
          ? prev
          // Adiciona no início da lista (pedidos mais recentes primeiro)
          : [newOrder, ...prev]
      );
    }
  };

  socket.on('completed', handleCompleted);
  
  return () => {
    socket.off('completed', handleCompleted);
  };
}, [socket, searchParams.status]);
Evento completed: recebe um pedido por vez e filtra por status antes de adicionar
Filtro por status: só adiciona se newOrder.status.name === searchParams.status
Prevenção de duplicatas: verifica se o pedido já existe antes de adicionar
Ordem dos pedidos: pedidos mais recentes aparecem primeiro ([newOrder, ...prev])
Diferença importante: filtra resultados por status no frontend antes de adicionar
Cleanup: remove listeners ao desmontar para prevenir memory leaks

Request URL

ws://api-dev.imagemais.com
{
  "search": "termo de busca",
  "acceptUserId": "123",
  ...
{
  "search": "termo de busca",
  "acceptUserId": "123",
  "status": "COMPLETED",
  "dateInitial": "2025-01-01",
  "dateFinal": "2025-01-31"
}

Respostas

{
  "message": "Pedidos completados serão enviados via evento 'completed'"
}
{
  "message": "Pedidos completados serão enviados via evento 'completed'"
}
{
  "message": "Erro ao buscar pedidos completados",
  "error": "Bad Request",
  ...
{
  "message": "Erro ao buscar pedidos completados",
  "error": "Bad Request",
  "statusCode": 400
}