callChamar Pedido para Coleta
Evento WebSocket para chamar um pedido em standby para coleta, mudando seu status de STANDBY para IN_PROGRESS. O cliente emite este evento com o ID do pedido e opcionalmente o ID do usuário que vai coletar. O servidor valida se o usuário já está coletando outro paciente, atualiza o pedido e notifica todos os clientes conectados da mesma conta via broadcast. Este evento é diferente de outros porque retorna uma resposta imediata via callback (status: 'receive' ou 'refused'), permitindo que o frontend processe o resultado instantaneamente. Em caso de sucesso, o frontend remove o pedido da lista de standby e todos os clientes recebem o evento 'progress' para adicionar o pedido à lista de "Em Progresso".
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 |
|---|---|---|---|
id | number | Sim | ID do pedido a ser chamado para coleta |
ID do pedido a ser chamado para coleta. É 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. | |||
acceptepUserId | number | Não | ID do usuário que vai coletar o pedido (opcional; se não enviado, usa o usuário logado) |
ID do usuário que vai coletar o pedido (opcional). Se não enviado, usa o usuário logado. É um identificador numérico único que identifica um usuário específico no sistema. Para encontrar o ID do usuário, para acessar a página de listar todos os usuários. | |||
idOBRIGATÓRIOID do pedido a ser chamado para coleta. É 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.
acceptepUserIdOPCIONALID do usuário que vai coletar o pedido (opcional). Se não enviado, usa o usuário logado. É um identificador numérico único que identifica um usuário específico no sistema.
Para encontrar o ID do usuário, para acessar a página de listar todos os usuários.
Fluxo passo a passo: call
Cliente emite a requisição via WebSocket com callback
O frontend emite o evento 'call' com o ID do pedido e opcionalmente o ID do usuário coletador:
// ListStandby.tsx
function onRemove(id: number, acceptepUserId?: number) {
socket?.emit('call', { id, acceptepUserId }, (data: responseWs) => {
if (data.status === 'receive') {
// Remove da lista de standby
socket?.emit('remove.standby', orders.find((o) => o.id === id));
}
if (data.status === 'refused') {
// Mostra notificação de erro
addNotification({
title: 'Atenção!!!',
message: data.message,
bg: 'danger',
className: 'text-white',
autohide: true,
});
}
});
}Servidor valida conflito de coleta
No backend (NestJS + Gateway), o servidor valida se o usuário já está coletando outro paciente:
@SubscribeMessage('call')
async handleMessage(
@ConnectedSocket() client: Socket,
@MessageBody() data: UpdateOrderDto,
) {
try {
const payload = client.data.payload as PayloadTokenDto;
// Valida se o usuário já está coletando outro paciente
const exists = await this.ordersService.existsOrder(
OrdersStatusEnum.IN_PROGRESS,
data.acceptepUserId ?? payload.sub, // Usa acceptepUserId se fornecido, senão usa usuário logado
payload,
);
if (exists) {
return {
status: 'refused',
message: 'O usuário já está coletando outro paciente',
timestamp: new Date().toISOString(),
};
}
// ... continua no próximo passo
} catch (e) {
// ... tratamento de erro
}
}Servidor atualiza pedido e notifica via broadcast
Se não houver conflito, o servidor atualiza o pedido de STANDBY para IN_PROGRESS e notifica todos os clientes:
// Continuação do handleMessage
// Atualiza o pedido (muda status de STANDBY para IN_PROGRESS)
const order = await this.ordersService.updateOrder(data, payload);
// Busca dados completos do pedido atualizado
const orderComplete = await this.ordersService.findById(order.id, payload);
// Notifica todos os clientes da mesma conta via broadcast
this.notifyOnEvent(
'progress',
orderComplete,
client.data.payload,
);
// Retorna sucesso
return {
status: 'receive',
timestamp: new Date().toISOString(),
};Servidor propaga evento 'progress' para todos da conta
O método `notifyOnEvent` envia o evento 'progress' 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 'progress'Cliente processa resposta e remove da lista standby
No frontend, o callback processa a resposta. Se sucesso, remove o pedido da lista de standby:
// ListStandby.tsx - Callback do socket.emit
if (data.status === 'receive') {
// Remove da lista de standby localmente
socket?.emit('remove.standby', orders.find((o) => o.id === id));
}
if (data.status === 'refused') {
// Exibe notificação de erro
addNotification({
title: 'Atenção!!!',
message: data.message,
bg: 'danger',
className: 'text-white',
autohide: true,
});
// Não remove da lista (pedido continua em standby)
}Outros clientes recebem evento 'progress' e adicionam à lista
Todos os clientes conectados da mesma conta recebem o evento 'progress' e adicionam o pedido à lista de 'Em Progresso':
// ListInProgress.tsx
socket.on('progress', (newData: Order) => {
setOrders((prev) => {
// Previne duplicatas
if (prev.find((d) => d.id === newData.id)) return prev;
// Adiciona no início da lista (pedidos mais recentes primeiro)
return [newData, ...prev];
});
});Request URL
ws://api-dev.imagemais.com{
"id": 123,
"acceptepUserId": 456
...{
"id": 123,
"acceptepUserId": 456
}Respostas
{
"status": "receive",
"timestamp": "2025-01-23T10:30:00.000Z"
...{
"status": "receive",
"timestamp": "2025-01-23T10:30:00.000Z"
}{
"status": "refused",
"message": "O usuário já está coletando outro paciente",
...{
"status": "refused",
"message": "O usuário já está coletando outro paciente",
"timestamp": "2025-01-23T10:30:00.000Z"
}