Skip to content

Ciclo de Vida e Observabilidade da State Machine

Em sistemas de saúde, entender como e por que uma transição ocorreu é fundamental para a segurança do paciente e auditoria técnica. Esta página detalha como gerenciar o ciclo de vida (Lifecycle) das máquinas de estado e como implementar mecanismos de observabilidade para visualizar o que ocorreu durante um atendimento.


1. Declarando o Ciclo de Vida (Lifecycle)

O XState fornece hooks integrados para executar lógica em momentos específicos do ciclo de vida de um estado: ao entrar (entry), ao sair (exit) e durante transições (actions).

Hooks de Entrada e Saída (Entry/Exit)

Estes hooks são ideais para preparar o ambiente ou limpar recursos, como ligar/desligar o microfone ou iniciar/parar timers de consulta.

typescript
// packages/domains/consultation/machines/teleconsultationMachine.ts

const teleconsultationMachine = createMachine({
  id: 'teleconsultation',
  initial: 'idle',
  states: {
    idle: {
      on: { START_CALL: 'inCall' }
    },
    inCall: {
      // CICLO DE VIDA: Ao entrar no estado de chamada
      entry: [
        'initializeWebRTC',
        'startConsultationTimer',
        'notifyAnalyticsCallStarted'
      ],
      // CICLO DE VIDA: Ao sair do estado de chamada
      exit: [
        'stopWebRTC',
        'stopConsultationTimer',
        'cleanupMediaResources'
      ],
      on: {
        END_CALL: 'summary'
      }
    },
    summary: {
      entry: 'generateAutoSummary'
    }
  }
}, {
  actions: {
    initializeWebRTC: (context) => {
      console.log('Iniciando WebRTC para o paciente:', context.patientId);
    },
    stopWebRTC: () => {
      console.log('Finalizando stream de vídeo e liberando hardware.');
    }
  }
});

2. Observabilidade: Visualizando o que Ocorreu

Para depuração e auditoria, precisamos de uma trilha clara de eventos. Implementamos isso através de três níveis:

A. Logging de Transições (Console & Telemetria)

Podemos utilizar o execute ou listeners de transição para logar cada passo da máquina. Em desenvolvimento, isso ajuda a entender o fluxo; em produção, esses logs podem ser enviados para ferramentas como Sentry ou Datadog.

typescript
// packages/core/machine-utils/logger.ts

export const createMachineLogger = (service: any, machineId: string) => {
  service.subscribe((state) => {
    if (state.changed) {
      console.group(`[State Machine: ${machineId}]`);
      console.log('Evento:', state.event.type);
      console.log('De:', state.history?.value || 'initial');
      console.log('Para:', state.value);
      console.log('Contexto Atual:', state.context);
      console.groupEnd();
    }
  });
};

B. Persistência de Histórico para Auditoria

Em cenários médicos, é vital saber se o médico visualizou o alerta de alergia antes de prescrever. Podemos salvar o histórico de transições no banco de dados.

typescript
// Exemplo de como capturar a trilha para persistência
service.onTransition((state) => {
  const auditLog = {
    timestamp: new Date().toISOString(),
    fromState: state.history?.value,
    toState: state.value,
    event: state.event,
    userId: state.context.doctorId
  };
  
  // Envia para o domínio de auditoria via Domain Event
  domainEventsBus.publish(DomainEventNames.MACHINE_TRANSITION_AUDIT, auditLog);
});

C. Visualização Gráfica (XState Inspect)

Para desenvolvedores, utilizamos o @xstate/inspect. Ele permite visualizar a máquina em tempo real, disparar eventos manualmente e inspecionar o contexto através de uma interface visual.

typescript
// No entry point do App (apenas em desenvolvimento)
import { inspect } from '@xstate/inspect';

if (process.env.NODE_ENV === 'development') {
  inspect({
    iframe: false // Abre em uma nova aba
  });
}

// Ao iniciar o serviço da máquina
const service = interpret(myMachine, { devTools: true });

3. Passo a Passo: Implementando Observabilidade em um Novo Fluxo

Siga estes passos para garantir que sua nova máquina de estado seja rastreável:

  1. Defina Actions de Ciclo de Vida: Sempre use entry e exit para efeitos colaterais em vez de dispará-los dentro dos componentes React. Isso garante que a lógica ocorra mesmo se a transição for disparada programaticamente.
  2. Adicione Nomes de Transição: Evite transições anônimas. Dê nomes claros aos eventos (ex: SUBMIT_VITAL_SIGNS).
  3. Habilite o Logger de Domínio: No arquivo ui/Page.tsx onde a máquina é iniciada, utilize o helper de log para monitorar o comportamento no console do navegador.
  4. Valide o Contexto: Utilize o log para verificar se o context (memória da máquina) está sendo atualizado corretamente em cada transição.

Matriz de Observabilidade

FerramentaPúblicoObjetivo
XState InspectDesenvolvedoresDepuração visual em tempo real e teste de transições.
Console LoggerDesenvolvedores/QARastreamento rápido de fluxo durante o desenvolvimento.
Audit LogsAnalistas de NegócioProva técnica de conformidade com protocolos médicos.
Domain EventsOutros SistemasReação assíncrona baseada em mudanças de estado críticas.