Block System
Block System
Section titled “Block System”The Block System is Juca’s fundamental UI architecture. Every piece of content rendered in the WorkCanvas — from chat messages to legal diagnoses to strategic recommendations — is a Block: a typed data structure with a corresponding React component.
Why Blocks?
Section titled “Why Blocks?”The Block System replaced a tab-based panel architecture where each feature (Chat, Juris, Ratio, Compare, Insights, Semantic) had its own isolated rendering logic. Blocks solve three problems:
- Uniform composition — Any content type can be rendered in the same canvas
- SSE-friendly — Blocks stream incrementally as they’re created
- Testable — Each block type has a factory function (pure) and a component (isolated)
The 11 Block Types
Section titled “The 11 Block Types”| Type | Component | Briefing Phase | Purpose |
|---|---|---|---|
message | MessageBlock | Phase 0 (Chat) | User and AI chat messages |
progress | ProgressBlock | Any | Loading indicators during processing |
diagnosis | DiagnosisBlock | Phase 1 | Diagnostic card with situation, area, theme, thesis |
action_prompt | ActionPromptBlock | Phase 1 | Interactive prompts suggesting next actions |
precedent | PrecedentBlock | Phase 2 | Individual STJ precedent card with details |
precedent_picker | PrecedentPickerBlock | Phase 2 | Selection interface for evaluating precedents |
summary | SummaryBlock | Any | Summary of analysis state |
risk_balance | RiskBalanceBlock | Phase 3 | Visual risk-vs-opportunity balance |
chart | ChartBlock | Phase 3 | Data visualization of risk analysis |
delivery | DeliveryBlock | Phase 4 | Final output in one of 4 adaptive modes |
exit_card | ExitCardBlock | Phase 4 | Session completion with summary + export |
Block Lifecycle
Section titled “Block Lifecycle”Every block follows this lifecycle from creation to rendering:
1. Intent detected → Tool selected2. Tool calls Valter API or processes data3. Block Factory creates typed data: createDiagnosisData(analysis) createPrecedentData(precedent) createRiskBalanceData(analysis, situation, evaluations)4. Block persisted: getBlocksDB().addBlock(input)5. SSE streams block event to client6. WorkCanvas renders block component based on block.typeBlock Factory Functions
Section titled “Block Factory Functions”All factory functions live in src/lib/blocks/types.ts. Each returns a strongly-typed data object:
// Phase 1 factoriescreateDiagnosisData(analysis: CaseAnalysis): DiagnosisBlockDatacreateSituationPromptData(): ActionPromptBlockDatacreateContextPromptData(): ActionPromptBlockData
// Phase 2 factoriescreatePrecedentData(p: Precedent): PrecedentBlockDatacreatePrecedentPickerData(total, precedentBlockIds): PrecedentPickerBlockData
// Phase 3 factoriescreateSummaryData(total): SummaryBlockDatacreateRiskBalanceData(analysis, situation, evaluatedUseful): RiskBalanceBlockDatacreateChartData(analysis, riskBalance): ChartBlockData
// Phase 4 factoriescreateDeliveryData(analysis, state): DeliveryBlockDatacreateExitCardData(): ExitCardBlockDataRisk Weight Calculation
Section titled “Risk Weight Calculation”The risk_balance block uses a weighted scoring system:
// Risk severity × probability → weighted scoreconst weights = { alta: { provavel: 90, possivel: 75, improvavel: 60 }, media: { provavel: 60, possivel: 45, improvavel: 30 }, baixa: { provavel: 40, possivel: 25, improvavel: 15 }};Delivery Mode Selection
Section titled “Delivery Mode Selection”The delivery block adapts based on the user’s situation selected in Phase 1:
| Situation | Delivery Mode | Content Generator |
|---|---|---|
pesquisando (researching) | Síntese (Synthesis) | buildSinteseContent() |
avaliando (evaluating) | Parecer (Opinion) | buildParecerContent() |
atuando (acting) | Estratégia (Strategy) | buildEstrategiaContent() |
estudando (studying) | Mapa (Map) | buildMapaContent() |
Block Components
Section titled “Block Components”Block components live in src/components/blocks/. Each receives typed props matching its data shape and renders independently. The WorkCanvas maps block.type to the correct component:
// Simplified WorkCanvas rendering logic{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 for all 11 types }})}Adding a New Block Type
Section titled “Adding a New Block Type”To add a 12th block type:
- Define the type in
src/types/blocks.ts— add to theBlockTypeunion and create theYourBlockDatainterface - Create the factory in
src/lib/blocks/types.ts— addcreateYourBlockData()function - Build the component in
src/components/blocks/YourBlock.tsx— React component that renders the data - Register in WorkCanvas — add the
caseto the block type switch insrc/components/canvas/WorkCanvas.tsx - Write tests — unit test for the factory function and component test for the React component