TuBrief
구독 채널
비디오
커뮤니티

Como integrar com segurança o código de interface gerado pelo Claude Code em um projeto existente

TuBrief 편집팀
2026년 9월 12일
0
Computing/Software

원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.

Português한국어EnglishEspañol中文हिन्दीDeutschFrançaisالعربيةРусскийBahasa Indonesia日本語

관련 영상

O Claude Code Acabou de Receber sua Maior Atualização de Design do Ano (E Veja Como Dominá-la)10:58

O Claude Code Acabou de Receber sua Maior Atualização de Design do Ano (E Veja Como Dominá-la)

Chase AI

커뮤니티의 다른 글

사내 시스템에 llm api 붙일 때 마주하는 현실적인 한계와 대응법

2026년 9월 13일

레거시 백엔드에 GPT-6 Astra 붙일 때 예산 승인과 보안 통과를 먼저 끝내는 법이 있습니다

2026년 9월 13일

에이전트끼리 대화하다 6천만 원 청구서가 나오는 이유

2026년 9월 13일

사내 RAG 벡터 검색에 Okta 권한 필터를 직접 거는 방법

2026년 9월 13일

브라우저 에이전트에게 내 구글 계정을 통째로 넘기면 안 되는 이유

2026년 9월 12일

Apple Won the AI Race

2026년 9월 12일

댓글 (0)

Log in to leave a comment

아직 작성된 글이 없습니다

© 2026 . All rights reserved.

TuBrief
구독 채널
비디오
커뮤니티
로그인

Como integrar com segurança o código de interface gerado pelo Claude Code em um projeto existente

Abra o Claude Code no terminal, digite /design e um rascunho de tela aparece em segundos. Para um desenvolvedor solo, isso é prático porque exige menos esforço. O problema começa no momento em que você abre esse código.

Ele nem olha para os componentes do shadcn/ui que já estão configurados no projeto e cria novas tags <button> do zero. Em vez de usar as cores semânticas registradas na paleta, ele espalha códigos hexadecimais arbitrários como bg-[#1e293b] por cada arquivo. A cada tela criada, você perde 40 minutos corrigindo caminhos de importação bagunçados e apagando estilos em linha.

Não é impressão sua. Um estudo da GitClear de 2024, que analisou 211 milhões de linhas de commits, mostrou que, após a introdução de ferramentas de IA, a proporção de código completamente descartado ou reescrito em até duas semanas saltou de 3,1% para 5,7% — quase o dobro. A taxa de refatoração despencou de 25% para menos de 10%. A dívida técnica se acumula na mesma velocidade em que o código cresce. É preciso abandonar a expectativa de que o modelo respeitará o sistema de design existente por conta própria e amarrá-lo a nível de sistema.


Fixando os caminhos dos componentes com um arquivo de regras do projeto

A razão pela qual o Claude Code ignora o código existente é simples: ele varre apenas os arquivos necessários de forma restrita para economizar a janela de contexto. Se nenhuma restrição for dada, o modelo compõe as telas usando as tags HTML mais primitivas.

Graças ao cache de prompts, o arquivo de configuração na raiz da sessão é mantido a um custo de entrada de cerca de 10% do padrão. Ele não desaparece mesmo se você reiniciar ou compactar a conversa. Inserir regras de reutilização de componentes aqui impede que o modelo crie tags cruas aleatoriamente.

Adicione os caminhos dos componentes comuns e as regras de estilo no arquivo CLAUDE.md na raiz do projeto.

`markdown

Design System Guidelines

  1. Component Reuse (STRICT)
  • DO NOT use raw DOM tags (, , ).
  • MUST import from @/components/ui:
    • Button: import { Button } from "@/components/ui/button"
    • Input: import { Input } from "@/components/ui/input"
    • Card: import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card"
    • Dialog: import { Dialog, DialogContent, DialogTrigger } from "@/components/ui/dialog"
  • If a component does not exist in @/components/ui, ask to run: "npx shadcn@latest add ".
  1. Token Boundaries
  • NEVER use arbitrary hex codes or pixel widths: NO bg-[#...], NO w-[...px].
  • Use Semantic CSS variables:
    • Surfaces: bg-background, bg-card, bg-muted
    • Text: text-foreground, text-muted-foreground, text-primary
    • Borders: border-border, border-input

`

Não há necessidade de passar arquivos CSS globais inteiros de milhares de linhas para o prompt o tempo todo. Basta selecionar apenas os nomes dos tokens na configuração do Tailwind e extraí-los para um JSON.

`javascript
// scripts/extract-tokens.mjs
import fs from 'fs';
import resolveConfig from 'tailwindcss/resolveConfig.js';
import tailwindConfig from '../tailwind.config.js';

const fullConfig = resolveConfig(tailwindConfig);
const semanticTokens = {
colors: Object.keys(fullConfig.theme.colors || {}).filter(
(name) => !['inherit', 'current', 'transparent'].includes(name)
),
spacing: Object.keys(fullConfig.theme.spacing || {}),
borderRadius: Object.keys(fullConfig.theme.borderRadius || {}),
};

if (!fs.existsSync('.claude')) {
fs.mkdirSync('.claude');
}

fs.writeFileSync(
'.claude/design-tokens.json',
JSON.stringify(semanticTokens, null, 2)
);

`

Conecte este script aos gatilhos postinstall e predev no package.json.

`json
{
"scripts": {
"postinstall": "node scripts/extract-tokens.mjs",
"predev": "node scripts/extract-tokens.mjs"
}
}

`

A lista de classes disponíveis é atualizada a cada build. O tempo gasto manualmente corrigindo classes de estilo com erros de digitação desaparece.


Substituindo automaticamente estilos arbitrários com scripts de ganchos (hooks)

Por mais que você coloque avisos no prompt, o modelo às vezes gera valores incorretos. Se você jogar uma captura de tela e pedir para ele criar uma interface, ele definirá larguras fixas como w-[380px] com base na proporção da imagem — o principal culpado pelo scroll horizontal que quebra em telas móveis.

Para atender aos critérios do WCAG 2.1 AA, é necessário especificar padrões por resolução e realizar uma inspeção obrigatória com um linter no exato momento em que o arquivo é gerado.

Área de Verificação Critério Alvo Classes Tailwind Obrigatórias Condição de Bloqueio
Dispositivos Móveis 390px (base) flex-col, w-full, grid-cols-1 Rolagem horizontal causada pelo uso de largura fixa w-[...px]
Tablets 768px (md:) md:flex-row, md:grid-cols-2, md:p-6 Quando a estrutura móvel de coluna única é mantida em telas largas
Desktops 1440px (xl:) xl:max-w-7xl, mx-auto, xl:grid-cols-4 Quando o container de layout se expande infinitamente em altas resoluções
Modo Escuro Seletor .dark bg-background, text-foreground Classes padrão como bg-white ou text-black deixadas isoladamente
Acessibilidade WCAG 2.1 AA aria-label, <main>, focus-visible:ring-2 Texto alternativo para leitores de tela ausente em botões de ícone

Ao controlar um modelo desobediente, usar ganchos de ciclo de vida é a escolha mais segura. O gancho PostToolUse do Claude Code permite que um script seja executado assim que um arquivo é gravado no disco.

Registre o comando do gancho em .claude/settings.json.

`json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit|MultiEdit",
"hooks": [
{
"type": "command",
"command": "node .claude/hooks/ast-lint-guard.mjs",
"timeout": 30
}
]
}
]
}
}

`

Agora, escreva o script de verificação. Ele captura códigos hexadecimais comuns usando expressões regulares, converte-os em tokens do projeto e aplica regras à força usando o plugin ESLint para Tailwind.

`javascript
// .claude/hooks/ast-lint-guard.mjs
import fs from 'fs';
import readline from 'readline';
import { execSync } from 'child_process';

const rl = readline.createInterface({ input: process.stdin });
let inputBuffer = '';

rl.on('line', (line) => { inputBuffer += line; });
rl.on('close', () => {
try {
const payload = JSON.parse(inputBuffer);
const filePath = payload.tool_input?.file_path || payload.tool_input?.path;

if (!filePath || !/\.(tsx|jsx)$/.test(filePath) || !fs.existsSync(filePath)) {
  process.exit(0);
}

let code = fs.readFileSync(filePath, 'utf-8');
let changed = false;

const replacementMap = {
  '#ffffff': 'bg-background',
  '#000000': 'text-foreground',
  '#020817': 'bg-background',
  '#0f172a': 'bg-card',
  '#1e293b': 'bg-muted',
  '#64748b': 'text-muted-foreground',
  '#2563eb': 'bg-primary',
};

for (const [hex, token] of Object.entries(replacementMap)) {
  const regex = new RegExp(`(bg|text|border)-\[${hex}\]`, 'gi');
  if (regex.test(code)) {
    code = code.replace(regex, token);
    changed = true;
  }
}

if (changed) {
  fs.writeFileSync(filePath, code, 'utf-8');
}

execSync(`npx eslint "${filePath}" --rule "tailwindcss/no-arbitrary-value: error"`, {
  stdio: 'pipe',
});

process.exit(0);

} catch (error) {
const failureLog = error.stdout?.toString() || error.stderr?.toString() || error.message;
console.error([Lint Pipeline Block] Violação de regras de estilo:\n${failureLog});
process.exit(1);
}
});

`

Instale o plugin do linter no projeto.

`bash
npm install -D eslint-plugin-tailwindcss

`

Se o script retornar o código de saída 1, o Claude Code lê o log de erros e reescreve o código usando classes semânticas no turno seguinte. Isso reduz a necessidade de perder tempo lidando com telas quebradas durante a fase de QA.


Separando fisicamente a camada de visualização (view) da lógica de negócios

Quando você pede ao Claude Code para montar uma interface, ele costuma misturar funções fetch, objetos gigantescos de dados falsos e JSX em um único arquivo. Para integrar uma API real depois, você acaba tendo que remover todo o código de renderização.

O código de interface não precisa saber como os estados são modificados. É mais seguro dividir um diretório de funcionalidade em quatro arquivos e firmar o esquema de dados primeiro.

Primeiro, defina o formato dos dados.

`typescript
// src/components/features/dashboard-card/schema.ts
import { z } from "zod";

export const MetricItemSchema = z.object({
id: z.string(),
label: z.string(),
value: z.string(),
changePercentage: z.number(),
trend: z.enum(["up", "down", "neutral"]),
});

export const DashboardCardSchema = z.object({
title: z.string().min(1),
metrics: z.array(MetricItemSchema),
});

export type DashboardCardData = z.infer;

export interface DashboardCardViewProps {
data: DashboardCardData;
isLoading?: boolean;
onActionClick?: (metricId: string) => void;
}

`

Em seguida, ao chamar o Claude Code no terminal, restrinja-o explicitamente para não usar nenhum estado interno.

`bash
claude "Crie src/components/features/dashboard-card/dashboard-card-view.tsx, que seja um componente de UI puro implementando DashboardCardViewProps de src/components/features/dashboard-card/schema.ts. Nunca use useState, useEffect ou fetch internamente; construa-o de forma responsiva usando apenas as Props recebidas e elementos de @/components/ui."

`

Envolva os dados com um hook ao integrá-los. Mantenha os dados mockados e a função de chamada de API real com a mesma estrutura.

`typescript
// src/components/features/dashboard-card/use-dashboard-card.ts
import { useQuery } from "@tanstack/react-query";
import { DashboardCardData } from "./schema";

const MOCK_DATA: DashboardCardData = {
title: "Métricas Ativas Mensais",
metrics: [
{ id: "m-1", label: "Novos usuários", value: "1.240", changePercentage: 12.5, trend: "up" },
{ id: "m-2", label: "Taxa de rejeição", value: "2.1%", changePercentage: -0.4, trend: "down" },
],
};

export const useDashboardCard = (cardId: string, useMock = false) => {
return useQuery({
queryKey: ["dashboard-card", cardId],
queryFn: async () => {
if (useMock) {
return MOCK_DATA;
}
const res = await fetch(/api/dashboard/${cardId});
if (!res.ok) throw new Error("Falha ao buscar dados");
return res.json();
},
});
};

`

Monte ambos no componente container.

`typescript
// src/components/features/dashboard-card/index.tsx
"use client";

import React from "react";
import { DashboardCardView } from "./dashboard-card-view";
import { useDashboardCard } from "./use-dashboard-card";

export function DashboardCardContainer({ cardId, useMock = false }: { cardId: string; useMock?: boolean }) {
const { data, isLoading } = useDashboardCard(cardId, useMock);

if (!data) return null;

return (
<DashboardCardView
data={data}
isLoading={isLoading}
onActionClick={(id) => console.log(id)}
/>
);
}

`

Antes que o backend esteja pronto, ajuste a interface usando useMock={true}. Quando a API estiver concluída, basta remover a flag. Não haverá motivo para mexer em uma única linha do código da view.


Isolando a árvore de trabalho e selecionando alterações

Ao conversar longamente com o modelo no terminal e ajustar a interface, é comum que arquivos de configuração globais acabem sendo modificados ou que arquivos temporários desnecessários surjam por todo o diretório. É muito mais tranquilo criar um diretório dedicado a experimentos para trabalhar, mantendo o seu espaço de trabalho intocado.

O uso do Git worktree permite executar o Claude Code em uma pasta completamente isolada.

`bash
git worktree add ../saas-ui-sandbox -b experiment/ai-dashboard-ui
cd ../saas-ui-sandbox
claude

`

Se o experimento der errado, basta deletar a pasta inteira sem preocupações.

`bash
cd ../saas-platform
git worktree remove ../saas-ui-sandbox --force
git branch -D experiment/ai-dashboard-ui

`

Se o resultado desejado for alcançado, evite fazer merge da branch inteira; em vez disso, traga apenas os trechos de código do arquivo de visualização usando o modo interativo.

`bash
git checkout main
git checkout -p experiment/ai-dashboard-ui -- src/components/features/dashboard-card/dashboard-card-view.tsx

`

Ao visualizar os blocos de código que aparecem no terminal, pressione y apenas para as partes que gostar e descarte modificações estranhas com n.

Se a sessão ultrapassar 5 turnos, o contexto começa a se perder e o modelo passa a falar besteira. Limpe a sessão sempre que isso acontecer:

  1. Verificação de tipos: Assim que criar um componente individual, execute imediatamente npx tsc --noEmit. Prossiga para o próximo prompt apenas quando houver 0 erros de tipo.
  2. Compactação de contexto: Se a conversa ficar longa, use /compact sem hesitar para reduzir o desperdício de tokens.
  3. Limpeza de sessão: Ao terminar o trabalho de interface, faça um commit e use /clear para esvaziar completamente a memória. Quando as coisas se embaraçarem, retorne ao ponto de verificação anterior com /rewind.

A capacidade de geração de um modelo é uma coisa, mas garantir que esse código possa entrar em produção é algo totalmente diferente. Estreitar o canal de entrada com CLAUDE.md, validar o código de saída com ganchos de ciclo de vida e separar o espaço de trabalho com worktrees poupará você de passar noites em claro consertando o código gerado pela IA.