WEBSOCKETbudgets.requests.accept

Aceitar Requisição de Orçamento

Evento WebSocket para aceitar uma requisição de orçamento pendente em tempo real. O cliente emite este evento com o UUID da requisição. O servidor processa a aceitação no banco de dados e propaga a atualização para todos os clientes conectados da mesma conta (broadcast), permitindo sincronização automática entre componentes. Diferente de eventos de cliente específico, este evento usa broadcast (notifyOnEvent) para enviar a atualização para todos os clientes da mesma accountId, garantindo que todos vejam a requisição sendo removida das listas de pendentes simultaneamente.

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

uuidOBRIGATÓRIO
Tipo:string
UUID da requisição de orçamento a ser aceita

UUID (Identificador Único Universal) da requisição de orçamento a ser aceita. É um identificador único que identifica uma requisição de orçamento específica no sistema.

Para encontrar o UUID da requisição de orçamento, para acessar a página de buscar todos os orçamentos da fila de envio.

Fluxo passo a passo: budgets.requests.accept

1

Cliente emite a requisição via WebSocket

O frontend emite o evento 'budgets.requests.accept' com o UUID da requisição:

async function acceptBudgetRequest(uuid: string) {
  setErrorBudgetRequests('');
  setLoadingBudgetRequests(true);
  
  socket?.emit(
    'budgets.requests.accept',
    { uuid },
    (response: {
      status: string;
      timestamp: string;
      message?: string;
    }) => {
      if (response.status !== 'receive') {
        setErrorBudgetRequests(
          response.message ?? 'Erro ao aceitar notificação'
        );
      }
      setLoadingBudgetRequests(false);
    }
  );
}
Quem emite: frontend (BudgetList.tsx)
Quando: ao aceitar uma requisição de orçamento
Payload: { uuid: string }
Callback: recebe resposta imediata (status: 'receive' ou 'refused')
2

Servidor recebe e propaga via broadcast

No backend (NestJS + Gateway), o servidor captura o evento, emite evento interno e propaga para todos os clientes da mesma conta:

@SubscribeMessage('budgets.requests.accept')
async handleBudgetsRequestsAccept(
  @ConnectedSocket() client: Socket,
  @MessageBody() data: { uuid: string },
) {
  try {
    const payload = client.data.payload as PayloadTokenDto;
    
    // Emite evento interno para processar no banco
    await this.eventEmitter.emitAsync('budgets.requests.accept', {
      uuid: data.uuid,
      payload,
    });
    
    // Propaga via broadcast para todos da mesma conta
    await this.notifyOnEvent(
      'budgets.requests.accept',
      { uuid: data.uuid },
      payload,
    );
    
    // Retorna resposta imediata (vai para o callback)
    return {
      status: 'receive',
      timestamp: new Date().toISOString(),
    };
  } catch (error) {
    return {
      status: 'refused',
      message: 'Erro ao aceitar requisição de orçamento',
      timestamp: new Date().toISOString(),
    };
  }
}
Quem recebe: servidor (Gateway WS)
O que faz: emite evento interno + propaga via broadcast
Diferença importante: notifyOnEvent() → broadcast para todos da conta
: não usa notifyOnEventClient() (cliente específico)
3

Listener processa a aceitação no banco

O listener escuta o evento interno e atualiza o status da requisição no banco de dados:

@OnEvent('budgets.requests.accept')
async handleOnBudgetsRequestsAccept(event: {
  uuid: string;
  payload: PayloadTokenDto;
}) {
  try {
    // Atualiza o status da requisição no banco
    await this.budgetsRequestsService.accept(
      event.payload,
      event.uuid
    );
  } catch (e) {
    this.logger.debug('Erro ao aceitar requisição', e);
  }
}
O que faz: atualiza status da requisição no banco
Filtro: por accountId do payload
Observação: listener não envia WebSocket; apenas processa no banco
4

Servidor propaga para todos da mesma conta

O método `notifyOnEvent` envia o evento 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);
  }
}
Diferença importante: notifyOnEvent() → broadcast para todos da conta
: notifyOnEventClient() → apenas para um cliente específico
Quem recebe: todos os clientes conectados daquela accountId
5

Clientes recebem e atualizam a UI

No frontend, múltiplos componentes escutam o evento e atualizam suas respectivas UIs:

// Notification.tsx - Remove da lista de notificações
socket.on('budgets.requests.accept', (data: { uuid: string }) => {
  setNotifications((prev) =>
    prev.filter((notification) => notification.uuid !== data.uuid)
  );
});

// BudgetList.tsx - Remove da lista e recarrega
socket.on('budgets.requests.accept', (data: { uuid: string }) => {
  setBudgetRequests((prev) =>
    prev.filter((budgetRequest) => budgetRequest.uuid !== data.uuid)
  );
  loadBudgetRequest();
});

// Form.tsx - Recarrega notificações
socket.on('budgets.requests.accept', (data: { uuid: string }) => {
  loadNotification();
});
Notification.tsx: remove notificação aceita da lista
BudgetList.tsx: remove requisição e recarrega dados
Form.tsx: recarrega notificações
Sincronização: todos os componentes atualizam simultaneamente

Request URL

ws://api-dev.imagemais.com
{
  "uuid": "550e8400-e29b-41d4-a716-446655440000"
}
{
  "uuid": "550e8400-e29b-41d4-a716-446655440000"
}

Respostas

{
  "status": "receive",
  "timestamp": "2025-01-23T10:30:00.000Z"
  ...
{
  "status": "receive",
  "timestamp": "2025-01-23T10:30:00.000Z"
}
{
  "status": "refused",
  "message": "Erro ao aceitar requisição de orçamento",
  ...
{
  "status": "refused",
  "message": "Erro ao aceitar requisição de orçamento",
  "timestamp": "2025-01-23T10:30:00.000Z"
}