Files
portifolio-evandrodevbr/app/ia/page.tsx
T
Evandro Fonseca Junior 10f170abf4 feat(home): posicionamento com prova, menu sem recarregar e WhatsApp em todo o site
H1 'Sites e sistemas que trazem pedidos pelo WhatsApp e tiram sua operação da planilha.'; HeroWork maior com a SEV; menu Cases, Serviços, Como trabalho, Sobre e IA com next/link e pré-carregamento no hover; menu do celular em tela cheia; WhatsApp flutuante e no rodapé com a mensagem da rota; rodapé em todas as páginas; FAQ da home; /ia como oferta de revisão de app feito com IA; formulário com noscript, validação do mailto e plano B do pop-up; cartões sem foco indevido; sem a fonte Monument.
2026-10-14 14:15:25 -03:00

339 lines
15 KiB
TypeScript

import type { Metadata } from "next";
import Link from "next/link";
import { Breadcrumb } from "@/app/components/Breadcrumb";
import {
pageTop,
primaryButton,
textLinkDark,
} from "@/app/components/button-styles";
import WhatsAppLink from "@/app/components/WhatsAppLink";
import { safeJsonLd } from "@/lib/jsonld";
import { buildBreadcrumbList, buildPageSocialMetadata } from "@/lib/seo";
import { siteUrl } from "@/lib/site-content";
import { AI_REVIEW_SUBJECT } from "@/lib/whatsapp";
const pageUrl = `${siteUrl}/ia`;
/** Curto de propósito: o template de app/layout.tsx acrescenta " | Evandro.dev.br" e o conjunto cabe em 44 caracteres. */
const pageTitle = "Revisão de app feito com IA";
const pageDescription =
"Fez um app com Lovable, Bolt ou Replit? Eu reviso as falhas de acesso a dados, separo o que aproveitar do que refazer e faço o orçamento para a produção.";
/** Entra na frase "Quero conversar sobre {assunto}." da mensagem do WhatsApp (a mesma do botão flutuante em /ia). */
const WHATSAPP_SERVICE = AI_REVIEW_SUBJECT;
export const metadata: Metadata = {
title: pageTitle,
description: pageDescription,
...buildPageSocialMetadata({
url: pageUrl,
// as prévias de compartilhamento não passam pelo template do título
title: `${pageTitle} | Evandro.dev.br`,
description: pageDescription,
type: "website",
}),
};
/** O que a pessoa recebe ao contratar a revisão. Sem prazo e sem preço: isso se combina na conversa. */
const DELIVERABLES = [
{
title: "As falhas de acesso a dados",
description:
"Testo se uma pessoa consegue ver ou alterar os dados de outra e mostro o que precisa de correção.",
},
{
title: "O que dá para aproveitar",
description: "O que já está pronto e pode seguir no projeto.",
},
{
title: "O que é melhor refazer",
description:
"As partes que não se sustentam em uso real, com o motivo de cada uma.",
},
{
title: "Um orçamento para pôr em produção",
description:
"O que falta para o app atender clientes de verdade, com o orçamento por escrito.",
},
];
const RESPONSIBILITIES = [
{
title: "Quem pode acessar cada dado?",
description:
"Login não basta. Permissões precisam ser verificadas no servidor e testadas entre usuários, empresas e perfis diferentes.",
},
{
title: "Como recuperar a operação?",
description:
"Ambientes separados, acesso restrito à produção e backups com restauração testada reduzem o impacto de uma alteração errada.",
},
{
title: "Quem valida antes de publicar?",
description:
"Código gerado também passa por revisão, testes e avaliação de dependências. O escopo inclui manutenção, custos e riscos de operação.",
},
];
/** Três episódios de 2025, resumidos. Cada um traz o que foi relatado, o que não foi provado e o cuidado técnico. */
const INCIDENTS = [
{
title: "Lovable: dados expostos em aplicações criadas na plataforma",
summary:
"Em maio de 2025, a Semafor noticiou uma análise que encontrou 170 de 1.645 aplicações com acesso indevido a informações, incluindo dados de usuários e chaves de API, ligado à configuração de acesso dos bancos conectados. O fornecedor contesta que a falha seja da plataforma e lembra que os clientes respondem por seus dados. O relato não comprova roubo em todas essas aplicações.",
care: "testar se uma pessoa consegue ler ou alterar dados de outra, em vez de tratar a tela de login como prova de segurança.",
links: [
{
href: "https://www.semafor.com/article/05/29/2025/the-hottest-new-vibe-coding-startup-lovable-is-a-sitting-duck-for-hackers",
label: "Reportagem da Semafor (em inglês)",
},
{
href: "https://nvd.nist.gov/vuln/detail/CVE-2025-48757",
label: "Registro e contestação no NVD",
},
],
},
{
title: "Replit: um agente apagou dados de uma aplicação",
summary:
"Em julho de 2025, o cofundador da SaaStr relatou que um agente apagou dados durante a construção de uma aplicação, e as alterações de desenvolvimento podiam afetar a produção. A Replit reconheceu o episódio, informou que o banco foi recuperado por rollback e anunciou a separação entre bancos de desenvolvimento e produção por padrão. Houve exclusão e recuperação, não roubo de informações.",
care: "limitar permissões de agentes, separar ambientes e testar a recuperação antes de depender dela.",
links: [
{
href: "https://replit.com/blog/doubling-down-on-our-commitment-to-secure-vibe-coding",
label: "Relato e medidas da Replit (29/07/2025)",
},
],
},
{
title: "Base44: aplicações privadas com falha de acesso",
summary:
"Em julho de 2025, pesquisadores da Wiz demonstraram uma falha que permitia acesso não autorizado a aplicações privadas do Base44. Ela estava na camada compartilhada de autenticação da plataforma, não em erro de um usuário iniciante. A Wix corrigiu em menos de 24 horas e informou não ter encontrado exploração maliciosa.",
care: "avaliar também o fornecedor e as permissões efetivas das integrações, além do código da aplicação.",
links: [
{
href: "https://www.wiz.io/blog/critical-vulnerability-base44",
label: "Pesquisa da Wiz e resposta da Wix (29/07/2025)",
},
],
},
];
export default function AiPage() {
const jsonLd = {
"@context": "https://schema.org",
"@graph": [
buildBreadcrumbList(pageUrl, [
["Início", siteUrl],
["Revisão de app feito com IA", pageUrl],
] as const),
],
};
return (
<main>
<script type="application/ld+json">{safeJsonLd(jsonLd)}</script>
<section className={`ds-section ds-section-dark ${pageTop}`}>
<div className="ds-section-shell">
<Breadcrumb
items={[
{ label: "Início", href: "/" },
{ label: "Revisão de app feito com IA", href: "/ia" },
]}
/>
<p className="ds-eyebrow">IA no desenvolvimento</p>
<h1 className="ds-section-title max-w-[22ch] text-balance">
Revisão de app feito com IA (Lovable, Bolt, Replit)
</h1>
<p className="ds-copy max-w-[62ch]">
A IA permite testar ideias e construir protótipos mesmo sem
experiência em programação. Quando o sistema passa a cuidar de
clientes, dinheiro ou dados pessoais, alguém precisa avaliar o que
foi gerado e validar como ele se comporta fora da demonstração.
</p>
<div className="mt-sp-6 flex flex-wrap items-center gap-x-sp-6 gap-y-sp-3">
<WhatsAppLink
className={primaryButton}
service={WHATSAPP_SERVICE}
placement="ia_hero"
>
Pedir a revisão do meu app
</WhatsAppLink>
<Link href="/cases" className={textLinkDark}>
Ver projetos entregues
</Link>
</div>
</div>
</section>
<section className="ds-section" aria-labelledby="ia-receber-title">
<div className="ds-section-shell">
<h2 id="ia-receber-title" className="ds-section-title max-w-[26ch]">
O que você recebe na revisão
</h2>
<ol className="mt-sp-8 grid gap-sp-6 sm:grid-cols-2 lg:grid-cols-4">
{DELIVERABLES.map((item, index) => (
<li
key={item.title}
className="border-t border-[var(--border)] pt-sp-5"
>
<span className="ds-kicker">
{String(index + 1).padStart(2, "0")}
</span>
<h3 className="mt-sp-3 text-lg font-semibold leading-snug">
{item.title}
</h3>
<p className="ds-copy">{item.description}</p>
</li>
))}
</ol>
<p className="ds-copy mt-sp-8 max-w-[65ch]">
Começa por uma conversa pelo WhatsApp, para eu entender o app e o
que ele precisa fazer. Não envie senhas nem acessos por mensagem.
</p>
</div>
</section>
<section className="ds-section" aria-labelledby="ia-contratar-title">
<div className="ds-section-shell">
<h2 id="ia-contratar-title" className="ds-section-title max-w-[26ch]">
Se a IA cria um sistema, por que contratar um desenvolvedor?
</h2>
<div className="mt-sp-6 border-l-2 border-[var(--slash)] pl-sp-5">
<p className="max-w-[75ch] text-lg leading-8 text-[var(--ink)]">
Você contrata engenharia para transformar as regras do seu negócio
em um sistema que possa ser testado, operado e mantido. A IA pode
fazer parte desse trabalho. Ela não dispensa decisões sobre
arquitetura, segurança e responsabilidade pelos dados.
</p>
</div>
<div className="mt-sp-8 grid gap-sp-6 md:grid-cols-3">
{RESPONSIBILITIES.map((item) => (
<article
key={item.title}
className="border-t border-[var(--border)] pt-sp-5"
>
<h3 className="text-lg font-semibold leading-snug">
{item.title}
</h3>
<p className="ds-copy">{item.description}</p>
</article>
))}
</div>
</div>
</section>
<section className="ds-section" aria-labelledby="ia-casos-title">
<div className="ds-section-shell">
{/* Recolhido: as notícias sustentam a oferta, mas não são o que a pessoa veio ver. */}
<details className="group border-y border-[var(--border)]">
<summary className="flex min-h-14 cursor-pointer list-none items-center justify-between gap-sp-4 py-sp-4 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--ink)] [&::-webkit-details-marker]:hidden">
<h2
id="ia-casos-title"
className="font-display text-[clamp(20px,3vw,28px)] font-semibold leading-tight tracking-[-0.02em]"
>
O que casos documentados ensinam
</h2>
<span
aria-hidden="true"
className="shrink-0 font-mono text-2xl leading-none text-[var(--meta)] transition-transform group-open:rotate-45 motion-reduce:transition-none"
>
+
</span>
</summary>
<div className="pb-sp-8">
<p className="ds-copy max-w-[75ch]">
São episódios de 2025, não avaliações atuais das plataformas.
Eles mostram riscos de configuração, permissões e operação; não
provam que todo sistema feito com IA seja inseguro ou que um
profissional elimine qualquer risco.
</p>
<div className="mt-sp-6 grid gap-sp-6 lg:grid-cols-3">
{INCIDENTS.map((incident) => (
<article key={incident.title} className="ds-card">
<h3 className="ds-card-title !mt-0">{incident.title}</h3>
<p className="ds-copy">{incident.summary}</p>
<p className="ds-copy">
<strong>O cuidado técnico:</strong> {incident.care}
</p>
<ul className="mt-sp-4 flex flex-col gap-sp-1">
{incident.links.map((link) => (
<li key={link.href}>
<a
className="inline-flex min-h-11 items-center text-[15px] md:text-sm underline underline-offset-4"
href={link.href}
target="_blank"
rel="noopener noreferrer"
>
{link.label}
</a>
</li>
))}
</ul>
</article>
))}
</div>
</div>
</details>
</div>
</section>
<section className="ds-section" aria-labelledby="ia-lgpd-title">
<div className="ds-section-shell grid gap-sp-6 lg:grid-cols-2">
<article className="ds-card">
<h2 id="ia-lgpd-title" className="ds-card-title !mt-0">
E a LGPD?
</h2>
<p className="ds-copy">
Usar IA não afasta as obrigações de proteção de dados. A ANPD
exige medidas técnicas e administrativas também de agentes de
pequeno porte e esclarece que as flexibilizações não os isentam
das demais obrigações da LGPD, como bases legais e direitos dos
titulares.
</p>
<p className="ds-copy">
O trabalho técnico inclui controles de acesso, coleta limitada ao
necessário e rotinas de retenção e exclusão. Conformidade depende
também dos processos da empresa e de orientação jurídica;
contratar desenvolvimento não equivale a uma certificação de
adequação.
</p>
<a
className="mt-sp-4 inline-flex min-h-11 items-center text-[15px] md:text-sm underline underline-offset-4"
href="https://www.gov.br/anpd/pt-br/acesso-a-informacao/institucional/atos-normativos/regulamentacoes_anpd/resolucao-cd-anpd-no-2-de-27-de-janeiro-de-2022"
target="_blank"
rel="noopener noreferrer"
>
ANPD: Resolução nº 2/2022, arts. 6º, 12 e 13
</a>
</article>
<article className="ds-card">
<h2 className="ds-card-title !mt-0">
Já começou com IA? Podemos partir daí.
</h2>
<p className="ds-copy">
Seu protótipo ajuda a explicar a ideia. Antes de propor uma
reconstrução, avalio o que pode ser aproveitado, quais riscos
precisam de correção e o que falta para atender usuários em
produção.
</p>
<p className="ds-copy">
Você não precisa saber programar para conduzir o negócio. Precisa
entender o que está contratando, acompanhar a entrega e ter
clareza sobre quem cuida de cada parte do sistema.
</p>
<div className="mt-sp-6">
<WhatsAppLink
className={primaryButton}
service={WHATSAPP_SERVICE}
placement="ia_closing"
>
Avaliar meu projeto
</WhatsAppLink>
</div>
</article>
</div>
</section>
</main>
);
}