Pular para o conteúdo

Block System

O Block System é a arquitetura de UI fundamental do Juca. Todo conteúdo renderizado no WorkCanvas — desde mensagens de chat até diagnósticos jurídicos e recomendações estratégicas — é um Block: uma estrutura de dados tipada com um componente React correspondente.

O Block System substituiu uma arquitetura de painéis por abas, onde cada funcionalidade (Chat, Juris, Ratio, Compare, Insights, Semantic) tinha sua própria lógica de renderização isolada. Os blocos resolvem três problemas:

  1. Composição uniforme — Qualquer tipo de conteúdo pode ser renderizado no mesmo canvas
  2. Compatível com SSE — Blocos chegam de forma incremental via streaming à medida que são criados
  3. Testável — Cada tipo de bloco tem uma factory function (pura) e um componente (isolado)
TipoComponenteFase do BriefingPropósito
messageMessageBlockFase 0 (Chat)Mensagens de chat do usuário e da IA
progressProgressBlockQualquerIndicadores de carregamento durante o processamento
diagnosisDiagnosisBlockFase 1Card de diagnóstico com situação, área, tema e tese
action_promptActionPromptBlockFase 1Prompts interativos sugerindo próximas ações
precedentPrecedentBlockFase 2Card individual de precedente do STJ com detalhes
precedent_pickerPrecedentPickerBlockFase 2Interface de seleção para avaliar precedentes
summarySummaryBlockQualquerResumo do estado da análise
risk_balanceRiskBalanceBlockFase 3Balanço visual de riscos versus oportunidades
chartChartBlockFase 3Visualização de dados da análise de riscos
deliveryDeliveryBlockFase 4Entregável final em um dos 4 modos adaptativos
exit_cardExitCardBlockFase 4Conclusão da sessão com resumo + exportação

Todo bloco segue este ciclo desde a criação até a renderização:

1. Intenção detectada → Ferramenta selecionada
2. Ferramenta chama a API do Valter ou processa os dados
3. Block Factory cria dados tipados:
createDiagnosisData(analysis)
createPrecedentData(precedent)
createRiskBalanceData(analysis, situation, evaluations)
4. Bloco persistido: getBlocksDB().addBlock(input)
5. SSE transmite o evento do bloco para o cliente
6. WorkCanvas renderiza o componente do bloco com base em block.type

Todas as factory functions ficam em src/lib/blocks/types.ts. Cada uma retorna um objeto de dados fortemente tipado:

// Factories da Fase 1
createDiagnosisData(analysis: CaseAnalysis): DiagnosisBlockData
createSituationPromptData(): ActionPromptBlockData
createContextPromptData(): ActionPromptBlockData
// Factories da Fase 2
createPrecedentData(p: Precedent): PrecedentBlockData
createPrecedentPickerData(total, precedentBlockIds): PrecedentPickerBlockData
// Factories da Fase 3
createSummaryData(total): SummaryBlockData
createRiskBalanceData(analysis, situation, evaluatedUseful): RiskBalanceBlockData
createChartData(analysis, riskBalance): ChartBlockData
// Factories da Fase 4
createDeliveryData(analysis, state): DeliveryBlockData
createExitCardData(): ExitCardBlockData

O bloco risk_balance utiliza um sistema de pontuação ponderada:

// Severidade × Probabilidade → pontuação ponderada
const weights = {
alta: { provavel: 90, possivel: 75, improvavel: 60 },
media: { provavel: 60, possivel: 45, improvavel: 30 },
baixa: { provavel: 40, possivel: 25, improvavel: 15 }
};

O bloco delivery se adapta com base na situação do usuário selecionada na Fase 1:

SituaçãoModo de EntregaGerador de Conteúdo
pesquisando (pesquisando)SíntesebuildSinteseContent()
avaliando (avaliando)ParecerbuildParecerContent()
atuando (atuando)EstratégiabuildEstrategiaContent()
estudando (estudando)MapabuildMapaContent()

Os componentes de blocos ficam em src/components/blocks/. Cada um recebe props tipadas correspondentes à sua estrutura de dados e renderiza de forma independente. O WorkCanvas mapeia block.type para o componente correto:

// Lógica simplificada de renderização do WorkCanvas
{blocks.map(block => {
switch (block.type) {
case 'message': return <MessageBlock data={block.data} />
case 'diagnosis': return <DiagnosisBlock data={block.data} />
case 'precedent': return <PrecedentBlock data={block.data} />
// ... etc para todos os 11 tipos
}
})}

Para adicionar um 12º tipo de bloco:

  1. Defina o tipo em src/types/blocks.ts — adicione à union BlockType e crie a interface YourBlockData
  2. Crie a factory em src/lib/blocks/types.ts — adicione a função createYourBlockData()
  3. Construa o componente em src/components/blocks/YourBlock.tsx — componente React que renderiza os dados
  4. Registre no WorkCanvas — adicione o case ao switch de tipo de bloco em src/components/canvas/WorkCanvas.tsx
  5. Escreva testes — teste unitário para a factory function e teste de componente para o componente React