<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://hertonnn.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://hertonnn.github.io/" rel="alternate" type="text/html" /><updated>2026-08-21T15:56:27+00:00</updated><id>https://hertonnn.github.io/feed.xml</id><title type="html">Herton Silveira | Blog</title><subtitle>Desenvolvedor &amp; Pesquisador Científico</subtitle><entry><title type="html">JusDigital: Interface Web e IA com Linguagem Natural</title><link href="https://hertonnn.github.io/blog/SistemaJuridico-FrontEnd-IA/" rel="alternate" type="text/html" title="JusDigital: Interface Web e IA com Linguagem Natural" /><published>2026-08-18T14:00:00+00:00</published><updated>2026-08-18T14:00:00+00:00</updated><id>https://hertonnn.github.io/blog/SistemaJuridico-FrontEnd-IA</id><content type="html" xml:base="https://hertonnn.github.io/blog/SistemaJuridico-FrontEnd-IA/"><![CDATA[<p>Há um tempo atrás, <a href="https://hertonnn.github.io/blog/SistemaJuridico/">escrevi no meu blog</a> a respeito de um projeto que nasceu de uma disciplina de Banco de Dados na UDESC. Naquele post, eu cobri a parte que talvez seja a menos glamourosa, mas sem dúvida a mais importante de qualquer sistema: a <strong>modelagem relacional</strong>. Tabelas, chaves, cardinalidades, gatilhos. O alicerce invisível que segura tudo de pé.</p>

<p>Agora é hora de contar o que veio depois.</p>

<p>Se no primeiro post o assunto era “como organizar dados jurídicos num banco relacional”, neste aqui a pergunta é diferente: <strong>como um ser humano normal interage com esses dados?</strong> Porque não adianta ter o banco mais bem modelado do mundo se o usuário final precisa abrir um terminal e digitar SQL para descobrir o status de um processo.</p>

<p>Este post cobre duas frentes que completam o sistema:</p>

<ol>
  <li><strong>Uma interface web</strong> pensada para ser limpa, navegável e útil — chamada JusDigital.</li>
  <li><strong>Uma API com IA</strong> que traduz linguagem natural em SQL, e que gera resumos processuais compreensíveis para qualquer pessoa.</li>
</ol>

<p>Vamos por partes.</p>

<hr />

<h2 id="a-interface-jusdigital">A Interface: JusDigital</h2>

<h3 id="a-decisão-de-ir-para-a-web">A decisão de ir para a web</h3>

<p>O projeto original tinha uma interface de linha de comando (CLI) com menu numerado — aquele estilo clássico de projeto acadêmico. Funcionava, mas era o tipo de coisa que só quem desenvolveu consegue usar sem perder a paciência.</p>

<p>A alternativa óbvia seria um frontend web, e foi exatamente o que fizemos. <strong>HTML puro, CSS puro, JavaScript vanilla.</strong> O servidor? O próprio <code class="language-plaintext highlighter-rouge">com.sun.net.httpserver.HttpServer</code> que já vem embutido no Java.</p>

<p>O resultado é que quando você roda <code class="language-plaintext highlighter-rouge">java -jar Run.jar</code> e digita <code class="language-plaintext highlighter-rouge">20</code> no menu, o servidor sobe na porta 8081 e você acessa <code class="language-plaintext highlighter-rouge">http://localhost:8081/</code> no navegador. Sem instalação de nada além do Java.</p>

<h3 id="a-arquitetura-do-front">A arquitetura do front</h3>

<p>O front-end é composto por <strong>13 páginas HTML</strong> que se comunicam com o servidor Java via <code class="language-plaintext highlighter-rouge">fetch()</code>. Não tem SPA, não tem routing do lado do cliente. Cada página é um arquivo <code class="language-plaintext highlighter-rouge">.html</code> independente que faz suas próprias requisições e renderiza o resultado com manipulação direta do DOM.</p>

<p>A estrutura:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>src/view/
├── style.css                    # Design system completo
├── auth.js                      # Módulo de sessão (localStorage)
├── index.html                   # Landing page + busca global
├── login.html                   # Autenticação
├── cadastro.html                # Registro de usuários
├── processos.html               # Tabela de processos
├── visualizar_processo.html     # Detalhe + resumo por IA
├── busca.html                   # Busca unificada
├── advogados.html               # Catálogo de advogados
├── perfil_advogado.html         # Perfil individual
├── jurisprudencia.html          # Base de leis
├── acordao.html                 # Detalhe de lei + processos que a citam
├── diarios.html                 # Diários oficiais (DJe)
└── modelos.html                 # Modelos de petições
</code></pre></div></div>

<p>É muito código? Não. Cada arquivo tem entre 70 e 200 linhas. Sem build step, sem transpilação. Você abre no bloco de notas e entende.</p>

<h3 id="design-o-que-guiou-as-decisões-visuais">Design: o que guiou as decisões visuais</h3>

<p>Nos inspiramos bastante no <a href="https://www.jusbrasil.com.br/">JusBrasil</a> — tanto na organização da informação quanto na experiência de uso. A ideia era criar algo que um profissional da área jurídica já se sentisse familiarizado ao abrir.</p>

<p>A fonte é a <strong>Inter</strong> (Google Fonts), que é basicamente a fonte padrão de qualquer interface que quer parecer profissional sem chamar atenção pra si mesma. As cores seguem uma paleta sóbria: azul institucional (<code class="language-plaintext highlighter-rouge">#1a56db</code>) como cor primária, cinzas para texto e fundo, e badges de status com semântica visual — verde para concluído, azul para em andamento, amarelo para suspenso.</p>

<p>O CSS usa variáveis <code class="language-plaintext highlighter-rouge">:root</code> como design system. Nenhuma cor, tamanho de fonte ou espaçamento é hardcoded nos componentes. Tudo referencia tokens. Isso é uma decisão que parece perfumaria até o dia que você precisa mudar o tom de azul do sistema inteiro.</p>

<div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">:root</span> <span class="p">{</span>
    <span class="py">--primary-color</span><span class="p">:</span> <span class="m">#1a56db</span><span class="p">;</span>
    <span class="py">--text-color</span><span class="p">:</span> <span class="m">#1f2937</span><span class="p">;</span>
    <span class="py">--bg-color</span><span class="p">:</span> <span class="m">#f9fafb</span><span class="p">;</span>
    <span class="c">/* ... */</span>
<span class="p">}</span>
</code></pre></div></div>

<h3 id="as-telas-que-importam">As telas que importam</h3>

<p><strong>Página inicial</strong> — Uma busca global no topo e três cards de acesso rápido: Processos, Diários Oficiais, e Modelos de Documentos. Sem menu hamburguer, sem sidebar, sem tutorial de onboarding. Você abre e sabe o que fazer.</p>

<p><img src="/assets/images/projects/projeto4/index_img.png" alt="Página inicial do JusDigital — hero com busca e cards de acesso rápido" /></p>

<p><strong>Autenticação</strong> — Login e cadastro com formulários simples. O back-end Java valida contra uma tabela <code class="language-plaintext highlighter-rouge">Usuario</code> no banco. A sessão é gerenciada com <code class="language-plaintext highlighter-rouge">localStorage</code> — quando logado, o botão “Entrar” do header vira “Olá, {nome}” com opção de sair. O <code class="language-plaintext highlighter-rouge">auth.js</code> roda em todas as páginas no <code class="language-plaintext highlighter-rouge">DOMContentLoaded</code>.</p>

<p><img src="/assets/images/projects/projeto4/login_img.png" alt="Página de login" /></p>

<p><strong>Lista de processos</strong> — Uma tabela que consome <code class="language-plaintext highlighter-rouge">/api/processos</code> e renderiza número, tipo, assunto e status com badges coloridas. Cada linha tem um botão “Visualizar” que leva ao detalhe.
<img src="/assets/images/projects/projeto4/processos_img.png" alt="Lista de processos com badges de status" /></p>

<p><strong>Detalhe do processo</strong> — Essa é a tela mais rica. Mostra o número do processo, a vara, as partes envolvidas (autor, réu), e uma <strong>linha do tempo</strong> com todo o histórico de trâmites. Mas o destaque é a seção “Resumo Inteligente”, que conecta o front com a API de IA. Mais sobre isso adiante.
<img src="/assets/images/projects/projeto4/processo1_detalhes.png" alt="Detalhe do processo — partes e histórico de trâmites" />
<img src="/assets/images/projects/projeto4/processo1_detalhes_gerando_resumo.png" alt="Gerando resumo inteligente do processo" />
<img src="/assets/images/projects/projeto4/processo1_detalhes_resumo_gerado.png" alt="Resumo inteligente gerado pela IA" /></p>

<p><strong>Busca unificada</strong> — A busca da página inicial redireciona para <code class="language-plaintext highlighter-rouge">busca.html?query=...</code>, que dispara <code class="language-plaintext highlighter-rouge">Promise.all</code> contra três endpoints (<code class="language-plaintext highlighter-rouge">/api/processos</code>, <code class="language-plaintext highlighter-rouge">/api/advogados</code>, <code class="language-plaintext highlighter-rouge">/api/leis</code>) e filtra os resultados no cliente. É uma busca fulltext bruta — sem Elasticsearch, sem índices especiais. Funciona porque o volume de dados é pequeno, e a simplicidade compensa.</p>

<p><img src="/assets/images/projects/projeto4/busca_resultados.png" alt="Busca unificada com resultados de processos, advogados e leis" /></p>

<p><strong>Advogados</strong> — Um grid responsivo com cards mostrando nome, OAB e área de atuação. Clicar em “Ver Perfil” leva a uma página com sidebar contendo os dados pessoais e a lista de processos em que o advogado atua.</p>

<p><img src="/assets/images/projects/projeto4/advogados_img.png" alt="Catálogo de advogados em grid" /></p>

<p><strong>Jurisprudência e Acórdãos</strong> — A página de jurisprudência lista as leis cadastradas. Clicar em uma lei abre a tela de acórdão, que além de mostrar o texto da lei, lista automaticamente todos os processos que a citam — com link direto para cada um.</p>

<p><img src="/assets/images/projects/projeto4/jurisprudencia_img.png" alt="Jurisprudência" /></p>

<p><strong>Modelos de documentos</strong> — Petições e contratos prontos com um botão “Copiar Texto” que usa a Clipboard API. Copiou? O botão vira “Copiado! ✓” por dois segundos e volta ao normal. Micro-interação simples que faz diferença.</p>

<p><img src="/assets/images/projects/projeto4/modelos_pecas_judiciais.png" alt="Modelos de peças judiciais" /></p>

<p><img src="/assets/images/projects/projeto4/diarios_eletronicos.png" alt="Diários eletrônicos" /></p>
<h3 id="o-servidor-por-trás-java-puro-sem-spring">O servidor por trás: Java puro, sem Spring</h3>

<p>O <code class="language-plaintext highlighter-rouge">ServidorWeb.java</code> é provavelmente a parte mais incomum da stack. Em vez de usar Spring Boot ou Javalin, o servidor HTTP é o <code class="language-plaintext highlighter-rouge">com.sun.net.httpserver.HttpServer</code> — uma classe que existe no JDK desde o Java 6 e que quase ninguém usa em produção, mas que é perfeita para projetos acadêmicos e protótipos.</p>

<p>O servidor expõe 9 rotas:</p>

<table>
  <thead>
    <tr>
      <th>Endpoint</th>
      <th>Método</th>
      <th>Descrição</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">/</code></td>
      <td>GET</td>
      <td>Serve <code class="language-plaintext highlighter-rouge">index.html</code> e arquivos estáticos</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">/api/processos</code></td>
      <td>GET</td>
      <td>Lista todos os processos</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">/api/processo?id=N</code></td>
      <td>GET</td>
      <td>Detalhe de um processo (partes, trâmites, vara)</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">/api/advogados</code></td>
      <td>GET</td>
      <td>Lista todos os advogados</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">/api/advogado?id=N</code></td>
      <td>GET</td>
      <td>Perfil do advogado e seus processos</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">/api/leis</code></td>
      <td>GET</td>
      <td>Lista todas as leis</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">/api/lei?id=N</code></td>
      <td>GET</td>
      <td>Detalhe da lei e processos que a citam</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">/api/login</code></td>
      <td>POST</td>
      <td>Autenticação</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">/api/cadastro</code></td>
      <td>POST</td>
      <td>Registro de novo usuário</td>
    </tr>
  </tbody>
</table>

<p>Cada handler é uma inner class que recebe a <code class="language-plaintext highlighter-rouge">Connection</code> JDBC no construtor e monta o JSON manualmente com <code class="language-plaintext highlighter-rouge">StringBuilder</code>. Sim, sem Jackson, sem Gson. Cada campo é escapado na mão. É feio? Um pouco. Funciona? Perfeitamente.</p>

<hr />

<h2 id="a-ia-quando-o-usuário-não-sabe-sql">A IA: Quando o Usuário Não Sabe SQL</h2>

<h3 id="o-problema-real">O problema real</h3>

<p>Vamos ser honestos: o front-end resolve o problema de navegação. Se você quer ver a lista de processos, clica em “Processos”. Se quer detalhes, clica em “Visualizar”. Mas e quando a pergunta é mais sofisticada?</p>

<ul>
  <li><em>“Quais ações de despejo foram abertas contra o Adriano em 2026?”</em></li>
  <li><em>“Liste os processos da Fazenda Estadual com valor acima de 50 mil”</em></li>
  <li><em>“Resumo do processo 0001234-55.2026.8.26.0001”</em></li>
</ul>

<p>Essas perguntas existem na cabeça do usuário em <strong>linguagem natural</strong>. Para respondê-las, alguém teria que escrever SQL. A ideia da API com IA é eliminar essa tradução manual.</p>

<h3 id="a-stack-fastapi--litellm--ollama">A stack: FastAPI + LiteLLM + Ollama</h3>

<p>A API foi construída em Python com <strong>FastAPI</strong> e roda na porta 8000. A comunicação com o modelo de linguagem usa <strong>LiteLLM</strong> como camada de abstração, o que significa que trocar de provedor (Ollama local → OpenAI → OpenRouter) é questão de mudar uma variável de ambiente.</p>

<p>O modelo padrão é o <strong>Qwen 2.5 (3B)</strong> rodando localmente via <strong>Ollama</strong>. Sim, 3 bilhões de parâmetros. Roda na CPU de um notebook comum. Não é GPT-4, mas para gerar SQL a partir de queries simples, funciona surpreendentemente bem.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>LLM-Juridica/
├── main.py            # FastAPI, rotas e CORS
├── llm_service.py     # Lógica das 3 camadas de IA
├── prompts.py         # Todos os prompts centralizados
├── schemas.py         # Modelos Pydantic (request/response)
├── config.py          # Settings com Pydantic + .env
├── test_client.py     # Script de testes
└── pyproject.toml     # Dependências (uv)
</code></pre></div></div>

<h3 id="o-pipeline-3-camadas-de-ia">O pipeline: 3 camadas de IA</h3>

<p>Essa é a parte que mais me interessou no desenvolvimento. Em vez de jogar a pergunta do usuário direto para o modelo e torcer para sair um SQL válido, o sistema usa um <strong>pipeline de três estágios</strong>, cada um com seu próprio prompt e responsabilidade:</p>

<h4 id="camada-1--ner-reconhecimento-de-entidades">Camada 1 — NER (Reconhecimento de Entidades)</h4>

<p>A primeira camada recebe a pergunta em linguagem natural e extrai entidades estruturadas. O modelo retorna um JSON com campos como <code class="language-plaintext highlighter-rouge">tipo_acao</code>, <code class="language-plaintext highlighter-rouge">autor</code>, <code class="language-plaintext highlighter-rouge">reu</code>, <code class="language-plaintext highlighter-rouge">ano</code>, <code class="language-plaintext highlighter-rouge">numero_processo</code>, <code class="language-plaintext highlighter-rouge">valor_causa</code>, <code class="language-plaintext highlighter-rouge">comarca</code>.</p>

<p><strong>Prompt (simplificado):</strong></p>
<blockquote>
  <p>“Você é um especialista em extração de entidades jurídicas. Analise a consulta e retorne APENAS um JSON válido. Use null para campos não encontrados.”</p>
</blockquote>

<p><strong>Entrada:</strong> <code class="language-plaintext highlighter-rouge">"Ação de despejo do Condomínio Edifício Central contra o Adriano em 2026"</code></p>

<p><strong>Saída:</strong></p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"tipo_acao"</span><span class="p">:</span><span class="w"> </span><span class="s2">"despejo"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"autor"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Condomínio Edifício Central"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"reu"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Adriano"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"ano"</span><span class="p">:</span><span class="w"> </span><span class="mi">2026</span><span class="p">,</span><span class="w">
  </span><span class="nl">"numero_processo"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w">
  </span><span class="nl">"valor_causa"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w">
  </span><span class="nl">"comarca"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w">
  </span><span class="nl">"extras"</span><span class="p">:</span><span class="w"> </span><span class="p">{}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p>O parsing da resposta é robusto: usa regex para extrair o bloco <code class="language-plaintext highlighter-rouge">{...}</code> mesmo se o modelo embrulhar em markdown, e valida contra um schema Pydantic. Se o JSON vier malformado, retorna HTTP 502 com mensagem clara.</p>

<h4 id="camada-2--geração-de-sql">Camada 2 — Geração de SQL</h4>

<p>A segunda camada recebe as entidades extraídas + o schema do banco (opcionalmente enviado pelo cliente) e gera uma query PostgreSQL <code class="language-plaintext highlighter-rouge">SELECT</code>.</p>

<p>O ponto mais interessante aqui é a <strong>injeção de contexto do banco</strong>. O cliente pode enviar no request um <code class="language-plaintext highlighter-rouge">db_context</code> com as tabelas, colunas e até dados de exemplo:</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"tables"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"processos"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"id"</span><span class="p">,</span><span class="w"> </span><span class="s2">"numero_cnj"</span><span class="p">,</span><span class="w"> </span><span class="s2">"tipo_acao"</span><span class="p">,</span><span class="w"> </span><span class="s2">"ano_distribuicao"</span><span class="p">,</span><span class="w"> </span><span class="s2">"autor_id"</span><span class="p">,</span><span class="w"> </span><span class="s2">"reu_id"</span><span class="p">],</span><span class="w">
    </span><span class="nl">"partes"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"id"</span><span class="p">,</span><span class="w"> </span><span class="s2">"nome"</span><span class="p">,</span><span class="w"> </span><span class="s2">"cpf_cnpj"</span><span class="p">]</span><span class="w">
  </span><span class="p">},</span><span class="w">
  </span><span class="nl">"sample_data"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"processos"</span><span class="p">:</span><span class="w"> </span><span class="p">[{</span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="nl">"tipo_acao"</span><span class="p">:</span><span class="w"> </span><span class="s2">"despejo"</span><span class="p">,</span><span class="w"> </span><span class="nl">"ano_distribuicao"</span><span class="p">:</span><span class="w"> </span><span class="mi">2026</span><span class="p">}]</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p>Isso faz o modelo usar os <strong>nomes exatos</strong> de tabelas e colunas do banco real, em vez de inventar. É a diferença entre gerar um SQL que roda e um que dá erro de “tabela não encontrada”.</p>

<p><strong>Regras do prompt:</strong></p>
<ul>
  <li>Apenas <code class="language-plaintext highlighter-rouge">SELECT</code> (leitura).</li>
  <li><code class="language-plaintext highlighter-rouge">ILIKE</code> para buscas textuais (case-insensitive).</li>
  <li><code class="language-plaintext highlighter-rouge">JOIN</code> entre tabelas relacionadas.</li>
  <li><code class="language-plaintext highlighter-rouge">LIMIT 100</code> sempre.</li>
</ul>

<h4 id="camada-3--resumo-jurídico">Camada 3 — Resumo Jurídico</h4>

<p>A terceira camada é independente das duas primeiras. Ela recebe dados brutos de um processo (número, vara, partes, trâmites) e gera um <strong>resumo em linguagem acessível</strong> para o público geral.</p>

<p>Essa é a camada que o front-end do JusDigital consome quando o usuário clica em “Gerar Resumo” na tela de detalhe do processo. O JavaScript coleta todas as informações visíveis na página, formata em texto, e faz um <code class="language-plaintext highlighter-rouge">POST</code> para <code class="language-plaintext highlighter-rouge">http://localhost:8000/summary</code>.</p>

<h3 id="uma-validação-básica-contra-sql-destrutivo">Uma validação básica contra SQL destrutivo</h3>

<p>Quando um LLM gera SQL, a pergunta natural é: <em>“e se ele gerar um DROP TABLE?”</em>. Implementamos uma validação simples com regex em <code class="language-plaintext highlighter-rouge">llm_service.py</code>, na função <code class="language-plaintext highlighter-rouge">validate_sql_safety()</code>:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">_DANGEROUS_PATTERN</span> <span class="o">=</span> <span class="n">re</span><span class="p">.</span><span class="nb">compile</span><span class="p">(</span>
    <span class="sa">r</span><span class="s">"\b(DROP|DELETE|UPDATE|INSERT|TRUNCATE|ALTER|CREATE|GRANT|REVOKE|EXEC|EXECUTE)\b"</span><span class="p">,</span>
    <span class="n">re</span><span class="p">.</span><span class="n">IGNORECASE</span><span class="p">,</span>
<span class="p">)</span>

<span class="k">def</span> <span class="nf">validate_sql_safety</span><span class="p">(</span><span class="n">sql</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="bp">None</span><span class="p">:</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="n">_SELECT_START_PATTERN</span><span class="p">.</span><span class="n">match</span><span class="p">(</span><span class="n">sql</span><span class="p">):</span>
        <span class="k">raise</span> <span class="n">HTTPException</span><span class="p">(</span><span class="n">status_code</span><span class="o">=</span><span class="mi">422</span><span class="p">,</span> <span class="n">detail</span><span class="o">=</span><span class="s">"Query não começa com SELECT"</span><span class="p">)</span>
    <span class="n">match</span> <span class="o">=</span> <span class="n">_DANGEROUS_PATTERN</span><span class="p">.</span><span class="n">search</span><span class="p">(</span><span class="n">sql</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">match</span><span class="p">:</span>
        <span class="k">raise</span> <span class="n">HTTPException</span><span class="p">(</span><span class="n">status_code</span><span class="o">=</span><span class="mi">422</span><span class="p">,</span> <span class="n">detail</span><span class="o">=</span><span class="sa">f</span><span class="s">"Palavra proibida: </span><span class="si">{</span><span class="n">match</span><span class="p">.</span><span class="n">group</span><span class="p">()</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>
</code></pre></div></div>

<p>Duas checagens básicas:</p>
<ol>
  <li>A query <strong>deve</strong> começar com <code class="language-plaintext highlighter-rouge">SELECT</code>.</li>
  <li>A query <strong>não pode</strong> conter nenhuma das 11 palavras destrutivas.</li>
</ol>

<p>Se qualquer uma falhar, a API retorna HTTP 422 e a query nunca chega ao banco. Não é uma solução robusta de segurança — é uma checagem mínima com regex que, combinada com o prompt que instrui o modelo a gerar apenas <code class="language-plaintext highlighter-rouge">SELECT</code>, já evita os cenários mais óbvios para o contexto desse projeto.</p>

<h3 id="os-endpoints">Os endpoints</h3>

<table>
  <thead>
    <tr>
      <th>Endpoint</th>
      <th>Método</th>
      <th>O que faz</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">/health</code></td>
      <td>GET</td>
      <td>Health check (<code class="language-plaintext highlighter-rouge">{"status": "ok"}</code>)</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">/search</code></td>
      <td>POST</td>
      <td>Pipeline NER + SQL Gen. Recebe <code class="language-plaintext highlighter-rouge">query</code> + <code class="language-plaintext highlighter-rouge">db_context</code> opcional</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">/summary</code></td>
      <td>POST</td>
      <td>Resumo jurídico. Recebe <code class="language-plaintext highlighter-rouge">process_data</code> (texto bruto)</td>
    </tr>
  </tbody>
</table>

<p>A documentação automática está em <code class="language-plaintext highlighter-rouge">/docs</code> (Swagger) e <code class="language-plaintext highlighter-rouge">/redoc</code>.</p>

<h3 id="configuração-troque-o-modelo-em-1-linha">Configuração: troque o modelo em 1 linha</h3>

<p>O <code class="language-plaintext highlighter-rouge">config.py</code> usa <code class="language-plaintext highlighter-rouge">pydantic-settings</code> com <code class="language-plaintext highlighter-rouge">.env</code>. Cada camada pode usar um modelo diferente:</p>

<pre><code class="language-env">NER_MODEL=ollama/qwen2.5:3B
NER_API_BASE=http://localhost:11434

SQL_MODEL=ollama/qwen2.5:3B
SQL_API_BASE=http://localhost:11434

SUMMARY_MODEL=ollama/qwen2.5:3B
SUMMARY_API_BASE=http://localhost:11434
</code></pre>

<p>Quer usar GPT-4 para a geração de SQL e manter o Ollama local para NER? Muda duas linhas:</p>

<pre><code class="language-env">SQL_MODEL=gpt-4o
SQL_API_KEY=sk-...
</code></pre>

<p>O LiteLLM cuida do resto. Sem alterar uma linha de código.</p>

<hr />

<h2 id="como-rodar-tudo">Como Rodar Tudo</h2>

<h3 id="pré-requisitos">Pré-requisitos</h3>

<ul>
  <li><strong>Java 17+</strong> (para o servidor web e a API de dados)</li>
  <li><strong>PostgreSQL</strong> (com o banco <code class="language-plaintext highlighter-rouge">sistema_juridico</code> configurado)</li>
  <li><strong>Python 3.12+</strong> (para a API com IA)</li>
  <li><strong>Ollama</strong> (para rodar o modelo de linguagem localmente)</li>
</ul>

<h3 id="1-banco-de-dados">1. Banco de Dados</h3>

<p>Garanta que o PostgreSQL está rodando e execute os scripts de criação e população na ordem:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Conecte ao PostgreSQL e execute:</span>
psql <span class="nt">-U</span> seu_usuario <span class="nt">-d</span> sistema_juridico <span class="nt">-f</span> refs/Script_BD.sql
psql <span class="nt">-U</span> seu_usuario <span class="nt">-d</span> sistema_juridico <span class="nt">-f</span> refs/PopularBanco.sql
</code></pre></div></div>

<h3 id="2-servidor-web-java">2. Servidor Web (Java)</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Compilar (se necessário)</span>
javac <span class="nt">-d</span> out src/<span class="k">*</span>.java src/bean/<span class="k">*</span>.java src/controller/<span class="k">*</span>.java src/db/<span class="k">*</span>.java src/model/<span class="k">*</span>.java

<span class="c"># Empacotar</span>
jar cfm Run.jar MANIFEST.MF <span class="nt">-C</span> out <span class="nb">.</span>

<span class="c"># Rodar</span>
java <span class="nt">-jar</span> Run.jar
</code></pre></div></div>

<p>No menu, digite <code class="language-plaintext highlighter-rouge">20</code> para iniciar o servidor web. Acesse <code class="language-plaintext highlighter-rouge">http://localhost:8081/</code>.</p>

<p><img src="/assets/images/projects/projeto4/servidor_api_opcao_20.png" alt="Terminal com a opção 20 — servidor web rodando" /></p>

<h3 id="3-api-com-ia">3. API com IA</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Instalar Ollama (se ainda não tem)</span>
<span class="c"># https://ollama.com/download</span>

<span class="c"># Baixar o modelo</span>
ollama pull qwen2.5:3b

<span class="c"># Instalar dependências da API</span>
<span class="nb">cd </span>LLM-Juridica
pip <span class="nb">install</span> <span class="nt">-r</span> requirements.txt
<span class="c"># ou, se usar uv:</span>
uv <span class="nb">sync</span>

<span class="c"># Configurar variáveis de ambiente</span>
<span class="nb">cp</span> .env.example .env
<span class="c"># Edite o .env se necessário</span>

<span class="c"># Rodar a API</span>
uvicorn main:app <span class="nt">--reload</span>
</code></pre></div></div>

<p>A API estará disponível em <code class="language-plaintext highlighter-rouge">http://localhost:8000/</code>. Documentação Swagger em <code class="language-plaintext highlighter-rouge">http://localhost:8000/docs</code>.</p>

<p><img src="/assets/images/projects/projeto4/Swagger_api_local.png" alt="Swagger UI da API com IA" /></p>

<h3 id="4-testando-a-integração-front--ia">4. Testando a integração Front + IA</h3>

<p>Com os dois servidores rodando (Java na 8081 e Python na 8000):</p>

<ol>
  <li>Acesse <code class="language-plaintext highlighter-rouge">http://localhost:8081/</code></li>
  <li>Navegue até um processo</li>
  <li>Clique em “Gerar Resumo”</li>
  <li>O front faz o request para a API de IA e exibe o resumo processual</li>
</ol>

<p><img src="/assets/images/projects/projeto4/processo2_detalhes.png" alt="Detalhe do processo (exemplo 2)" /></p>

<p><img src="/assets/images/projects/projeto4/processo2_detalhes_gerando_resumo.png" alt="Gerando resumo pela IA (exemplo 2)" /></p>

<p><img src="/assets/images/projects/projeto4/processo2_detalhes_resumo_gerado.png" alt="Resumo gerado pela IA (exemplo 2)" /></p>

<p>Para testar a API de IA isoladamente:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd </span>LLM-Juridica
python test_client.py
</code></pre></div></div>

<p><img src="/assets/images/projects/projeto4/retorno_api_teste1.png" alt="Retorno da API — teste 1 (entidades extraídas)" /></p>

<p><img src="/assets/images/projects/projeto4/retorno_api_teste2.png" alt="Retorno da API — teste 2 (SQL gerado)" /></p>

<p><img src="/assets/images/projects/projeto4/retorno_api_teste3.png" alt="Retorno da API — teste 3 (resumo)" /></p>

<hr />

<h2 id="diagrama-de-integração">Diagrama de Integração</h2>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>┌─────────────────────────────────────────────────────────┐
│                    USUÁRIO (Navegador)                  │
│                  http://localhost:8081                  │
└────────────┬──────────────────────────┬─────────────────┘
             │ fetch("/api/...")        │ fetch("localhost:8000/summary")
             ▼                          ▼
┌────────────────────────┐  ┌──────────────────────────────┐
│   ServidorWeb.java     │  │     FastAPI (LLM-Juridica)   │
│   HttpServer :8081     │  │     Uvicorn :8000            │
│                        │  │                              │
│  ┌─ /api/processos     │  │  ┌─ POST /search             │
│  ├─ /api/processo?id=  │  │  │  ├─ Camada 1: NER         │
│  ├─ /api/advogados     │  │  │  ├─ Camada 2: SQL Gen     │
│  ├─ /api/leis          │  │  │  └─ validate_sql_safety() │
│  ├─ /api/login         │  │  │                           │
│  └─ /api/cadastro      │  │  └─ POST /summary            │
│                        │  │     └─ Camada 3: Resumo      │
└────────────┬───────────┘  └──────────────┬───────────────┘
             │                             │
             ▼                             ▼
┌────────────────────────┐  ┌──────────────────────────────┐
│      PostgreSQL        │  │     Ollama (Qwen 2.5 3B)     │
│   sistema_juridico     │  │     http://localhost:11434   │
└────────────────────────┘  └──────────────────────────────┘
</code></pre></div></div>

<hr />

<h2 id="o-que-eu-aprendi">O Que Eu Aprendi</h2>

<p>Esse projeto começou como uma tarefa de faculdade sobre modelagem relacional e foi crescendo. Cada etapa adicionou uma camada de complexidade, mas também de utilidade real. Algumas reflexões:</p>

<p><strong>Sobre LLMs para SQL</strong>: O pipeline de dois estágios (NER → SQL) é significativamente mais confiável do que jogar a pergunta direto para o modelo e pedir SQL. A extração de entidades primeiro cria uma representação intermediária estruturada que o segundo estágio usa como input bem definido. É o mesmo princípio de compiladores: tokenizar primeiro, parsear depois.</p>

<p><strong>Sobre rodar IA localmente</strong>: O Qwen 2.5 3B via Ollama é surpreendentemente capaz para tarefas focadas como geração de SQL. Não precisa de GPU dedicada, não depende de API externa, não tem custo por token. Para prototipagem, é imbatível.</p>

<p><strong>Sobre segurança de LLMs</strong>: A validação de SQL com regex não é um WAF. Mas a combinação de instruções no prompt (“apenas SELECT”) + validação hard-coded no código (“deve começar com SELECT, não pode conter DROP/DELETE/…”) cria uma defesa em profundidade razoável para um projeto desse porte.</p>

<hr />

<p>O código completo está disponível no <a href="https://github.com/hertonnn/Sistema-Juridico-BD">repositório do GitHub</a>.</p>

<p><strong>Disciplina:</strong> Banco de Dados II<br />
<strong>Instituição:</strong> Universidade do Estado de Santa Catarina (UDESC) - CCT<br />
<strong>Autores:</strong> Herton Silveira, Arthur Bertoli Silva<br />
<strong>Ano:</strong> 2025/2026</p>

<div class="mb-5">
    <span class="d-inline-block px-2 py-1 bg-light text-dark rounded small">
        <strong>Java</strong>
    </span>
    <span class="d-inline-block px-2 py-1 bg-light text-dark rounded small">
        <strong>HTML/CSS/JS</strong>
    </span>
    <span class="d-inline-block px-2 py-1 bg-light text-dark rounded small">
        <strong>FastAPI</strong>
    </span>
    <span class="d-inline-block px-2 py-1 bg-light text-dark rounded small">
        <strong>LiteLLM</strong>
    </span>
    <span class="d-inline-block px-2 py-1 bg-light text-dark rounded small">
        <strong>Ollama</strong>
    </span>
    <span class="d-inline-block px-2 py-1 bg-light text-dark rounded small">
        <strong>PostgreSQL</strong>
    </span>
    <span class="d-inline-block px-2 py-1 bg-light text-dark rounded small">
        <strong>UDESC</strong>
    </span>
</div>]]></content><author><name></name></author><category term="blog" /><category term="projeto" /><category term="Java" /><category term="HTML" /><category term="CSS" /><category term="JavaScript" /><category term="FastAPI" /><category term="LLM" /><category term="Ollama" /><category term="IA" /><category term="PostgreSQL" /><summary type="html"><![CDATA[Há um tempo atrás, escrevi no meu blog a respeito de um projeto que nasceu de uma disciplina de Banco de Dados na UDESC. Naquele post, eu cobri a parte que talvez seja a menos glamourosa, mas sem dúvida a mais importante de qualquer sistema: a modelagem relacional. Tabelas, chaves, cardinalidades, gatilhos. O alicerce invisível que segura tudo de pé.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://hertonnn.github.io/assets/images/projects/projeto4/index_img.png" /><media:content medium="image" url="https://hertonnn.github.io/assets/images/projects/projeto4/index_img.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Desenvolvimento de Aplicações na Web (ODAW)</title><link href="https://hertonnn.github.io/blog/odaw/" rel="alternate" type="text/html" title="Desenvolvimento de Aplicações na Web (ODAW)" /><published>2026-02-11T13:00:00+00:00</published><updated>2026-02-11T13:00:00+00:00</updated><id>https://hertonnn.github.io/blog/odaw</id><content type="html" xml:base="https://hertonnn.github.io/blog/odaw/"><![CDATA[<p><strong>Desenvolvimento de Aplicações na Web (ODAW)</strong> abrange o histórico e os conceitos fundamentais relacionados à Internet e à Web. O objetivo da disciplina é capacitar o aluno no conhecimento das tecnologias e desenvolvimento de um ambiente/aplicação protótipo completo.</p>

<p>A ementa explora desde o design estático até o dinâmico (com acesso a banco de dados), unindo o desenvolvimento orientado ao usuário com conceitos vitais de <strong>Acessibilidade</strong>, <strong>Usabilidade</strong>, <strong>Design Responsivo</strong> e <strong>Segurança na Web</strong>.</p>

<hr />

<h2 id="️-roadmap-da-disciplina">🗺️ Roadmap da Disciplina</h2>

<p>Tópicos e conteúdos práticos que são abordados durante o semestre:</p>

<ul class="task-list">
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" /><strong>Introdução e Evolução:</strong> Conceitos básicos de Internet, evolução da Web e Internet das Coisas (IoT).</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" /><strong>Estruturação e Marcação (HTML &amp; HTML5):</strong>
    <ul>
      <li>Listas, Tabelas e Formulários.</li>
      <li>Tags Semânticas, Mídias (Áudio/Vídeo) e Elementos Gráficos (Canvas, SVG).</li>
    </ul>
  </li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" /><strong>Apresentação e Estilo (CSS &amp; CSS3):</strong>
    <ul>
      <li>Estilos (Inline, Interno e Externo).</li>
      <li>Templates, RWD Frameworks (Bootstrap, W3.CSS, Pure CSS).</li>
      <li>Flexbox e Grid Layout.</li>
    </ul>
  </li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" /><strong>Programação Client-Side (JavaScript):</strong>
    <ul>
      <li>Lógica, eventos, tratamento de DOM.</li>
      <li>Validações de formulários (RegExp, lógicas matemáticas).</li>
    </ul>
  </li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" /><strong>Programação Server-Side (PHP Moderno):</strong>
    <ul>
      <li>Configuração do Servidor (Apache + PHP + MySQL).</li>
      <li>Processamento GET/POST, Sessões e Cookies.</li>
      <li>Autenticação e Criptografia.</li>
    </ul>
  </li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><strong>Integração com Banco de Dados</strong></li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><strong>Pesquisas e Novas Tecnologias (Seminários):</strong> Ferramentas emergentes, Frameworks e Arquiteturas.</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" /><strong>Projeto Final:</strong> Elaboração e implementação de uma aplicação Web robusta.</li>
</ul>

<hr />

<h2 id="️-materiais-e-ferramentas">🛠️ Materiais e Ferramentas</h2>

<p>Informações gerais para as aulas e configuração de ambiente.</p>

<h3 id="-informações-básicas">📌 Informações Básicas</h3>

<ul>
  <li>🕒 <strong>Aulas:</strong> Terças e Quintas, 15:20h</li>
  <li>📍 <strong>Local:</strong> Laboratório F307</li>
  <li>🌐 <strong>Plataforma:</strong> Moodle UDESC</li>
</ul>

<h3 id="-ambiente-de-desenvolvimento-e-base-de-estudos">💻 Ambiente de Desenvolvimento e Base de Estudos</h3>

<ul>
  <li>📚 <strong>W3Schools:</strong> Principal referência documentacional (<a href="https://www.w3schools.com/html/">HTML</a>, <a href="https://www.w3schools.com/css/">CSS</a>, <a href="https://www.w3schools.com/js/">JS</a>, <a href="https://www.w3schools.com/php/">PHP</a>).</li>
  <li>⚙️ <strong>Setup Local:</strong> Instalação do conjunto base <strong>Apache + PHP + MySQL</strong> (Linux Ubuntu ou Windows).</li>
</ul>

<hr />

<h2 id="-conteúdos-gerais-e-exercícios-práticos">📚 Conteúdos Gerais e Exercícios Práticos</h2>

<p>A disciplina utiliza um formato prático onde o aluno define um <strong>Tema Central</strong> (ex: <em>Locadora de Veículos, Venda de Carros, Fórum, Livros</em>) e aplica todas as tecnologias aprendidas em um projeto cumulativo de 10 exercícios.</p>

<h3 id="-1-estruturação-básica-html">📄 1. Estruturação Básica (HTML)</h3>

<ul>
  <li><strong>Exercício 1 a 3:</strong> Criação de estrutura HTML inicial com inserção de textos, imagens e links. Evolução para construção de <strong>Listas, Tabelas e Formulários</strong>, finalizando com integração de marcações avançadas do <strong>HTML5</strong> (Semântica, Áudio/Vídeo, Canvas).</li>
</ul>

<h3 id="-2-design-e-layout-css">🎨 2. Design e Layout (CSS)</h3>

<ul>
  <li><strong>Exercício 4 a 6:</strong> Início da estilização padrão. Implementação de novas classes/ids utilizando as formas externa, interna e inline. Consolidação de layouts complexos com auxílio de <strong>Templates</strong> ou <strong>RWD Frameworks</strong> (Bootstrap, W3.CSS).</li>
</ul>

<h3 id="-3-interatividade-e-dinamismo-javascript">⚡ 3. Interatividade e Dinamismo (JavaScript)</h3>

<ul>
  <li><strong>Exercício 7 e 8:</strong> Implementações de manipulação do DOM. Exercícios cobrindo interações (alerts, caixas de texto), estruturas lógicas, tratamento de strings/arrays/datas e validação robusta de dados em formulários (uso de Expressões Regulares).</li>
</ul>

<h3 id="️-4-regras-de-negócio-e-backend-php">⚙️ 4. Regras de Negócio e Backend (PHP)</h3>

<ul>
  <li><strong>Exercício 9 e 10:</strong> Configuração backend inicial. Uso de funções para tratamento de strings/arrays, gerenciamento de contadores baseados em arquivos <code class="language-plaintext highlighter-rouge">.txt</code>, controle de acesso com <strong>Cookies e Sessions</strong>. Processamento massivo de formulários (GET e POST) finalizando com <strong>Autenticação, Validação Server-side e Criptografia</strong>.</li>
</ul>

<hr />

<h2 id="️-seminários-e-tecnologias-emergentes-trabalho-1">🗣️ Seminários e Tecnologias Emergentes (Trabalho 1)</h2>

<p>Como complemento da disciplina, os alunos desenvolvem resumos expandidos e pesquisas das principais tecnologias adotadas na indústria web:</p>

<table>
  <thead>
    <tr>
      <th style="text-align: left">Categoria</th>
      <th style="text-align: left">Assuntos Abordados</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left"><strong>Front-end / Frameworks</strong></td>
      <td style="text-align: left">Angular, Vue, CSS3 + Frameworks, TypeScript</td>
    </tr>
    <tr>
      <td style="text-align: left"><strong>Back-end / Arquitetura</strong></td>
      <td style="text-align: left">Python (em Dev. Web), Laravel Framework, LUA</td>
    </tr>
    <tr>
      <td style="text-align: left"><strong>Padrões e Ferramentas</strong></td>
      <td style="text-align: left">WebAssembly, Web Semântica</td>
    </tr>
    <tr>
      <td style="text-align: left"><strong>UX &amp; Segurança</strong></td>
      <td style="text-align: left">Acessibilidade e Usabilidade, Design Responsivo, Segurança Web</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="-sobre-a-professora">👩‍🏫 Sobre a Professora</h2>

<p>👤 <strong>Profª. Dra. Débora Cabral Nazario</strong> 📧 <strong>Contato:</strong> debora.nazario@udesc.br
🔗 <strong>Lattes:</strong> <a href="http://lattes.cnpq.br/6905169880963398">Acessar Currículo Lattes</a>
🏢 <strong>Departamento:</strong> Ciência da Computação (CCT-DCC)</p>

<p><strong>Formação Acadêmica:</strong></p>

<ul>
  <li>🎓 Graduação em Ciências da Computação (UFSC, 2001)</li>
  <li>🎓 Mestrado em Ciências da Computação (UFSC, 2003)</li>
  <li>🎓 Doutorado em Engenharia e Gestão do Conhecimento (UFSC, 2015)</li>
</ul>

<p><em>Atualmente é professora efetiva da Universidade do Estado de Santa Catarina (UDESC) atuando na instituição desde 2004.</em></p>

<hr />

<div align="center">
  <i>"A Web não conecta apenas máquinas, ela conecta pessoas."</i> 🌐✨
</div>]]></content><author><name></name></author><category term="blog" /><category term="estudo" /><category term="HTML" /><category term="CSS" /><category term="JavaScript" /><category term="PHP" /><category term="MySQL" /><category term="Bootstrap" /><category term="Web" /><category term="UDESC" /><summary type="html"><![CDATA[Desenvolvimento de Aplicações na Web (ODAW) abrange o histórico e os conceitos fundamentais relacionados à Internet e à Web. O objetivo da disciplina é capacitar o aluno no conhecimento das tecnologias e desenvolvimento de um ambiente/aplicação protótipo completo.]]></summary></entry><entry><title type="html">Compiladores</title><link href="https://hertonnn.github.io/blog/compiladores/" rel="alternate" type="text/html" title="Compiladores" /><published>2026-01-11T13:00:00+00:00</published><updated>2026-01-11T13:00:00+00:00</updated><id>https://hertonnn.github.io/blog/compiladores</id><content type="html" xml:base="https://hertonnn.github.io/blog/compiladores/"><![CDATA[<p>Estudo dos princípios, técnicas e ferramentas para análise léxica, sintática e semântica, além da geração de código.</p>

<p>Um <strong>compilador</strong> é um programa (ou conjunto de programas) que, a partir de um <strong>código fonte</strong> escrito em uma linguagem compilada, gera um <strong>código objeto</strong> semanticamente equivalente.</p>

<p>De forma clássica, um compilador traduz um programa de uma <strong>linguagem textual de alto nível</strong> para uma <strong>linguagem de máquina</strong>, específica para determinado processador e sistema operacional.</p>

<hr />

<h2 id="-materiais-da-disciplina">📂 Materiais da Disciplina</h2>

<ul>
  <li>📦 <a href="https://github.com/cdvasconcellos/Compiladores">Repositório da disciplina</a></li>
  <li>🖥️ <a href="https://godbolt.org/">Compiler Explorer</a></li>
  <li>📖 <a href="https://haskell-happy.readthedocs.io/en/latest/">Documentação Happy</a></li>
  <li>📖 <a href="https://haskell-alex.readthedocs.io/en/latest/index.html">Documentação Alex</a></li>
</ul>

<hr />

<h2 id="-sobre-o-professor">👨‍🏫 Sobre o Professor</h2>

<p><strong>Cristiano Damiani Vasconcellos</strong></p>

<ul>
  <li>🎓 Graduação em Ciência da Computação (PUCPR, 1993)</li>
  <li>🎓 Mestrado em Engenharia Elétrica e Informática Industrial (UTFPR, 1997)</li>
  <li>🎓 Doutorado em Ciência da Computação (UFMG, 2004)</li>
</ul>

<p>🔎 Áreas de Interesse: Projeto, implementação e uso de linguagens de programação.<br />
Foco em <strong>linguagens funcionais</strong>, <strong>sistemas de tipos</strong> e <strong>verificação formal</strong>.</p>

<p>📌 Recursos:</p>
<ul>
  <li><a href="https://github.com/cdvasconcellos/">📂 GitHub (Materiais de aula)</a></li>
  <li><a href="https://www.youtube.com/channel/UCZ0iWiwN2zy5qB4CevpD89Q">▶️ YouTube (Videoaulas)</a></li>
</ul>

<p>📧 <strong>E-mail:</strong> cristiano.vasconcellos@udesc.br<br />
📄 <strong>Lattes:</strong> <a href="http://lattes.cnpq.br/7291640788372419">Clique aqui</a></p>

<hr />
<p><em>“Construir um compilador é aprender como funciona a alma de uma linguagem de programação.”</em> 🤓</p>]]></content><author><name></name></author><category term="blog" /><category term="estudo" /><category term="Compiladores" /><category term="Haskell" /><category term="JVM" /><category term="Análise Léxica" /><category term="Análise Sintática" /><category term="UDESC" /><summary type="html"><![CDATA[Estudo dos princípios, técnicas e ferramentas para análise léxica, sintática e semântica, além da geração de código.]]></summary></entry><entry><title type="html">Modelagem e Implementação de um Banco de Dados para Sistema Jurídico</title><link href="https://hertonnn.github.io/blog/SistemaJuridico/" rel="alternate" type="text/html" title="Modelagem e Implementação de um Banco de Dados para Sistema Jurídico" /><published>2025-06-01T12:20:00+00:00</published><updated>2025-06-01T12:20:00+00:00</updated><id>https://hertonnn.github.io/blog/SistemaJuridico</id><content type="html" xml:base="https://hertonnn.github.io/blog/SistemaJuridico/"><![CDATA[<p><img src="https://www.bcompany.com.br/wp-content/uploads/2020/03/martelo-juiz-laptop-sistema-juridico-1024x683.jpg.webp" alt="img_inicio" /></p>

<p>Este post detalha a arquitetura e o desenvolvimento de um banco de dados relacional projetado para o ecossistema jurídico, criado em parceria com Adriano Silva como projeto final da disciplina de Banco de Dados I na UDESC. O trabalho envolveu todas as etapas do ciclo de vida dos dados: desde a modelagem conceitual e regras de negócio até a implementação física e construção de uma API.</p>

<h2 id="o-problema-e-o-escopo">O Problema e o Escopo</h2>

<p>A área do Direito lida diariamente com um volume massivo de informações fragmentadas. A proposta deste projeto foi estruturar um repositório centralizado que organize processos, trâmites, documentos e os diversos atores envolvidos, otimizando o acesso às informações para profissionais da área.</p>

<p>Para manter o domínio de informação organizado e escalável, o modelo foi dividido em quatro núcleos arquiteturais:</p>

<ul>
  <li><strong><em>Núcleo do Processo:</em></strong> Composto pelas entidades <strong><em>Processo</em></strong> e <strong><em>Tramite</em></strong> (com especializações em <strong><em>Audiencia</em></strong> e <strong><em>Decisao</em></strong>), representando o histórico cronológico dos eventos.</li>
  <li><strong><em>Atores e Participantes:</em></strong> Utilizando o conceito de generalização na entidade base <strong><em>Pessoa</em></strong>, com ramificações estruturadas para <strong><em>Advogado</em></strong> e <strong><em>Agente Judiciario</em></strong> (especializado em <strong><em>Juiz</em></strong> e <strong><em>Servidor Publico</em></strong>).</li>
  <li><strong><em>Estrutura Organizacional:</em></strong> Mapeamento da hierarquia e localização jurisdicional através das entidades <strong><em>Comarca</em></strong> e <strong><em>Vara</em></strong>.</li>
  <li><strong><em>Fundamentação e Conteúdo:</em></strong> As entidades <strong><em>Documento</em></strong> e <strong><em>Lei</em></strong>, que representam os artefatos e a base legal dos eventos processuais.</li>
</ul>

<h2 id="integridade-e-regras-de-negócio">Integridade e Regras de Negócio</h2>

<p>A confiabilidade de um sistema jurídico exige restrições rigorosas no banco de dados. Algumas das principais regras de negócio mapeadas no Dicionário de Dados incluem:</p>

<ul>
  <li><strong><em>Lotação e Hierarquia:</em></strong> Um <strong><em>Juiz</em></strong> deve estar lotado em uma única <strong><em>Vara</em></strong> (1:N), e uma <strong><em>Vara</em></strong> pertence a uma única <strong><em>Comarca</em></strong> (1:N).</li>
  <li><strong><em>Fluxo Processual:</em></strong> Todo <strong><em>Processo</em></strong> deve tramitar sob a responsabilidade de um único <strong><em>Juiz</em></strong> e possuir pelo menos um <strong><em>Tramite</em></strong> associado para existir no sistema.</li>
  <li><strong><em>Relacionamentos Complexos:</em></strong> A defesa de uma parte em um processo exige um relacionamento ternário (N:N:N) conectando <strong><em>Advogado</em></strong>, <strong><em>Pessoa</em></strong> e <strong><em>Processo</em></strong>.</li>
</ul>

<p>Abaixo está a representação visual do Esquema Entidade-Relacionamento Estendido (EER):</p>

<p><img src="https://github.com/hertonnn/Sistema-Juridico/blob/main/refs/Parte%201%20-%20Corrigida/Conceitual_1.png?raw=true" alt="Esquema Conceitual EER" /></p>

<h2 id="construindo-a-api-relacional-em-java">Construindo a API Relacional em Java</h2>

<p>A segunda fase do projeto consistiu em abstrair a complexidade do banco através de uma aplicação. A API foi desenvolvida em <strong><em>Java</em></strong> adotando o padrão arquitetural <strong><em>MVC (Model-View-Controller)</em></strong>, garantindo a separação de responsabilidades entre a lógica de acesso aos dados, as regras da aplicação e a interface com o usuário.</p>

<p>A aplicação consome um subconjunto do banco de dados (no mínimo 5 tabelas relacionadas) e fornece funcionalidades completas de manipulação:</p>

<ul>
  <li>Inserção e remoção de registros em todas as tabelas mapeadas.</li>
  <li>Listagens simples e consultas analíticas complexas envolvendo <strong><em>JOINs</em></strong>, subconsultas e funções de agregação.</li>
</ul>

<p><img src="https://github.com/hertonnn/Sistema-Juridico/blob/main/refs/Parte%201%20-%20Corrigida/c%C3%B3digo.png?raw=true" alt="Interface da API" /></p>

<h3 id="considerações-finais">Considerações finais</h3>

<p>Em sumo, esse trabalho de conclusão final da disciplina de BAN1 foi crucial para relembrar e sintetizar todo conteúdo teórico e prático visto no decorrer do semestre. O repositório do projeto está disponível no <a href="https://github.com/hertonnn/Sistema-Juridico">GitHub</a>, contendo todo o código fonte e os artefatos do banco de dados.</p>

<p><strong>Disciplina:</strong> Banco de Dados I</p>

<p><strong>Instituição:</strong> Universidade do Estado de Santa Catarina (UDESC) - Centro de Ciências Tecnológicas (CCT)</p>

<p><strong>Autores:</strong> Adriano Silva, Herton Silveira</p>

<p><strong>Professora</strong>: Dra. Rebeca Schroeder Freitas</p>

<p><strong>Ano:</strong> 2025</p>

<div class="mb-5">
    <span class="d-inline-block px-2 py-1 bg-light text-dark rounded small">
        <strong>PostgreSQL</strong>
    </span>
    <span class="d-inline-block px-2 py-1 bg-light text-dark rounded small">
        <strong>Java</strong>
    </span>
    <span class="d-inline-block px-2 py-1 bg-light text-dark rounded small">
        <strong>Modelagem Relacional</strong>
    </span>
    <span class="d-inline-block px-2 py-1 bg-light text-dark rounded small">
        <strong>MVC</strong>
    </span>
    <span class="d-inline-block px-2 py-1 bg-light text-dark rounded small">
        <strong>UDESC</strong>
    </span>
    <span class="d-inline-block px-2 py-1 bg-light text-dark rounded small">
        <strong>API</strong>
    </span>
</div>]]></content><author><name></name></author><category term="blog" /><category term="Banco de Dados" /><category term="Java" /><category term="Arquitetura" /><category term="SQL" /><category term="Modelagem Relacional" /><category term="MVC" /><category term="UDESC" /><category term="API" /><summary type="html"><![CDATA[]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.bcompany.com.br/wp-content/uploads/2020/03/martelo-juiz-laptop-sistema-juridico-1024x683.jpg.webp" /><media:content medium="image" url="https://www.bcompany.com.br/wp-content/uploads/2020/03/martelo-juiz-laptop-sistema-juridico-1024x683.jpg.webp" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Desenvolvendo uma aplicação desktop de controle de Finanças Pessoais em Java, com Java Swing e PostgreSQL.</title><link href="https://hertonnn.github.io/blog/ApiFinance/" rel="alternate" type="text/html" title="Desenvolvendo uma aplicação desktop de controle de Finanças Pessoais em Java, com Java Swing e PostgreSQL." /><published>2022-07-01T13:00:00+00:00</published><updated>2022-07-01T13:00:00+00:00</updated><id>https://hertonnn.github.io/blog/ApiFinance</id><content type="html" xml:base="https://hertonnn.github.io/blog/ApiFinance/"><![CDATA[<p><a href="https://www.youtube.com/watch?v=W3SZnzQo-sg"><img src="https://img.youtube.com/vi/W3SZnzQo-sg/maxresdefault.jpg" alt="Demonstração do Projeto" /></a></p>

<p>Na disciplina de <strong>Programação Orientada a Objetos</strong> ministrada em minha faculdade (Universidade Estadual de Santa Catarina - UDESC), foi apresentada como proposta de trabalho individual final a implementação de um programa em três etapas. Na primeira fase, serão modeladas e implementadas, em Java, as camadas de <strong>dados</strong> e <strong>negócio</strong>; na segunda, a <strong>interface gráfica</strong>. Por fim, na terceira etapa, ocorrerá a projeção e implementação do <strong>banco de dados</strong> para a aplicação, denominada persistência.</p>

<p>Neste post, detalharei as etapas do projeto, do <strong>backend</strong> ao <strong>frontend</strong>, com o tema Sistema de Finanças. Trata-se de uma aplicação ligeiramente complexa que visa ser um programa de gerenciamento de finanças pessoais. Nessa aplicação, o usuário adiciona suas receitas e despesas em categorias específicas, permitindo que o programa:</p>

<ul>
  <li>Plote <strong>gráficos</strong> e faça estimativas a partir dos dados de entradas e saídas financeiras do usuário no <strong>dashboard</strong> principal.</li>
  <li>Possibilite que o usuário gerencie e monitore suas transações financeiras por meio de históricos de registros em suas próprias categorias pré-definidas.</li>
  <li>Ofereça uma interface intuitiva e de fácil uso, incorporando elementos de <strong>experiência do usuário (UX)</strong>.</li>
  <li>Possua sistema de login e cadastro.</li>
  <li>Permita a previsão de receitas/despesas através da adição de orçamentos pelo usuário.</li>
</ul>

<p><img src="/assets/images/projects/projeto3/img1.0.png" alt="Imagem 1" />
<img src="/assets/images/projects/projeto3/img1.1.png" alt="Imagem 2" />
<img src="/assets/images/projects/projeto3/img1.2.png" alt="Imagem 3" />
<img src="/assets/images/projects/projeto3/img1.3.png" alt="Imagem 4" />
<img src="/assets/images/projects/projeto3/img1.4.png" alt="Imagem 5" /></p>

<h2 id="arquitetura-do-back-end">Arquitetura do Back-end</h2>

<h3 id="o-banco-de-dados">O banco de dados</h3>

<p>Inicialmente, a ferramenta utilizada para a persistência de dados é o <strong>PostgreSQL.</strong> Conforme a documentação oficial, o PostgreSQL é um sistema de gerenciamento de banco de dados objeto-relacional capaz de suportar os principais recursos da área, tais como consultas complexas, chaves estrangeiras, controle de concorrência de várias versões, além da adição de novos tipos de dados, funções, entre outros.</p>

<p>Em uma análise mais aprofundada, destaca-se a organização do projeto em tabelas que representam as classes da camada de dados, concebida para armazenar os objetos que o programa manipulará, juntamente com seus atributos e métodos. Além disso, como linguagem para documentar e visualizar o banco de dados, optou-se pelo tradicional e eficiente diagrama de classes da <strong>UML (Unified Modeling Language).</strong></p>

<p><img src="/assets/images/projects/projeto3/img2.png" alt="Diagrama de Classes" /></p>

<p>Portanto, a UML de classes acima representa a organização dos dados no banco, incluindo as cardinalidades que representam os relacionamentos entre as tabelas Usuário, Conta, Categoria, Registro e Orçamento. Isso possibilita uma visualização organizada da estrutura dos dados. Por exemplo, a tabela Registro possui duas chaves estrangeiras (FK): uma referente à conta e outra à categoria de receita/despesa daquele registro. Adicionalmente, a tabela Conta faz referência a um usuário da tabela Usuário, sendo este o proprietário da conta que realizou o registro.</p>

<h3 id="encapsulamento-e-padrão-de-projeto-dao">Encapsulamento e Padrão de projeto DAO</h3>

<p>De forma geral, estabelecer a conexão com o banco de dados e realizar operações <strong>CRUD (Create, Update e Delete)</strong> em tabelas parece ser inicialmente simples. Basta consultar a documentação oficial da biblioteca utilizada, seguir as etapas de conexão, baixar o driver necessário na pasta lib e escrever algumas poucas linhas de código, incluindo informações como usuário, senha e caminho do banco de dados.</p>

<p>Contudo, dependendo do projeto e se realizado de maneira incorreta, o código pode se tornar confuso, com várias conexões ao banco espalhadas em camadas que nem foram criadas para essa finalidade. Isso pode resultar em futuros erros e dificultar a manutenção do código. Pensando nisso, esse projeto adota o padrão <strong>DAO (Data Access Object)</strong>, que, embora relativamente simples, tem se mostrado altamente eficaz, simplificando significativamente o processo de implementação desse código.</p>

<p><img src="/assets/images/projects/projeto3/img3.0.png" alt="Código DAO 1" />
<img src="/assets/images/projects/projeto3/img3.1.png" alt="Código DAO 2" /></p>

<p>Em resumo, esse padrão consiste em criar uma classe DAO para cada objeto de domínio, e cada uma dessas classes terá as operações de CRUD correspondentes, comunicando-se com o banco e encapsulando o acesso aos dados. Dessa forma, ao utilizar também o padrão singleton, em que apenas uma instância pode ser criada de cada classe, o projeto não só se torna mais organizado e limpo, mas também limita o número de conexões desnecessárias ao banco, resultando em uma <strong>otimização</strong> mais eficiente.</p>

<p>A estrutura do banco de dados final ficou assim:</p>

<p><img src="/assets/images/projects/projeto3/img4.png" alt="Estrutura do banco" /></p>

<h3 id="o-sistema">O Sistema</h3>

<p>Na camada de <strong>negócios</strong>, a lógica da aplicação atua como uma ponte, conectando-se às camadas DAO, para possibilitar a persistência, acesso ou remoção de dados específicos na camada de apresentação. As operações, tais como cadastro, validação e remoção de cada objeto do programa, são executadas pela classe Sistema nessa camada. Essa abordagem possibilita a integração eficiente das camadas visíveis da aplicação, como as telas de login, cadastro, etc.</p>

<p>A estrutura geral do projeto ficará assim:</p>

<p><img src="/assets/images/projects/projeto3/img5.png" alt="Estrutura Geral do Projeto" /></p>

<h2 id="a-experiência-do-usuário">A experiência do usuário</h2>

<h3 id="paleta-de-cores-formas-e-fonte">Paleta de cores, formas e fonte</h3>

<p>A primeira etapa que decidi seguir ao criar a interface dessa aplicação (camada de apresentação) foi criar uma identidade visual para ser usada em todas as janelas do programa. Dessa forma, a aplicação vai possuir ícones, paleta de cores, fonte e vários outros elementos gráficos que são de suma importância para dar <strong>personalidade</strong> ao projeto.</p>

<p><img src="/assets/images/projects/projeto3/img6.png" alt="Identidade Visual" /></p>

<p>A paleta de cores é composta por tons azuis que estão por toda parte, seja em botões, textos, fundos ou em bordas. Da mesma forma, a fonte escolhida está na maioria dos textos em destaque, assim como os ícones que seguem os mesmos padrões.</p>

<h3 id="janelas-intuitivas-e-designer">Janelas intuitivas e Designer</h3>

<p>A intenção por trás de cada janela ou função era torná-las intuitivas, buscando uma semelhança com o design de programas de desktop ou web, utilizando HTML e CSS como referência. No entanto, a ferramenta <strong>Java Swing</strong>, que foi utilizada, não oferece nativamente um layout com elementos tão modernos quanto as ferramentas mais atualizadas, o que tornou o processo de design um tanto mais desafiador. Por exemplo, componentes como botões, comboboxes ou campos de texto possuem, por padrão, uma aparência antiquada e são mais difíceis de manipular, mas eu os modifiquei ao máximo para se aproximarem de aparências mais modernas e minimalistas.</p>

<p><img src="/assets/images/projects/projeto3/img7.png" alt="Interface Java Swing" /></p>

<h3 id="gráficos-e-tabelas">Gráficos e tabelas</h3>

<p>Os gráficos do painel principal foram elaborados utilizando a biblioteca <strong>JFreeChart</strong> do Java, que oferece uma variedade de modelos, como gráficos de linha, de barras, radiais, entre outros. Os dados selecionados são alimentados nos eixos x e y, representando os registros financeiros da pessoa, sendo filtrados e modificados dinamicamente durante a aplicação. Além disso, as tabelas são atualizadas em conjunto com os gráficos, refletindo as alterações feitas pelo usuário nos filtros.</p>

<p><img src="/assets/images/projects/projeto3/img8.png" alt="Gráficos e Tabelas" /></p>

<h2 id="conclusão">Conclusão</h2>

<p>Em resumo, este projeto, parcialmente pronto para a fase beta, incluiria: um executável testado em pelo menos algumas máquinas com sistemas Linux e Windows, uma implementação eficiente de criptografia, uma bateria de testes de performance e, pelo menos, a disponibilização para download durante a fase beta para testes com usuários. No entanto, cada um desses tópicos é complexo o suficiente para demandar vários meses de estudo e renderia um post exclusivo nesta página se fossem implementados por uma única pessoa (eu), o que não é viável neste momento. Portanto, ainda é necessário dedicar mais tempo de estudo a este projeto, o que resultará em mais aprendizado, bem como mais prática em <strong>Java</strong>.</p>

<p>Link do repositório em meu Github - <a href="https://github.com/hertonnn/API-Financas">https://github.com/hertonnn/API-Financas</a></p>

<h2 id="referências">Referências</h2>

<ul>
  <li>PostgreSQL Documentation - <a href="https://www.postgresql.org/docs/current/intro-whatis.html">https://www.postgresql.org/docs/current/intro-whatis.html</a></li>
  <li>Programação orientada a objetos (IBM) - <a href="https://www.ibm.com/docs/pt-br/watsonx-as-a-service?topic=language-object-oriented-programming">https://www.ibm.com/docs/pt-br/watsonx-as-a-service?topic=language-object-oriented-programming</a></li>
  <li>UML - <a href="https://www.microsoft.com/pt-br/microsoft-365/business-insights-ideas/resources/guide-to-uml-diagramming-and-database-modeling">https://www.microsoft.com/pt-br/microsoft-365/business-insights-ideas/resources/guide-to-uml-diagramming-and-database-modeling</a></li>
  <li>Padrão DAO - <a href="https://www.macoratti.net/11/10/pp_dao1.htm">https://www.macoratti.net/11/10/pp_dao1.htm</a></li>
</ul>]]></content><author><name></name></author><category term="blog" /><category term="projeto" /><category term="Java" /><category term="Java Swing" /><category term="PostgreSQL" /><category term="POO" /><category term="UML" /><category term="MVC" /><category term="UDESC" /><summary type="html"><![CDATA[]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img.youtube.com/vi/W3SZnzQo-sg/maxresdefault.jpg" /><media:content medium="image" url="https://img.youtube.com/vi/W3SZnzQo-sg/maxresdefault.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>