MILWEB®
MILWEB®
MW/023ECOAESTUDIO

ECOA

ECOA — pantalla inicial
ESTUDIO
MILWEB
TIPO
PRODUCTO DIGITAL
ESTADO
EN LÍNEA

02 / LA IDEA

Red social anónima · producto completo con IA

Las personas quieren desahogarse y ser escuchadas sin exponer el rostro, y las redes tradicionales castigan la vulnerabilidad.

03 / EXPERIENCIA
  1. 01 / 01

    revoke select + grant en lista explícita de columnas: ni la API puede vincular cuenta con post.

    ECOA — 01
  2. 02 / 02

    Regex determinístico siempre activo más Claude Haiku opcional. La indisponibilidad de la IA nunca bloquea la publicación.

    ECOA — 02
  3. 03 / 03

    Una frase de 6 palabras con hash bcrypt reasigna la cuenta vía RPC, sin necesitar ningún dato personal.

    ECOA — 03
  4. 04 / 04

    Sin hashtags libres, sin DM y con 13 temas curados: estructura pensada contra campañas coordinadas.

    ECOA — 04
Onboarding de ECOA:"Aquí, solo palabras"

04 / BAJO EL CAPÓ

  • 01El stack en producción es Next.js 16 (App Router, Turbopack) sobre Supabase Postgres en la región sa-east-1, elegida por residencia de datos…+

    El stack en producción es Next.js 16 (App Router, Turbopack) sobre Supabase Postgres en la región sa-east-1, elegida por residencia de datos en Brasil, pensando en la LGPD. Es deliberadamente más simple que la arquitectura objetivo documentada en el blueprint del proyecto (NestJS, Redis, NATS JetStream, Meilisearch, React Native/Expo): el MVP cambió todo eso por un atajo de validación rápida. Como el producto es solo texto y no tiene grafo social (sin seguir, sin seguidores), el problema más caro de una red social, el fan-out del timeline, simplemente no existe. Cada post pesa pocos KB y la query del feed es una view de Postgres con paginación por keyset, sin cola ni caché dedicado.

  • 02El anonimato aquí no es 'sin registro', es una garantía de base de datos. Cada persona entra vía signInAnonymously() de Supabase y recibe un…+

    El anonimato aquí no es 'sin registro', es una garantía de base de datos. Cada persona entra vía signInAnonymously() de Supabase y recibe un public_number generado por una función Postgres (sorteo con verificación de unicidad), mostrado como "Usuario #48291". El UUID interno (profiles.id) nunca sale de la base: un revoke select quita el acceso por defecto a las tablas posts, comments y profiles para el rol authenticated, y un grant select posterior devuelve acceso solo a una lista explícita de columnas, sin user_id. En la práctica, ni siquiera una query maliciosa del lado del cliente puede vincular cuenta con contenido, porque el privilegio para eso no existe en el rol de la base. No es una regla de aplicación que se pueda eludir. Tampoco existe página de perfil navegable: tocar un "#48291" no abre ningún historial, decisión deliberada anti-stalking.

  • 03La moderación corre en dos etapas, ambas en lib/moderation.ts. La etapa 0 es determinística e instantánea: normalización Unicode NFKC (contr…+

    La moderación corre en dos etapas, ambas en lib/moderation.ts. La etapa 0 es determinística e instantánea: normalización Unicode NFKC (contra bypass por homoglifos), bloqueo de links, regex de PII (e-mail y teléfono) que solo marca, y un regex de señal de crisis ("quiero morir", "hacerme daño") que nunca bloquea la publicación, porque solo existe para activar apoyo. La etapa 2 es opcional: una llamada a Claude Haiku con salida JSON estructurada, cuyo prompt de sistema instruye explícitamente "ante la duda, no marques", porque un falso positivo que silencia a alguien en sufrimiento se trata como peor que un falso negativo. El diseño es fail-open por principio: si la API cae o supera el timeout de 8 s, el contenido pasa. Hoy, sin crédito de API configurado en producción, solo la etapa 0 está realmente activa. Las denuncias de la comunidad se convierten en autoeliminación vía trigger de Postgres a partir de 3 denunciantes distintos, sin cola de moderación dedicada. El panel de Supabase cumple ese papel en el MVP.

  • 04Algunas decisiones dejan claro el tipo de producto que es. Nunca habrá mensajes privados, tratados en el proyecto como "vector de acoso y ca…+

    Algunas decisiones dejan claro el tipo de producto que es. Nunca habrá mensajes privados, tratados en el proyecto como "vector de acoso y captación". Nunca habrá hashtags libres: solo una taxonomía curada de 13 temas, justamente para impedir campañas coordinadas. Y el feed es cronológico, sin scroll infinito, con "hitos de respiro" cada ~50 posts, que es una decisión estructural antiadicción y no solo de UX. La recuperación de cuenta sin e-mail usa una frase de 6 palabras (lista de 240 términos, ~47 bits de entropía) con hash bcrypt, reasignada vía RPC con ON UPDATE CASCADE propagando a posts, comentarios y reacciones. Los límites actuales están documentados con honestidad: el contador de intentos de recuperación queda anulado por el rollback de la misma transacción que genera el error de autenticación. Es un detalle reconocido y aceptado, porque la entropía de la frase y el costo de bcrypt ya contienen la mayor parte del riesgo. Una suite e2e de 19 escenarios corre contra la base de datos real, incluyendo la verificación de que la privacidad por columna realmente impide la fuga de user_id.

CONSTRUIDO CONNext.js · TypeScript · Supabase · PostgreSQL · Claude API

06 / RESULTADO

Anonimato por arquitectura · IA de moderación

MVP EN LÍNEA

[ QUIERO ALGO PARECIDO ]

07 / PANTALLAS SELECCIONADAS
Onboarding de ECOA:"Aquí, solo palabras"
PANTALLA 01Onboarding de ECOA:"Aquí, solo palabras"
Onboarding de ECOA:reglas de la comunidad
PANTALLA 02Onboarding de ECOA:reglas de la comunidad
Onboarding de ECOA:"Eres un número"
PANTALLA 03Onboarding de ECOA:"Eres un número"
SIGUIENTE EXPERIENCIA17 / LOJA DE IPHONE

Loja de iPhone

Loja de iPhone

TODOS LOS PROYECTOS

TODOS LOS PROYECTOS