MILWEB®
MILWEB®
MW/023ECOAESTÚDIO

ECOA

ECOA — tela inicial
ESTÚDIO
MILWEB
TIPO
PRODUTO DIGITAL
STATUS
NO AR

02 / A IDEIA

Rede social anônima · produto completo com IA

Pessoas querem desabafar e ser ouvidas sem expor o rosto, e as redes tradicionais punem a vulnerabilidade.

03 / EXPERIÊNCIA
  1. 01 / 01

    revoke select + grant em lista explícita de colunas: nem a API consegue ligar conta a post.

    ECOA — 01
  2. 02 / 02

    Regex determinístico sempre ativo mais Claude Haiku opcional. Indisponibilidade da IA nunca bloqueia a publicação.

    ECOA — 02
  3. 03 / 03

    Frase de 6 palavras com hash bcrypt reatribui a conta via RPC, sem precisar de nenhum dado pessoal.

    ECOA — 03
  4. 04 / 04

    Sem hashtag livre, sem DM e com 13 tópicos curados: estrutura pensada contra campanhas coordenadas.

    ECOA — 04
Onboarding do ECOA:"Aqui, só palavras"

04 / POR BAIXO DO CAPÔ

  • 01O 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 B…+

    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.

  • 02Anonimato aqui não é 'sem cadastro', é uma garantia de banco de dados. Cada pessoa entra via signInAnonymously() do Supabase e recebe um pub…+

    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.

  • 03A 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…+

    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.

  • 04Algumas decisões deixam claro o tipo de produto que é. Nunca vai ter mensagem privada, tratada no projeto como "vetor de assédio e aliciamen…+

    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.

CONSTRUÍDO COMNext.js · TypeScript · Supabase · PostgreSQL · Claude API

06 / RESULTADO

Anonimato por arquitetura · IA de moderação

MVP NO AR

[ QUERO ALGO PARECIDO ]

07 / TELAS SELECIONADAS
Onboarding do ECOA:"Aqui, só palavras"
TELA 01Onboarding do ECOA:"Aqui, só palavras"
Onboarding do ECOA:regras da comunidade
TELA 02Onboarding do ECOA:regras da comunidade
Onboarding do ECOA:"Você é um número"
TELA 03Onboarding do ECOA:"Você é um número"
PRÓXIMA EXPERIÊNCIA17 / LOJA DE IPHONE

Loja de iPhone

Loja de iPhone

TODOS OS PROJETOS

TODOS OS PROJETOS