Rede social anônima · produto completo com IA
ECOA

Problema
Pessoas querem desabafar e ser ouvidas sem expor o rosto, e as redes tradicionais punem a vulnerabilidade.
Solução
Rede só-texto onde cada pessoa é um número: anonimato garantido pela arquitetura do banco (nem a API consegue ligar conta a post), moderação em 2 estágios com IA, recuperação de conta sem e-mail e LGPD de ponta a ponta.
Como foi construído
O stack em produção é Next.js 16 (App Router, Turbopack) sobre Supabase Postgres na região sa-east-1, escolhida por residência de dados no Brasil, pensando em LGPD. É deliberadamente mais simples que a arquitetura-alvo documentada no blueprint do projeto (NestJS, Redis, NATS JetStream, Meilisearch, React Native/Expo): o MVP trocou tudo isso por um atalho de validação rápida. Como o produto é só texto e não tem grafo social (sem seguir, sem seguidores), o problema mais caro de uma rede social, que é o fan-out de timeline, simplesmente não existe. Cada post pesa poucos KB e a query do feed é uma view Postgres com paginação por keyset, sem fila nem cache dedicado.
Anonimato aqui não é 'sem cadastro', é uma garantia de banco de dados. Cada pessoa entra via signInAnonymously() do Supabase e recebe um public_number gerado por uma função Postgres (sorteio com checagem de unicidade), exibido como "Usuário #48291". O UUID interno (profiles.id) nunca sai do banco: um revoke select remove o acesso padrão das tabelas posts, comments e profiles para o papel authenticated, e um grant select seguinte devolve acesso só a uma lista explícita de colunas, sem user_id. Na prática, mesmo uma query client-side maliciosa não consegue ligar conta a conteúdo, porque o privilégio pra isso não existe no papel do banco. Não é uma regra de aplicação que dá pra contornar. Também não existe página de perfil navegável: tocar num "#48291" não abre histórico nenhum, decisão deliberada anti-stalking.
A moderação roda em dois estágios, ambos em lib/moderation.ts. O estágio 0 é determinístico e instantâneo: normalização Unicode NFKC (contra bypass por homóglifos), bloqueio de links, regex de PII (e-mail e telefone) que só sinaliza, e um regex de sinal de crise ("quero morrer", "me machucar") que nunca bloqueia a publicação, porque só existe pra acionar apoio. O estágio 2 é opcional: uma chamada à Claude Haiku com saída JSON estruturada, cujo prompt de sistema instrui explicitamente "na dúvida, não sinalize", porque um falso positivo silenciando alguém em sofrimento é tratado como pior que um falso negativo. O design é fail-open por princípio: se a API cair ou estourar o timeout de 8s, o conteúdo passa. Hoje, sem crédito de API configurado em produção, só o estágio 0 está realmente ativo. Denúncias da comunidade viram auto-remoção via trigger Postgres a partir de 3 denunciantes distintos, sem fila de moderação dedicada. O painel do Supabase faz esse papel no MVP.
Algumas decisões deixam claro o tipo de produto que é. Nunca vai ter mensagem privada, tratada no projeto como "vetor de assédio e aliciamento". Nunca vai ter hashtag livre: só uma taxonomia curada de 13 tópicos, justamente pra impedir campanhas coordenadas. E o feed é cronológico, sem scroll infinito, com "marcos de respiro" a cada ~50 posts, que é decisão estrutural anti-vício e não só de UX. A recuperação de conta sem e-mail usa uma frase de 6 palavras (lista de 240 termos, ~47 bits de entropia) com hash bcrypt, reatribuída via RPC com ON UPDATE CASCADE propagando pra posts, comentários e reações. Os limites atuais estão documentados com honestidade: o contador de tentativas de recuperação é anulado pelo rollback da mesma transação que gera o erro de autenticação. É um detalhe reconhecido e aceito, porque a entropia da frase e o custo do bcrypt já seguram a maior parte do risco. Uma suíte e2e de 19 cenários roda contra o banco real, incluindo checagem de que a privacidade por coluna realmente impede o vazamento de user_id.
Anonimato por privilégio de coluna
revoke select + grant em lista explícita de colunas: nem a API consegue ligar conta a post.
Moderação em 2 estágios, fail-open
Regex determinístico sempre ativo mais Claude Haiku opcional. Indisponibilidade da IA nunca bloqueia a publicação.
Recuperação sem e-mail
Frase de 6 palavras com hash bcrypt reatribui a conta via RPC, sem precisar de nenhum dado pessoal.
Anti-manipulação por design
Sem hashtag livre, sem DM e com 13 tópicos curados: estrutura pensada contra campanhas coordenadas.
Mais telas
Stack
- Next.js
- TypeScript
- Supabase
- PostgreSQL
- Claude API


